「ATmega328でのタイマとPWMの使用方法」の版間の差分
編集の要約なし |
細 (文字列「</source>」を「</syntaxhighlight>」に置換) |
||
(2人の利用者による、間の16版が非表示) | |||
6行目: | 6行目: | ||
== タイマとPWM == | == タイマとPWM == | ||
PWMを使用するには、まずタイマについて理解しなければならない。<br> | PWMを使用するには、まずタイマについて理解しなければならない。<br> | ||
タイマには、8bitタイマと16bitタイマがある。<br> | |||
<br> | <br> | ||
8bitタイマは、0 - 255のパターンを表すことができる。<br> | 8bitタイマは、0 - 255のパターンを表すことができる。<br> | ||
17行目: | 17行目: | ||
<br> | <br> | ||
タイマとPWMの関係を下図に示す。(タイマは実線(青)とし、PWM出力は実線(赤)とする)<br> | タイマとPWMの関係を下図に示す。(タイマは実線(青)とし、PWM出力は実線(赤)とする)<br> | ||
[[ファイル:ATmega328 Timer PWM 1.jpg|フレームなし|中央]] | |||
<br> | <br> | ||
タイマ(カウンタ)は、0からTOP値までカウントしていく。(青線)<br> | タイマ(カウンタ)は、0からTOP値までカウントしていく。(青線)<br> | ||
49行目: | 50行目: | ||
タイマとPWMの関係を再度、下図に示す。(タイマは実線(青)とし、PWM出力は実線(赤)とする)<br> | タイマとPWMの関係を再度、下図に示す。(タイマは実線(青)とし、PWM出力は実線(赤)とする)<br> | ||
下図は、タイマ0(8bitタイマ)の図だが、他のタイマも似たものとなる。<br> | 下図は、タイマ0(8bitタイマ)の図だが、他のタイマも似たものとなる。<br> | ||
[[ファイル:ATmega328 Timer PWM 1.jpg|フレームなし|中央]] | |||
<br> | <br> | ||
下記にタイマとPWMを使用するための説明を行う。<br> | 下記にタイマとPWMを使用するための説明を行う。<br> | ||
70行目: | 72行目: | ||
<br> | <br> | ||
<center> | <center> | ||
{| class="wikitable" | {| class="wikitable" | ||
! colspan = "4" | ピンの役割 | |||
|- | |- | ||
! !! 8bitタイマ(タイマ0) !! 16bitタイマ(タイマ1) !! 8bitタイマ(タイマ2) | ! !! 8bitタイマ(タイマ0) !! 16bitタイマ(タイマ1) !! 8bitタイマ(タイマ2) | ||
79行目: | 81行目: | ||
| ピン出力 || OCR0A<br>OCR0B || OCR1A<br>OCR1B || OCR2A<br>OCR2B | | ピン出力 || OCR0A<br>OCR0B || OCR1A<br>OCR1B || OCR2A<br>OCR2B | ||
|- | |- | ||
| ピン名 || PD6(OCR0A)<br>PD5(OCR0B) || PB1(OCR1A)<br>PB2( | | ピン名 || PD6(OCR0A)<br>PD5(OCR0B) || PB1(OCR1A)<br>PB2(OCR1B) || PB3(OCR2A)<br>PD3(OCR2B) | ||
|} | |} | ||
</center> | </center> | ||
103行目: | 105行目: | ||
|- | |- | ||
| | | | ||
! colspan="2" | PWM出力方法(コンペアマッチA)<br>出力ピン : OCR0A | ! colspan="2" | PWM出力方法(コンペアマッチA)<br>出力ピン : OCR0A(PD6) | ||
! colspan="2" | PWM出力方法(コンペアマッチB)<br>出力ピン : OCR0B | ! colspan="2" | PWM出力方法(コンペアマッチB)<br>出力ピン : OCR0B(PD5) | ||
! 設定なし | ! 設定なし | ||
! 設定なし | ! 設定なし | ||
157行目: | 159行目: | ||
! colspan="5" | WGMの役割 タイマモード設定 | ! colspan="5" | WGMの役割 タイマモード設定 | ||
|- | |- | ||
! WGM02 !! WGM01 !! | ! WGM02 !! WGM01 !! WGM00 !! 動作モード !! TOP | ||
|- | |- | ||
| 0 || 0 || 0 || 標準 || 0xFF | | 0 || 0 || 0 || 標準 || 0xFF | ||
163行目: | 165行目: | ||
| 1 || 0 || 0 || 予約 || - | | 1 || 0 || 0 || 予約 || - | ||
|- | |- | ||
| 0 || | | 0 || 0 || 1 || 位相基準PWM || 0xFF | ||
|- | |- | ||
| 1 || 0 || 1 || 位相基準PWM || | | 1 || 0 || 1 || 位相基準PWM || OCR0A | ||
|- | |- | ||
| 0 || 1 || 0 || CTC || | | 0 || 1 || 0 || CTC || OCR0A | ||
|- | |- | ||
| 1 || 1 || 0 || 予約 || - | | 1 || 1 || 0 || 予約 || - | ||
173行目: | 175行目: | ||
| 0 || 1 || 1 || 高速PWM || 0xFF | | 0 || 1 || 1 || 高速PWM || 0xFF | ||
|- | |- | ||
| 1 || 1 || 1 || 高速PWM || | | 1 || 1 || 1 || 高速PWM || OCR0A | ||
|} | |} | ||
</center> | </center> | ||
185行目: | 187行目: | ||
! ビット名(TCCR0B) | ! ビット名(TCCR0B) | ||
| 2 || 1 || 0 | | 2 || 1 || 0 | ||
|- | |||
! タイマ停止 | |||
| 0 || 0 || 0 | |||
|- | |- | ||
! 分周なし | ! 分周なし | ||
217行目: | 222行目: | ||
|- | |- | ||
| | | | ||
! colspan="2" | PWM出力方法<br>(コンペアマッチA)<br>出力ピン : OCR1A | ! colspan="2" | PWM出力方法<br>(コンペアマッチA)<br>出力ピン : OCR1A(PB1) | ||
! colspan="2" | PWM出力方法<br>(コンペアマッチB)<br>出力ピン : OCR1B | ! colspan="2" | PWM出力方法<br>(コンペアマッチB)<br>出力ピン : OCR1B(PB2) | ||
! 設定なし | ! 設定なし | ||
! 設定なし | ! 設定なし | ||
246行目: | 251行目: | ||
<center> | <center> | ||
{| class="wikitable" | {| class="wikitable" | ||
! colspan="9" | TCCR1B | ! colspan="9" | TCCR1B タイマ1設定レジスタ | ||
|- | |- | ||
| | | | ||
273行目: | 278行目: | ||
! colspan="6" | WGMの役割 タイマモード設定 | ! colspan="6" | WGMの役割 タイマモード設定 | ||
|- | |- | ||
! WGM13 !! WGM12 !! WGM11 !! | ! WGM13 !! WGM12 !! WGM11 !! WGM10 !! 動作モード !! TOP | ||
|- | |- | ||
| 0 || 0 || 0 || 0 || 標準 || 0xFFFF | | 0 || 0 || 0 || 0 || 標準 || 0xFFFF | ||
279行目: | 284行目: | ||
| 0 || 0 || 0 || 1 || 8bit位相標準PWM || 0x00FF | | 0 || 0 || 0 || 1 || 8bit位相標準PWM || 0x00FF | ||
|- | |- | ||
| 0 || 0 || 0 || 0 || 標準 || | | 0 || 0 || 1 || 0 || 9bit位相標準PWM || 0x1FFF | ||
|- | |||
| 0 || 0 || 1 || 1 || 10bit位相標準PWM || 0x03FF | |||
|- | |||
| 1 || 0 || 0 || 0 || 位相・周波数基準PWM || ICR1 | |||
|- | |||
| 1 || 0 || 0 || 1 || 位相・周波数基準PWM || OCR1A | |||
|- | |||
| 1 || 0 || 1 || 0 || 位相基準PWM || ICR1 | |||
|- | |||
| 1 || 0 || 1 || 1 || 位相基準PWM || OCR1A | |||
|- | |||
| 0 || 1 || 0 || 0 || CTC || OCR1A | |||
|- | |||
| 1 || 1 || 0 || 0 || CTC || ICR1 | |||
|- | |||
| 1 || 1 || 0 || 1 || 予約 || - | |||
|- | |||
| 0 || 1 || 0 || 1 || 8bit高速PWM || 0x00FF | |||
|- | |||
| 0 || 1 || 1 || 0 || 9bit高速PWM || 0x01FF | |||
|- | |||
| 0 || 1 || 1 || 1 || 10bit高速PWM || 0x03FF | |||
|- | |||
| 1 || 1 || 1 || 0 || 高速PWM ||ICR1 | |||
|- | |||
| 1 || 1 || 1 || 1 || 高速PWM || OCR1A | |||
|} | |||
</center> | |||
<br> | |||
<center> | |||
{| class="wikitable" | |||
! colspan="4" | クロック分周の設定 | |||
|- | |||
! 設定 !! CS12 !! CS11 !! CS10 | |||
|- | |||
! ビット名(TCCR1B) | |||
| 2 || 1 || 0 | |||
|- | |||
! タイマ停止 | |||
| 0 || 0 || 0 | |||
|- | |||
! 分周なし | |||
| 0 || 0 || 1 | |||
|- | |||
! 分周 1 / 8 | |||
| 0 || 1 || 0 | |||
|- | |||
! 分周 1 / 64 | |||
| 0 || 1 || 1 | |||
|- | |||
! 分周 1 / 256 | |||
| 1 || 0 || 0 | |||
|- | |||
! 分周 1 / 1024 | |||
| 1 || 0 || 1 | |||
|- | |||
! 外部クロック<br>T0を立ち下がりエッジで | |||
| 1 || 1 || 0 | |||
|- | |||
! 外部クロック<br>T0を立ち上がりエッジで | |||
| 1 || 1 || 1 | |||
|} | |||
</center> | |||
<br><br> | |||
== タイマ2のレジスタ設定 == | |||
タイマ2の設定レジスタであるTCCR2Aの設定を下表に示す。<br> | |||
<center> | |||
{| class="wikitable" | |||
! colspan="10" | TCCR2A タイマ2設定レジスタ | |||
|- | |||
| | |||
! colspan="2" | PWM出力方法(コンペアマッチA)<br>出力ピン : OCR2A | |||
! colspan="2" | PWM出力方法(コンペアマッチB)<br>出力ピン : OCR2B | |||
! 設定なし | |||
! 設定なし | |||
! colspan="3" | タイマのモード設定(一部) | |||
|- | |||
! ビット名 | |||
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0 || | |||
|- | |||
! レジスタ名 | |||
| COM2A1 || COM2A0 || COM2B1 || COM2B0 || - || - || WGM21 || WGM20 || | |||
|- | |||
! 波形出力なし | |||
| 0 || 0 || 0 || 0 || - || - || 0 || 0 || 標準 | |||
|- | |||
! コンペアマッチで出力が反転 | |||
| 0 || 1 || 0 || 1 || - || - || 1 || 0 || CTC | |||
|- | |||
! コンペアマッチでLow出力 | |||
| 1 || 0 || 1 || 0 || - || - || 0 || 1 || 位相基準PWM | |||
|- | |||
! コンペアマッチでHigh出力 | |||
| 1 || 1 || 1 || 1 || - || - || 1 || 1 || 高速PWM | |||
|} | |||
</center> | |||
<br> | |||
<center> | |||
{| class="wikitable" | |||
! colspan="9" | TCCR2B タイマ2設定レジスタ | |||
|- | |||
| | |||
! colspan="2" | OCR2AおよびOCR2Bの強制変更 | |||
! 設定なし | |||
! 設定なし | |||
! タイマモード設定(一部) | |||
! colspan="3" | クロック分周の設定 | |||
|- | |||
! ビット名 | |||
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0 | |||
|- | |||
! レジスタ名 | |||
| FOC2A || FOC2B || - || - || WGM22 || CS22 || CS21 || CS20 | |||
|- | |||
! 役割 | |||
| colspan="2" | 強制コンペアマッチ<br>(非PWMモードのみ) | |||
| - || - || 下で説明する | |||
| colspan="3" | クロック分周の選択 | |||
|} | |||
</center> | |||
<br> | |||
<center> | |||
{| class="wikitable" | |||
! colspan="5" | WGMの役割 タイマモード設定 | |||
|- | |||
! WGM22 !! WGM21 !! WGM20 !! 動作モード !! TOP | |||
|- | |||
| 0 || 0 || 0 || 標準 || 0xFF | |||
|- | |||
| 1 || 0 || 0 || 予約 || - | |||
|- | |||
| 0 || 0 || 1 || 8bit位相基準PWM || 0xFF | |||
|- | |||
| 1 || 0 || 1 || 位相基準PWM || OCR2A | |||
|- | |||
| 0 || 1 || 0 || CTC || OCR2A | |||
|- | |||
| 1 || 1 || 0 || 予約 || - | |||
|- | |||
| 0 || 1 || 1 || 8bit高速PWM || 0xFF | |||
|- | |||
| 1 || 1 || 1 || 高速PWM || OCR2A | |||
|} | |||
</center> | |||
<br> | |||
<center> | |||
{| class="wikitable" | |||
! colspan="4" | クロック分周の設定 | |||
|- | |||
! 設定 !! CS22 !! CS21 !! CS20 | |||
|- | |||
! ビット名(TCCR2B) | |||
| 2 || 1 || 0 | |||
|- | |||
! タイマ停止 | |||
| 0 || 0 || 0 | |||
|- | |- | ||
| 0 || 0 || | ! 分周なし | ||
| 0 || 0 || 1 | |||
|- | |- | ||
| 0 || | ! 分周 1 / 8 | ||
| 0 || 1 || 0 | |||
|- | |- | ||
| 0 || | ! 分周 1 / 32 | ||
| 0 || 1 || 1 | |||
|- | |- | ||
| | ! 分周 1 / 64 | ||
| 1 || 0 || 0 | |||
|- | |- | ||
| | ! 分周 1 / 128 | ||
| 1 || 0 || 1 | |||
|- | |- | ||
| | ! 分周 1 / 256 | ||
| 1 || 1 || 0 | |||
|- | |- | ||
| | ! 分周 1 / 1024 | ||
| 1 || 1 || 1 | |||
|} | |} | ||
</center> | </center> | ||
<br><br> | |||
== PWMを使用するときの設定 == | |||
* タイマ0(8bit) | |||
*:レジスタ : TCCR0AとTCCR0B | |||
*:HIGH時間を指定する : OCR0A(PD6),OCR0B(PD5) | |||
* タイマ1(16bit) | |||
*: レジスタ : TCCR1AとTCCR1B | |||
*: HIGH時間を指定する : OCR1A(PB1),OCR1B(PB2) | |||
*: TOP値を指定する : ICR1 | |||
* タイマ2(8bit) | |||
*: レジスタ : TCCR2AとTCCR2B | |||
*: HIGH時間を指定する : OCR2A(PB3)とOCR2B(PD3) | |||
<br><br> | |||
== ソースコード == | |||
タイマ1を使用してPWM制御でLEDを点滅させる。<br> | |||
PB0にスイッチを付けて、スイッチを押下した時にLEDが点滅するプログラムを以下に記述する。<br> | |||
なお、PORTB = 0b00000001とすることで、PB0のプルアップが有効になるので、プルアップ抵抗を付ける必要はない。<br> | |||
<br> | |||
<syntaxhighlight lang="c++"> | |||
// タイマ0 : 8bit : 0 - 255 | |||
// タイマ1 : 16bit : 0 - 65535 | |||
// 1[MHz]で動作すると仮定すると、1クロック0.000001[s]なので | |||
// タイマ1 : 0.000001 * 65536 = 65.5[ms]までOK | |||
/* 高速PWMモード | |||
ICR1 : 最大値 | |||
OCR1A(データシートのピン配置ではOC1A) : 真ん中 | |||
| | |||
ICR1 ----/\------------------------ | |||
| / \ | |||
| / \ / | |||
OCR1A /---------\------/----------- | |||
| / \ / | |||
|/ \/ | |||
PB1 出力波形 | |||
| | |||
| ̄| | ̄| | |||
| |__________________| |___ | |||
| | |||
CTCモード : 最大値はICR1 | |||
通常モード : 最大値はOCR1A | |||
*/ | |||
// タイマ1を使用 | |||
#include <avr/io.h> | |||
int main() | |||
{ | |||
// 制御レジスタA | |||
TCCR1A = 0b10000010; // 10 : コンペアマッチAでLOW, 10 : 高速PWM動作 | |||
// 制御レジスタB | |||
TCCR1B = 0b00011001; // 11 : 高速PWM動作, 001 : 分周なし | |||
// 最大値 | |||
ICR1 = 64999; // 0から数える(全体時間は65[ms]) | |||
// 0.000001 * 65000 : 65[ms] | |||
// HIGHの時間(クロック数) | |||
OCR1A = 32499; // 0から数える(High時間は32.5[ms]) | |||
// 0.000001 * 32500 : 32.5[ms] | |||
// OCR1AはPB1ピン | |||
DDRB = 0b11111110; // PB0のみ入力 | |||
PORTB = 0b00000001; // PB0をプルアップ | |||
while(1) | |||
{ | |||
if(bit_is_clear(PINB, PB0)) | |||
{ // PB0が0(オン)の場合 | |||
OCR1A = 32499; // PB1 HIGH時間 32.5[ms] | |||
// OCR1Aの値を変えることで、LEDが光る時間を調節できる | |||
} | |||
else | |||
{ | |||
OCR1A = 0; // PB1 HIGH時間 0[ms] | |||
} | |||
} | |||
return 0; | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
===== PWMの設定 ===== | |||
まず、TCCR1AとTCCR1Bで、タイマ1を使用するための設定を行う。<br> | |||
<br> | |||
次に、ICR1で、タイマ(カウンタ)のTOP値(上記では、ICR1 = 64999)を決める。0からカウントするので、65000回カウントアップされる。<br> | |||
1[MHz](1[us])なので、0.000001 * 65000 = 65[ms]が1周期となる。<br> | |||
<br> | |||
最後に、OCR1Aで、PWM波形のHIGH時間(OCR1A = 32499)を決める。<br> | |||
同様に、0.000001 * 32500 = 32.5[ms]が、1周期のHIGH時間となる。<br> | |||
<br> | |||
===== その他の設定 ===== | |||
まず、DDRBで入出力設定を行い、PORTBでPB0のプルアップを有効にする。<br> | |||
<br> | |||
次に、bit_is_clear(PINB, PB0)関数において、PB0が0(スイッチがオンの状態)の時、trueとなる。<br> | |||
<br> | |||
スイッチがオンの状態で、PWM出力波形のHIGH時間を32.5[ms]にする。<br> | |||
スイッチがオフの状態で、HIGH時間を0[ms]にする。<br> | |||
<br> | |||
===== 作成した回路 ===== | |||
ここでは、スイッチを押下するとPWM制御により、LEDが点滅する回路を以下に記載する。<br> | |||
[[ファイル:ATmega328 Timer PWM 2.jpg|フレームなし|中央]] | |||
<br><br> | |||
== サンプルコード2 == | |||
タイマ割り込みでデューティ比を変化せるプログラムを以下に記述する。<br> | |||
PWMの周期を2048[us]、12.5[ms]ごとに割り込みを発生させて、デューティ比を0.78と0.04に切り替える。<br> | |||
<syntaxhighlight lang="c++"> | |||
#include <avr/io.h> | |||
#include <util/delay.h> | |||
#include <avr/interrupt.h> | |||
unsigned char i; | |||
// タイマ2 コンペアマッチA割り込み | |||
ISR(TIMER2_COMPA_vect) | |||
{ | |||
if(i == 255) | |||
{ | |||
i = 0; | |||
} | |||
else | |||
{ | |||
i++; | |||
} | |||
if(i % 2 == 0) | |||
{ | |||
OCR0A = 10; | |||
} | |||
else | |||
{ | |||
OCR0A = 200; | |||
} | |||
} | |||
int main() | |||
{ | |||
// タイマ0 | |||
TCCR0A = 0b10100011; // 1010 = OCR0A出力とOCR1A出力, 011 = 高速PWM(TOP値 = 0xFF) | |||
TCCR0B = 0b00000010; // 010 = 分周比 : 8(PWM周期 = 1 / (1,000,000[Hz] / 8分周) * 256 = 2048[us]) | |||
// タイマ2(割り込み用 : コンペアマッチAで割り込み開始) | |||
TCCR2A = 0b00000010; // 0000 = ピン出力なし, 010 = CTC(TOP値 = OCR2A) | |||
TCCR2B = 0b00000101; // 101 = 分周比 : 128 | |||
OCR2A = 97; // 12.5[ms]ごとに割り込み(1 / (1,000,000[Hz] / 128分周) * 98) | |||
TIMSK2 = 0b0000010; // コンペアマッチAの割り込みを有効 | |||
// 方向レジスタの設定 | |||
DDRB = 0xFF; // PORTB2を出力 | |||
DDRD = 0xFF; // PORTD5を出力 | |||
// 割り込み許可 | |||
sei(); | |||
while(1) | |||
{ | |||
; | |||
} | |||
} | |||
</syntaxhighlight> | |||
<br><br> | <br><br> | ||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:AVR]] | [[カテゴリ:AVR]] |
2021年11月24日 (水) 18:07時点における最新版
概要
タイマには、8bitタイマと16bitタイマがあり、16bitの方がより多くのパターンを表すことができる。
また、ATmega48、88、168、328にはPWMを使えるピンが6つある。
タイマとPWM
PWMを使用するには、まずタイマについて理解しなければならない。
タイマには、8bitタイマと16bitタイマがある。
8bitタイマは、0 - 255のパターンを表すことができる。
16bitタイマは、0 - 65535のパターンを表すことができる。
例 :
ATmega328の動作周波数が1[MHz]のとき、1/1,000,000 = 0.000001[s]が表せる最小の時間なので、
8bitタイマでは、最大0.000001 * 256 = 0.256[ms]までの時間を表すことができる。
16bitタイマでは、最大0.000001 * 65536 = 65.536[ms]までの時間を表すことができる。
タイマとPWMの関係を下図に示す。(タイマは実線(青)とし、PWM出力は実線(赤)とする)
タイマ(カウンタ)は、0からTOP値までカウントしていく。(青線)
TOP値を超えるとオーバーフロー割り込みが発生し、TOP値を超えたことを知らせる。
その後、タイマ(カウンタ)の値は0に戻り、カウントが再開される。
また、指定した値に到達したことを知らせる割り込み"比較一致割り込み(コンペアマッチ)"等の割り込みもある。
比較一致のときに、波形をHIGH、LOW、反転させることでPWM制御ができる。(赤線)
キーワード
- タイマモードの種類
- 標準モード (普通のタイマ、カウンタを使う)
- CTCモード (カウンタの上限を自由に設定)
- 高速PWM (タイマが、ノコギリ波)
- 位相基準PWM (タイマが、三角波)
- タイマ、PWMが出力できるピン
- OCR0A(PD6)とOCR0B(PD5)
- OCR1A(PB1)とOCR1B(PB2)
- OCR2A(PB3)とOCR2B(PD3)
- タイマとPWMを使うための設定(これらは、タイマ設定レジスタである)
- 1のための設定: TCCR0AとTCCR0B
- 2のための設定: TCCR1AとTCCR1B
- 3のための設定: TCCR2AとTCCR2B
タイマモード
タイマのモードには、標準、CTC、位相基準PWM、高速PWMがある。
PWMを使用する時は、タイマモードを位相基準PWM、高速PWMに設定することで使用できる。
タイマとPWMの関係を再度、下図に示す。(タイマは実線(青)とし、PWM出力は実線(赤)とする)
下図は、タイマ0(8bitタイマ)の図だが、他のタイマも似たものとなる。
下記にタイマとPWMを使用するための説明を行う。
- 標準モードは、カウンタとして動作させたい時に使用する。(普通のタイマ)
- コンペアマッチ(指定値とタイマの値が一致)するための指定値はOCRnAまたはOCRnB(nは数字、後述)で設定する。
- その値を超えたらTOPの値になるまでPWM信号は0を出力し、その後、タイマは0に戻る。
- しかし、TOPの値をTOP = OCRnAまたはTOP = OCRnBとすることで、TOPの値まで行かなくてもタイマを0に戻すことができる。
- これを、CTCモードという。
- 高速PWMモードは、PWMを使うときに使用する。
- 動作原理は、上図の通りである。(タイマはノコギリ波で表される)
- 位相基準PWMモードは、高速PWMモードとは違い、タイマは三角波で表される。
PWM出力ができるピン
ATmega48、88、168、328にはPWMを使えるピンが6つある。
OCR0A(PD6)とOCR0B(PD5)、OCR1A(PB1)とOCR1B(PB2)、OCR2A(PB3)とOCR2B(PD3)
上記6つのピンに対するタイマやPWMの設定は、それぞれTCCR0AとTCCR0B、TCCR1AとTCCR1B、TCCR2AとTCCR2Bで設定する。
TCCRnAは、タイマレジスタの7 - 6bitで使い方を指定し、
TCCRnBは、タイマレジスタの5 - 4bitで使い方を指定する。
ピンの役割 | |||
---|---|---|---|
8bitタイマ(タイマ0) | 16bitタイマ(タイマ1) | 8bitタイマ(タイマ2) | |
ピン設定 | TCCR0A TCCR0B |
TCCR1A TCCR1B |
TCCR2A TCCR2B |
ピン出力 | OCR0A OCR0B |
OCR1A OCR1B |
OCR2A OCR2B |
ピン名 | PD6(OCR0A) PD5(OCR0B) |
PB1(OCR1A) PB2(OCR1B) |
PB3(OCR2A) PD3(OCR2B) |
タイマ設定レジスタ
8bitタイマであるタイマ0(OCR0A(PD6)とOCR0B(PD5))を使用する場合は、TCCR0AとTCCR0BでタイマとPWMの設定を行う。
TCCR0Aで、PWMのコンペアマッチとタイマのモード設定を行い、TCCR0BでタイマのTOP値と、クロック分周の設定を行う。
詳細は、以下のタイマ0のレジスタ設定に示す。
16bitタイマであるタイマ1(OCR1A(PB1)とOCR1B(PB2))を使用する場合は、TCCR1AとTCCR1BでタイマとPWMの設定を行う。
詳細は、以下のタイマ1のレジスタ設定に示す。
8bitタイマであるタイマ2(OCR2A(PB3)とOCR2B(PD3))を使用する場合は、タイマ0とほぼ同じなので割愛する。
タイマ0のレジスタ設定
タイマ0の設定レジスタであるTCCR0Aの設定を下表に示す。
TCCR0A タイマ0設定レジスタ | |||||||||
---|---|---|---|---|---|---|---|---|---|
PWM出力方法(コンペアマッチA) 出力ピン : OCR0A(PD6) |
PWM出力方法(コンペアマッチB) 出力ピン : OCR0B(PD5) |
設定なし | 設定なし | タイマのモード設定(一部) | |||||
ビット名 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
レジスタ名 | COM0A1 | COM0A0 | COM0B1 | COM0B0 | - | - | WGM01 | WGM00 | |
波形出力なし | 0 | 0 | 0 | 0 | - | - | 0 | 0 | 標準 |
コンペアマッチで出力が反転 | 0 | 1 | 0 | 1 | - | - | 1 | 0 | CTC |
コンペアマッチでLow出力 | 1 | 0 | 1 | 0 | - | - | 0 | 1 | 位相基準PWM |
コンペアマッチでHigh出力 | 1 | 1 | 1 | 1 | - | - | 1 | 1 | 高速PWM |
TCCR0B タイマ0設定レジスタ | ||||||||
---|---|---|---|---|---|---|---|---|
OC0RAおよびOCR0Bの強制変更 | 設定なし | 設定なし | タイマモード設定(一部) | クロック分周の設定 | ||||
ビット名 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
レジスタ名 | FOC0A | FOC0B | - | - | WGM02 | CS02 | CS01 | CS00 |
役割 | 強制コンペアマッチ (非PWMモードのみ) |
- | - | 下で説明する | クロック分周の選択 |
WGMの役割 タイマモード設定 | ||||
---|---|---|---|---|
WGM02 | WGM01 | WGM00 | 動作モード | TOP |
0 | 0 | 0 | 標準 | 0xFF |
1 | 0 | 0 | 予約 | - |
0 | 0 | 1 | 位相基準PWM | 0xFF |
1 | 0 | 1 | 位相基準PWM | OCR0A |
0 | 1 | 0 | CTC | OCR0A |
1 | 1 | 0 | 予約 | - |
0 | 1 | 1 | 高速PWM | 0xFF |
1 | 1 | 1 | 高速PWM | OCR0A |
クロック分周の設定 | |||
---|---|---|---|
設定 | CS02 | CS01 | CS00 |
ビット名(TCCR0B) | 2 | 1 | 0 |
タイマ停止 | 0 | 0 | 0 |
分周なし | 0 | 0 | 1 |
分周 1 / 8 | 0 | 1 | 0 |
分周 1 / 64 | 0 | 1 | 1 |
分周 1 / 256 | 1 | 0 | 0 |
分周 1 / 1024 | 1 | 0 | 1 |
外部クロック T0を立ち下がりエッジで |
1 | 1 | 0 |
外部クロック T0を立ち上がりエッジで |
1 | 1 | 1 |
タイマ1のレジスタ設定
タイマ1の設定レジスタであるTCCR1Aの設定を下表に示す。
TCCR1A タイマ1設定レジスタ | ||||||||
---|---|---|---|---|---|---|---|---|
PWM出力方法 (コンペアマッチA) 出力ピン : OCR1A(PB1) |
PWM出力方法 (コンペアマッチB) 出力ピン : OCR1B(PB2) |
設定なし | 設定なし | タイマのモード設定(一部) | ||||
ビット名 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
レジスタ名 | COM1A1 | COM1A0 | COM1B1 | COM1B0 | - | - | WGM11 | WGM10 |
波形出力なし | 0 | 0 | 0 | 0 | - | - | タイマのモード設定 (下に記載) | |
コンペアマッチで出力が反転 | 0 | 1 | 0 | 1 | - | - | ||
コンペアマッチでLow出力 | 1 | 0 | 1 | 0 | - | - | ||
コンペアマッチでHigh出力 | 1 | 1 | 1 | 1 | - | - |
TCCR1B タイマ1設定レジスタ | ||||||||
---|---|---|---|---|---|---|---|---|
インプットキャプチャ | 設定なし | タイマモード設定(一部) | クロック分周の設定 | |||||
ビット名 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
レジスタ名 | 1CNC1 | 1CES1 | - | WGM13 | WGM12 | CS12 | CS11 | CS10 |
役割 | ノイズ除去器を有効にする (4回同じ入力で1入力される) |
エッジ設定 0 : 立ち下がり 1 : 立ち上がり |
- | タイマモード設定 (下で説明する) |
クロック分周の選択 |
WGMの役割 タイマモード設定 | |||||
---|---|---|---|---|---|
WGM13 | WGM12 | WGM11 | WGM10 | 動作モード | TOP |
0 | 0 | 0 | 0 | 標準 | 0xFFFF |
0 | 0 | 0 | 1 | 8bit位相標準PWM | 0x00FF |
0 | 0 | 1 | 0 | 9bit位相標準PWM | 0x1FFF |
0 | 0 | 1 | 1 | 10bit位相標準PWM | 0x03FF |
1 | 0 | 0 | 0 | 位相・周波数基準PWM | ICR1 |
1 | 0 | 0 | 1 | 位相・周波数基準PWM | OCR1A |
1 | 0 | 1 | 0 | 位相基準PWM | ICR1 |
1 | 0 | 1 | 1 | 位相基準PWM | OCR1A |
0 | 1 | 0 | 0 | CTC | OCR1A |
1 | 1 | 0 | 0 | CTC | ICR1 |
1 | 1 | 0 | 1 | 予約 | - |
0 | 1 | 0 | 1 | 8bit高速PWM | 0x00FF |
0 | 1 | 1 | 0 | 9bit高速PWM | 0x01FF |
0 | 1 | 1 | 1 | 10bit高速PWM | 0x03FF |
1 | 1 | 1 | 0 | 高速PWM | ICR1 |
1 | 1 | 1 | 1 | 高速PWM | OCR1A |
クロック分周の設定 | |||
---|---|---|---|
設定 | CS12 | CS11 | CS10 |
ビット名(TCCR1B) | 2 | 1 | 0 |
タイマ停止 | 0 | 0 | 0 |
分周なし | 0 | 0 | 1 |
分周 1 / 8 | 0 | 1 | 0 |
分周 1 / 64 | 0 | 1 | 1 |
分周 1 / 256 | 1 | 0 | 0 |
分周 1 / 1024 | 1 | 0 | 1 |
外部クロック T0を立ち下がりエッジで |
1 | 1 | 0 |
外部クロック T0を立ち上がりエッジで |
1 | 1 | 1 |
タイマ2のレジスタ設定
タイマ2の設定レジスタであるTCCR2Aの設定を下表に示す。
TCCR2A タイマ2設定レジスタ | |||||||||
---|---|---|---|---|---|---|---|---|---|
PWM出力方法(コンペアマッチA) 出力ピン : OCR2A |
PWM出力方法(コンペアマッチB) 出力ピン : OCR2B |
設定なし | 設定なし | タイマのモード設定(一部) | |||||
ビット名 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
レジスタ名 | COM2A1 | COM2A0 | COM2B1 | COM2B0 | - | - | WGM21 | WGM20 | |
波形出力なし | 0 | 0 | 0 | 0 | - | - | 0 | 0 | 標準 |
コンペアマッチで出力が反転 | 0 | 1 | 0 | 1 | - | - | 1 | 0 | CTC |
コンペアマッチでLow出力 | 1 | 0 | 1 | 0 | - | - | 0 | 1 | 位相基準PWM |
コンペアマッチでHigh出力 | 1 | 1 | 1 | 1 | - | - | 1 | 1 | 高速PWM |
TCCR2B タイマ2設定レジスタ | ||||||||
---|---|---|---|---|---|---|---|---|
OCR2AおよびOCR2Bの強制変更 | 設定なし | 設定なし | タイマモード設定(一部) | クロック分周の設定 | ||||
ビット名 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
レジスタ名 | FOC2A | FOC2B | - | - | WGM22 | CS22 | CS21 | CS20 |
役割 | 強制コンペアマッチ (非PWMモードのみ) |
- | - | 下で説明する | クロック分周の選択 |
WGMの役割 タイマモード設定 | ||||
---|---|---|---|---|
WGM22 | WGM21 | WGM20 | 動作モード | TOP |
0 | 0 | 0 | 標準 | 0xFF |
1 | 0 | 0 | 予約 | - |
0 | 0 | 1 | 8bit位相基準PWM | 0xFF |
1 | 0 | 1 | 位相基準PWM | OCR2A |
0 | 1 | 0 | CTC | OCR2A |
1 | 1 | 0 | 予約 | - |
0 | 1 | 1 | 8bit高速PWM | 0xFF |
1 | 1 | 1 | 高速PWM | OCR2A |
クロック分周の設定 | |||
---|---|---|---|
設定 | CS22 | CS21 | CS20 |
ビット名(TCCR2B) | 2 | 1 | 0 |
タイマ停止 | 0 | 0 | 0 |
分周なし | 0 | 0 | 1 |
分周 1 / 8 | 0 | 1 | 0 |
分周 1 / 32 | 0 | 1 | 1 |
分周 1 / 64 | 1 | 0 | 0 |
分周 1 / 128 | 1 | 0 | 1 |
分周 1 / 256 | 1 | 1 | 0 |
分周 1 / 1024 | 1 | 1 | 1 |
PWMを使用するときの設定
- タイマ0(8bit)
- レジスタ : TCCR0AとTCCR0B
- HIGH時間を指定する : OCR0A(PD6),OCR0B(PD5)
- タイマ1(16bit)
- レジスタ : TCCR1AとTCCR1B
- HIGH時間を指定する : OCR1A(PB1),OCR1B(PB2)
- TOP値を指定する : ICR1
- タイマ2(8bit)
- レジスタ : TCCR2AとTCCR2B
- HIGH時間を指定する : OCR2A(PB3)とOCR2B(PD3)
ソースコード
タイマ1を使用してPWM制御でLEDを点滅させる。
PB0にスイッチを付けて、スイッチを押下した時にLEDが点滅するプログラムを以下に記述する。
なお、PORTB = 0b00000001とすることで、PB0のプルアップが有効になるので、プルアップ抵抗を付ける必要はない。
// タイマ0 : 8bit : 0 - 255
// タイマ1 : 16bit : 0 - 65535
// 1[MHz]で動作すると仮定すると、1クロック0.000001[s]なので
// タイマ1 : 0.000001 * 65536 = 65.5[ms]までOK
/* 高速PWMモード
ICR1 : 最大値
OCR1A(データシートのピン配置ではOC1A) : 真ん中
|
ICR1 ----/\------------------------
| / \
| / \ /
OCR1A /---------\------/-----------
| / \ /
|/ \/
PB1 出力波形
|
| ̄| | ̄|
| |__________________| |___
|
CTCモード : 最大値はICR1
通常モード : 最大値はOCR1A
*/
// タイマ1を使用
#include <avr/io.h>
int main()
{
// 制御レジスタA
TCCR1A = 0b10000010; // 10 : コンペアマッチAでLOW, 10 : 高速PWM動作
// 制御レジスタB
TCCR1B = 0b00011001; // 11 : 高速PWM動作, 001 : 分周なし
// 最大値
ICR1 = 64999; // 0から数える(全体時間は65[ms])
// 0.000001 * 65000 : 65[ms]
// HIGHの時間(クロック数)
OCR1A = 32499; // 0から数える(High時間は32.5[ms])
// 0.000001 * 32500 : 32.5[ms]
// OCR1AはPB1ピン
DDRB = 0b11111110; // PB0のみ入力
PORTB = 0b00000001; // PB0をプルアップ
while(1)
{
if(bit_is_clear(PINB, PB0))
{ // PB0が0(オン)の場合
OCR1A = 32499; // PB1 HIGH時間 32.5[ms]
// OCR1Aの値を変えることで、LEDが光る時間を調節できる
}
else
{
OCR1A = 0; // PB1 HIGH時間 0[ms]
}
}
return 0;
}
PWMの設定
まず、TCCR1AとTCCR1Bで、タイマ1を使用するための設定を行う。
次に、ICR1で、タイマ(カウンタ)のTOP値(上記では、ICR1 = 64999)を決める。0からカウントするので、65000回カウントアップされる。
1[MHz](1[us])なので、0.000001 * 65000 = 65[ms]が1周期となる。
最後に、OCR1Aで、PWM波形のHIGH時間(OCR1A = 32499)を決める。
同様に、0.000001 * 32500 = 32.5[ms]が、1周期のHIGH時間となる。
その他の設定
まず、DDRBで入出力設定を行い、PORTBでPB0のプルアップを有効にする。
次に、bit_is_clear(PINB, PB0)関数において、PB0が0(スイッチがオンの状態)の時、trueとなる。
スイッチがオンの状態で、PWM出力波形のHIGH時間を32.5[ms]にする。
スイッチがオフの状態で、HIGH時間を0[ms]にする。
作成した回路
ここでは、スイッチを押下するとPWM制御により、LEDが点滅する回路を以下に記載する。
サンプルコード2
タイマ割り込みでデューティ比を変化せるプログラムを以下に記述する。
PWMの周期を2048[us]、12.5[ms]ごとに割り込みを発生させて、デューティ比を0.78と0.04に切り替える。
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
unsigned char i;
// タイマ2 コンペアマッチA割り込み
ISR(TIMER2_COMPA_vect)
{
if(i == 255)
{
i = 0;
}
else
{
i++;
}
if(i % 2 == 0)
{
OCR0A = 10;
}
else
{
OCR0A = 200;
}
}
int main()
{
// タイマ0
TCCR0A = 0b10100011; // 1010 = OCR0A出力とOCR1A出力, 011 = 高速PWM(TOP値 = 0xFF)
TCCR0B = 0b00000010; // 010 = 分周比 : 8(PWM周期 = 1 / (1,000,000[Hz] / 8分周) * 256 = 2048[us])
// タイマ2(割り込み用 : コンペアマッチAで割り込み開始)
TCCR2A = 0b00000010; // 0000 = ピン出力なし, 010 = CTC(TOP値 = OCR2A)
TCCR2B = 0b00000101; // 101 = 分周比 : 128
OCR2A = 97; // 12.5[ms]ごとに割り込み(1 / (1,000,000[Hz] / 128分周) * 98)
TIMSK2 = 0b0000010; // コンペアマッチAの割り込みを有効
// 方向レジスタの設定
DDRB = 0xFF; // PORTB2を出力
DDRD = 0xFF; // PORTD5を出力
// 割り込み許可
sei();
while(1)
{
;
}
}