今日もatmega8。SIG_OVERFLOW0でのタイマ/カウンタ割込みをやってみたよ
PB0のLED点滅はタイマー割り込みで行う。同時にmain()の中のループで、UARTで文字列を送信する。→ソースコード(AVR-GCC)、動画(2.1MB)
タイマ/カウンタ0は8bit。mega8には他に16bitのタイマ/カウンタ1(PWM付き)と8bitのタイマ/カウンタ2(PWM付き)があり、3つとも別のタイミングで割り込みを発生させる事ができる。
でもまだ1と2は使ってない。
タイマ0の精度として、TCCR0レジスタで分周率を設定する。
HERO’s Downloadさんより
■やり方
タイマ/カウンタ0の設定関数
/* タイマ/カウンタ0オーバーフロー割り込み設定 */
void overflow0_init(){
TCNT0 = 0; // タイマ0初期値
TCCR0 = (0<<CS02)|(0<<CS01)|(1<<CS00); // 分周率設定 前置分周無し
sbi(TIMSK,TOIE0); // タイマ/カウンタ0オーバーフロー割り込み許可
}
これをmain()から呼び出す。
int main(void){
port_init(); // PORT設定
usart_init(MYUBRR); // USART設定
overflow0_init(); // タイマ/カウンタ0設定
sei(); // 割り込み許可
for(;;){
uart_send_str(&qute;hoge\0&qute;);
}
}
sei(); を忘れずに。
んで割り込み部分
volatile unsigned int led0;
/* タイマ/カウンタ0オーバーフロー割り込み */
SIGNAL(SIG_OVERFLOW0){
led0++;
if(led0 > 1500) LED_SET(); // LED点灯
else LED_CLR(); // LED消灯
if(led0 == 3000){
led0 = 0; // カウント初期化
}
nop(1); // これ入れないと固まる
}
よくわからないけど、nop(int count); という自分で用意した関数を呼び出さないと、main()の中の処理を巻き込んで止まる。
多重割り込みとか?
一応nopの中身
/* No Operation */
void nop(int count){
int i;
for(i = 0; i < count*100; i++){
}
}
そういえばDigi-Key、mega8値上がりしてますか?mega48のが安くなってますね。mega88と同じぐらいの値段。次実装するとしたらmega88かな
PWM6個あるし