PWM / タイマー1を使ってOC1Aピン(PB1)、OC1Bピン(PB2)からPWM波を出力する -
PWM / タイマー2を使ってOC2Aピン(PB3)、OC2Bピン(PD3)からPWM波を出力する -
PWM / タイマー0を使ってOC0Aピン(PD6)、OC0Bピン(PD5)からPWM波を出力する -ではタイマーをFast PWMモードにしてPWMを実現したが、この方法では、決まっている6端子からしかPWM波が出力できない。
ここでは割り込みを利用してどのGPIO端子からもPWM波が出力できるようにしてみる。
// LEDをぼわーんと光らせる #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> volatile uint8_t duty; ISR(TIMER0_OVF_vect){ // タイマー0がオーバーフローしたら、 PORTB |= (1 << PB5); // PB5からHを出力して、 OCR0A = duty; // コンペア値を更新する。 } ISR(TIMER0_COMPA_vect){ // タイマー0がコンペア値Aにマッチしたら、 PORTB &= ~(1 << PB5); // PB5からLを出力する。 } void initTimer0(){ TCCR0B |= (1 <<CS01) | (1 << CS00); // タイマー0のクロック源の分周比を設定する。ここでは64分周にした。 TIMSK0 |= (1 << OCIE0A) | (1 << TOIE0); // コンペア値Aマッチ時およびオーバーフロー時に割り込む。 sei(); } int main(){ DDRB |= (1 << PB5); initTimer0(); uint8_t incre = 1; while(1){ duty += incre; if(duty <= 0 || 255 <= duty){incre = -incre;}; _delay_ms(5); } return 0; }
これでChapter 10: Pulse-Width Modulationがだいたい終わり。