タイマーを使うときは必ず、(1)ウェーブフォームモードを設定し、(2)クロックの分周比を設定し、(3)出力モードを設定する。
#include <avr/io.h> /* タイマー0 (8ビット)を使ってOC0Aピン(PD6)、OC0Bピン(PD5)からPWM波を出力する。 */ int main(){ TCCR0A |= (1 << WGM01) | (1 << WGM00); // ウェーブフォームモードの設定。Fast PWMモード。 TCCR0B |= (1 << CS01) | (1 << CS00); // CPUクロック分周比の設定。ここでは64分周。PWM周波数は8MHz/64分周/256ステップ ≒ 488Hz。 TCCR0A |= (1 << COM0A1); // 出力モードの設定。コンペアマッチ時にOC0Aピン(PD6)からLを出力、そのままカウントアップしてオーバーフロー時にHを出力。 //TCCR0A |= (1 << COM0A1) | (1 << COM0A0); // インバーティングモード時は逆にコンペアマッチ時にH、オーバーフロー時にL。 TCCR0A |= (1 << COM0B1); // 出力モードの設定。コンペアマッチ時にOC0Bピン(PD5)からLを出力、そのままカウントアップしてオーバーフロー時にHを出力。 //TCCR0A |= (1 << COM0B1) | (1 << COM0B0); // インバーティングモード時は逆にコンペアマッチ時にH、オーバーフロー時にL。 DDRD |= (1 << PD5) | (1 << PD6); // タイマーを設定するだけではダメであって、当該ピンのIOをOUTにしなければならない。 OCR0A = 63; // Output Compare Register AにOC0Aピン(PD6)用のコンペア値を設定する。 OCR0B = 0; // Output Compare Register BにOC0Bピン(PD5)用のコンペア値を設定する。 // コンペア値を0にしても、オーバーフロー時にHが出力され、その後にコンペアマッチするので、1/256 (約0.39%)の時間だけHが出力される。 return 0; }
黄色がOC0Aピン(PD6)、緑色がOC0Bピン(PD5)から出力したPWM波。OC0Bピン(PD5)のほうはコンペア値を0にしているにもかかわらずデューティが0になっていないことがわかる。