BeetleはLeonardo互換ということなので,使えるかも...
1/4に一度投稿したのですが,あまりにひどい出来だったので,調べ直しました。
対象
Pin Out | CPU |
---|---|
D10 | 30pin = PB6 |
D9 | 29pin = PB5 |
- D11 = 12pin = PB7 は,以下では除外する。
- D11のPWMはデフォルト976.5625Hz,Duty精度は7ビット。
- Timer0を使用するので,PWMの周波数を変更すると,
millis()
等にも影響を与えるため,この記事では周波数変更を考慮しない。
duty:8ビット精度,周波数 = 490.2Hz で良い場合
analogWrite(9,duty_9); // uint8_t duty_9
analogWrite(10,duty_10); // uint8_t duty_10
- 補足説明
- 9ピン,10ピン 独立して設定可能。
duty:8ビット精度,周波数を選択する
// TCCR1B = (TCCR1B & 0b11111000) | 0x01; // 31372.55Hz div:1
// TCCR1B = (TCCR1B & 0b11111000) | 0x02; // 3921.16Hz div:8
// TCCR1B = (TCCR1B & 0b11111000) | 0x03; // 490.20Hz <- default div:64
// TCCR1B = (TCCR1B & 0b11111000) | 0x04; // 122.55Hz div:256
// TCCR1B = (TCCR1B & 0b11111000) | 0x05; // 30.64Hz div:1024
analogWrite(9,duty_9); // uint8_t duty_9
analogWrite(10,duty_10); // uint8_t duty_10
-
コメントのうち,必要な行を有効にする。
-
補足説明
- TCCR1Bレジスターの下位3ビットで,分周比が決められる。
- このPWM周波数は,以下の式で決められる。
- 16MHz / (分周比) / (255*2)
- デフォルト値の例:16MHz/64/(255*2)≒490.2
- 8ビットのカウンターで0->255->0->255を繰り返すため,(255*2)が周期となる。
- phase-correct PWM mode(8ビット位相基準PWM動作)と呼ばれている。
-
参考URL
duty:16ビット未満,周波数を(ある程度任意に)設定する
10ピン限定。9ピンに出す方法がわからない。できなさそう?
以下の例は,4kHz 80%に設定している。
TCCR1A = 0b00100001;
TCCR1B = 0b00010000 | 0b001 ; // div = 1
OCR1A=(uint16_t)(8000000 / 1 / 4000); // f=4kHz
OCR1B=(uint16_t)(8000000 / 1 / 4000 * 80 / 100); // duty=80%
設定したOCR1A
が,Duty精度となる。上記例では,8000000/4000=2000段階となる。(11ビット弱)
- 補足説明
- 2行目の
0b001
が分周比設定で,基本周波数を決めている。以下のようになっている。
- 2行目の
// |CS12|CS11|CS10|=001 1分周 122Hz(=16MHz/(65535*2))
// |CS12|CS11|CS10|=010 8分周 15.26Hz
// |CS12|CS11|CS10|=011 64分周 1.91Hz
// |CS12|CS11|CS10|=100 256分周 0.477Hz
// |CS12|CS11|CS10|=101 1024分周 0.119Hz
-
122Hz未満の周波数にする場合,適当に分周を設定する。
- たとえば100Hzなら,8分周にする。
-
TCCR1B
の式の後半を書き換え,さらにOCR1A
およびOCR1B
の/ 1
の部分を変更する。
-
動作解説
- 位相/周波数基準PWM動作というモードを使っている。
- このPWMの基本周波数は,以下の式で決められる。
- 16MHz / 分周比 / (65535*2) * 65535 = 8MHz / 分周比 / 65535
- 上記の例:16MHz/1/(65535*2)≒122
- 16ビットのカウンターで0->65535->0->65535を繰り返すため,(65535*2)が周期となる。
- 16ビットレジスタ
OCR1A
にて,カウンターの上限値が決められる。- 65535の場合,基本周期そのものとなる。
- 65535 >
OCR1A
の場合,カウンターがOCR1A
に到達した時に,65535を待たずにリセットされる。すなわち,OCR1A
により,基本周期が短くなる。
- カウンターが16ビットレジスタ
OCR1B
にて設定した値よりも小さい時に,Hが出力される。 -
OCR1A
は,基本周波数との比になる。具体的には,以下の式となる。
OCR1A = 65535 * 基本周波数 / 設定周波数
= 65535 * 16MHz / 分周比 / (65535*2) / 設定周波数
= 8MHz / 分周比 / 設定周波数
-
OCR1B
も同様。
-参考URL
- http://blog.kts.jp.net/arduino-pwm-change-freq/
- http://garretlab.web.fc2.com/arduino/inside/hardware/arduino/avr/cores/arduino/wiring_analog.c/analogWrite.html