そもそもタイマとはなんぞや?
基本的には、時間を計るものであるが、マイコンに搭載されているタイマには、様々な機能がある。例えば、
イベントの発生間隔を計ったり
などである。AVRマイコンにも、同様の機能が搭載されている。ATMega32U4には、4つのタイマが実装されている。それぞれ、
タイマ0 | (1) カウンタ長8bit (2) 独立した2つの比較器(TCNTとの) (3) 比較一致(コンペア・マッチ)で設定値をTCNTに自動的に再設定 (4) PWM出力機能(高速PWM、位相基準PWM) (5) PWMの周期を可変可能 (6) 周波数発生器(プリスケーラ) (7) 3つの独立した割り込みイベント (TOV0, OCF0A, and OCF0B) |
タイマ1 タイマ3 |
(1) カウンタ長16bit (2) 完全な16bit構成 (3) 独立した3つの比較器(TCNTとの) (4) インプット・キャプチャ機能(外部入力のイベント発生時刻の計測等) (5) インプット・キャプチャ機能のノイズキャンセラ (6) 比較一致(コンペア・マッチ)で設定値をTCNTに自動的に再設定 (7) PWM出力機能(高速PWM、位相基準PWM) (8) PWMの周期を可変可能 (9) 周波数発生器(プリスケーラ) (10) 外部イベントのカウンタ (11) 10個の独立した割り込みイベント (TOV1, OCF1A, OCF1B, OCF1C, ICF1, TOV3, OCF3A, OCF3B,OCF3C and ICF3) |
タイマ4 |
(1) カウンタ長8bit (2) Up to 10-Bit Accuracy (3) 独立した3つの比較器(TCNTとの) (4) 比較一致(コンペア・マッチ)で設定値をTCNTに自動的に再設定 (5) PWM出力機能(高速PWM、位相基準PWM) (6) 拡張PWM機能 (7) PWMの周期を可変可能 (8) PWMのチャネルごとに独立したデッドタイム生成器 (9) PWMのレジスタを同期更新 (10) 5個の独立した割り込みイベント (TOV4, OCF4A, OCF4B, OCF4D, FPF4) (11) 高速 同期/非同期クロックモード (12) 独立した周波数発生器(プリスケーラ) |
の様な特徴を持つ。なんだかよく分からんと思うので、詳細については、以降に解説する。
それぞれのタイマの機能は、そのタイマに固有の機能で無ければ、同じように使う事が出来る。
タイマ0の構造
タイマ0は8ビットのカウンタ/タイマである。8ビットというのはTCNTのデータ長で、このレジスタ(カウンタ)がタイマ機能の要となる。
以下に、タイマの全体構成を示す。
図1 タイマユニットの構成
タイマ0の動作モード
タイマ0には、4つの動作モードがある。それぞれ、
レジスタの種類
タイマ0には4つのレジスタがある。それぞれの機能を以下に説明する。
レジスタ名 | 機能 |
TCNT |
プリスケーラもしくは外部からのカウント信号をカウントアップ(もしくはダウン)するレジスタ。プリスケーラの出力するカウント信号は、システムクロックを何分の一かにしたものになる。(後述) カウンタの起動・停止は、カウント信号の有無で行う。 |
OCR0A | 比較・一致(コンペア・マッチ)を行うためのレジスタ。TCNTと比較する値を設定する。TCNTがカウントする数値と比較する事で、時間を計る。一致 が発生した場合は、比較器と波形発生器を通じてPWMやパルス信号の出力を行う。なお、信号の出力パターンについては、TCCR0A、TCCR0Bで設定 する。 |
OCR0B | 比較・一致(コンペア・マッチ)を行うためのレジスタ。OCR0Aと同様。 |
TCCR0A | タイマモードの切り替えなど、タイマユニットの設定を行うレジスタ。 |
TCCR0B | プリスケーラの設定などを行う。 |
TIMSK0 | タイマ0に関連する割り込みをマスクする。 bit2:OCIE0B bit1:OCIE0A bit0:TOIE0 (1で割り込み許可、0で禁止) |
TIFR0 | タイマ0に関連する割り込みを記録する。 bit2:OCF0B bit1:OCF0A bit0:TOV0 (割り込み発生時に1にセット。0を書き込むとイベントをキャンセル出来る) |
以上のレジスタの機能は、タイマモードの設定によって変化する事に注意。
TCCR0Aのビット配列
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
ビットの名称 | COM0A1 | COM0A0 | COM0B1 | COM0B0 | - | - | WGM01 | WGM00 |
機能 | OCR0AレジスタとTCNTの値が一致した 時の波形出力(OC0Aピン)を設定 |
OCR0BレジスタとTCNTの値が一致した 時の波形出力(OC0Bピン)を設定 |
動作モードを設定 |
TCCR0Bのビット配列
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
ビットの名称 | FOC0A | FOCOB | - | - | WGM02 | CS02 | CS01 | CS00 |
機能 | ※1 | ※2 | 動作モードを設定 | プリスケーラ設定※3 |
※1
PWMモード以外で動作。1を書き込むと、OCR0AとTCNTが一致(コンペアマッチ)したとみなされ、OC0Aピンから信号が
出力される。(割り込みイベントは発生しない)
※2
PWMモード以外で動作。1を書き込むと、OCR0BとTCNTが一致(コンペアマッチ)したとみなされ、OC0Bピンから信号が
出力される。(割り込みイベントは発生しない)
※3 プリスケーラによるシステムクロックの分周比は、以下の通り。
CS02 | CS01 | CS00 | 動作 |
0 | 0 | 0 | タイマ停止 |
0 | 0 | 1 | 分周しない(システムクロックを直接供給) |
0 | 1 | 0 | 1/8 |
0 | 1 | 1 | 1/64 |
1 | 0 | 0 | 1/256 |
1 | 0 | 1 | 1/1024 |
1 | 1 | 0 | 外部クロック入力(T0ピン)、立ち下がりエッジ |
1 | 1 | 1 | 外部クロック入力(T0ピン)、立ち上がりエッジ |
標準モードの設定
TCCR0AのWGM01,WGM00及びTCCR0BのWGM02ビットをそれぞれ0に設定すると、標準モードになる。
また、OC0Aピン及びOC0Bピンからデジタル信号の出力を行う場合は、以下の様に設定する。
OC0A(29ピン)の出力設定
TCCR0A bit | 7 | 6 | 備 考 |
ビットの名称 | COM0A1 | COM0A0 | |
波形出力なし | 0 | 0 | PB7は通常のIOポート |
TCNTが255→0で切替 | 0 | 1 | 一致する度にOC0Aが1→0→1の様に切り替わる |
TCNTが255→0でLow | 1 | 0 | |
TCNTが255→0でHigh | 1 | 1 |
OC0B(4ピン)の出力設定
TCCR0A bit | 5 | 4 | 備 考 |
ビットの名称 | COM0B1 | COM0B0 | |
波形出力なし | 0 | 0 | PD0は通常のIOポート |
TCNTが255→0で切替 | 0 | 1 | 一致する度にOC0Bが1→0→1の様に切り替わる |
TCNTが255→0でLow | 1 | 0 | |
TCNTが255→0でHigh | 1 | 1 |
サンプルプログラム (一定周期でボード上のLEDを点滅)
#define F_CPU 16000000 #include < avr/io.h > ISR (TIMER0_OVF_vect) // 割り込みハンドラ int main() DDRC = 0b10000000; // PC7を出力に TCCR0B = 0; // タイマ停止 sei(); // 全ての割り込みを許可 while(1); |
CTCモードの設定
標準モードでは、割り込み周期はプリスケーラの設定でしか変化できないが、CTCモードでは、TCNTの上限値をOCR0Aで設定できるので、設定の自由度が大きくなる。
TCCR0AのWGM1ビットを1、WGM0ビットを0、TCCR0BのWGM2ビットを0に設定すると、CTCモードになる。
OC0A(29ピン)の出力設定
TCCR0A bit | 7 | 6 | 備 考 |
ビットの名称 | COM0A1 | COM0A0 | |
波形出力なし | 0 | 0 | PB7は通常のIOポート |
OCR0Aと値の一致で切替 | 0 | 1 | 一致する度にOC0Aが1→0→1の様に切り替わる |
OCR0Aと値の一致でLow | 1 | 0 | |
OCR0Aと値の一致でHigh | 1 | 1 |
OC0B(4ピン)の出力設定
TCCR0A bit | 5 | 4 | 備 考 |
ビットの名称 | COM0B1 | COM0B0 | |
波形出力なし | 0 | 0 | PD0は通常のIOポート |
OCR0Bと値の一致で切替 | 0 | 1 | 一致する度にOC0Aが1→0→1の様に切り替わる |
OCR0Bと値の一致でLow | 1 | 0 | |
OCR0Bと値の一致でHigh | 1 | 1 |
サンプルプログラム
#define F_CPU 16000000 #include < avr/io.h > ISR (TIMER0_COMPA_vect) // 割り込みハンドラ int main() DDRC = 0b10000000; // IOポートを出力に TCCR0B = 0; // タイマ停止 sei(); // 全ての割り込みを許可 while(1); |
高速PWMモード
こちらを参照のこと。