2009年05月25日

2009年05月25日:ATtiny13A で PWM 出力

 お約束の LED 点滅…はサンプルそのままなので、PWM出力をやってみた。いくつかモードがあるが、Fast PWM Mode というのがわかりやすい。初期状態ではシステムクロックは 1.2 MHz なので、これを8分周してタイマークロックにする。"Set OC0A on Compare Match, Clear OC0A at TOP" モード (COM01:0 = 0b11) にして、値を OCR0A にセットする。PWM 出力は OC0A(ピン5)に出てくる。セットした値が255の時出力は完全に0、0 の時ほとんど1(256クロックに1回だけ0)になる。「負論理」になってしまうのがイマイチ使いにくいが、「完全に0」が実現できることは必要なので、やむなくこうした。

 テストプログラム。ピン3にLEDをつなぎ、ピン5の出力をテスターで測る。5秒ごとに電圧が変化するはず。

#include <avr/io.h> #include <util/delay.h> int main(void) { DDRB = 0b00010001; /* pin 3 (bit 4) and pin 5 (bit 0) for output */ TCCR0A = 0b11000000 /* PWM: set OC0A on compare match and clear at TOP */ | 0b00000011; /* Fast PWM */ TCCR0B = 0b00000000 /* Fast PWM with TOP = MAX */ | 0b00000010; /* Clock prescale by 8 */ OCR0A = 0; /* PWM duty ratio */ for (;;) { char i; for (i = 100; i >= 0; i--) _delay_ms(50); PORTB ^= 0b00010000; /* toggle the LED */ OCR0A = 128; for (i = 100; i >= 0; i--) _delay_ms(50); PORTB ^= 0b00010000; OCR0A = 255; for (i = 100; i >= 0; i--) _delay_ms(50); PORTB ^= 0b00010000; OCR0A = 128; for (i = 100; i >= 0; i--) _delay_ms(50); PORTB ^= 0b00010000; OCR0A = 0; } return 0; /* never reached */ }

 Makefile も少し手直しが必要。-p $(DEVICE) をそのまま使うと、-p attiny13a となるが、これはエラーになってしまう。

DEVICE = attiny13a CLOCK = 1200000 PROGRAMMER = -c avrisp -b 19200 -P /dev/tty.usbserial-A7006Uq3 -p t13 OBJECTS = main.o ... AVRDUDE = avrdude $(PROGRAMMER) # -p $(DEVICE) を削り、PROGRAMMER の行で指定

Posted at 2009年05月25日 01:45:57
email.png