今日もatmega8。SIG_OVERFLOW0でのタイマ/カウンタ割込みをやってみたよDSC00830.jpg

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個あるし