Timer0、Timer1の両方のオーバーフロー割り込みを同時に使う
pp.330-331
今度はTimer0、Timer1の両方のオーバーフロー割り込みを同時に使ってみる。
- メインループでは、PORTCに入力された値をPORTBから出力する。
- それと並行して、Timer0がオーバーフローするたびにPD4の出力をトグルする。
- さらにそれと並行して、Timer1がオーバーフローするたびにPD3の出力をトグルする。
; スタックポインタの初期化マクロ .MACRO INITSTACK LDI R20, HIGH(RAMEND) OUT SPH, R20 LDI R20, LOW(RAMEND) OUT SPL, R20 .ENDMACRO ; 割り込みベクターテーブルを侵さないようにするため、マイコンのリセット後はただちに別の番地へ飛ぶことにする。 .ORG 0 JMP MAIN ; Timer1オーバーフロー割り込みがかかると制御が0x1A番地に飛んでくるので、そこからさらに別の番地へ飛んで何かを実行する。 .ORG 0x1A JMP T1_OV_ISR ; Timer0オーバーフロー割り込みがかかると制御が0x20番地に飛んでくるので、そこからさらに別の番地へ飛んで何かを実行する。 .ORG 0x20 JMP T0_OV_ISR .ORG 0x100 MAIN: INITSTACK .EQU INIT0 = 50 ; Timer0の初期値 .EQU INIT1 = 0xFE00 ; Timer1の初期値 ; PD3、PD4のIOをOUTにして、 LDI R20, 0b11000 OUT DDRD, R20 ;SBI DDRD, 3 ;SBI DDRD, 4 ; PC0~5のIOをINのまま内部プルアップして、 LDI R20, 0b00111111 OUT PORTC, R20 ; PB0~5のIOをOUTにして、 OUT DDRB, R20 ; Timer0の初期値を設定して、 LDI R20, INIT0 OUT TCNT0, R20 ; Timer0をノーマルモード、分周比1に設定して、 LDI R20, 1 << CS00 OUT TCCR0B, R20 ; Timer1の初期値を設定して、 LDI R20, HIGH(INIT1) STS TCNT1H, R20 LDI R20, LOW(INIT1) STS TCNT1L, R20 ; Timer1をノーマルモード、分周比1に設定して、 LDI R20, 1 << CS10 STS TCCR1B, R20 ; Timer0オーバーフロー割り込みを有効化して、 LDI R20, 1 << TOIE0 STS TIMSK0, R20 ; Timer1オーバーフロー割り込みを有効化して、 LDI R20, 1 << TOIE1 STS TIMSK1, R20 ; グローバル割り込みを有効化して、 SEI HERE: ; PC0~5に入力された値を読み取って、それをPB0~5に出力する。 ; を繰り返す。 IN R20, PINC OUT PORTB, R20 RJMP HERE .ORG 0x200 T0_OV_ISR: ; Timer0がオーバーフローしたら、PD4の出力をトグルして、 IN R16, PORTD LDI R17, 1 << PD4 EOR R16, R17 OUT PORTD, R16 ; Timer0の初期カウント値をセットし直す。 LDI R16, INIT0 OUT TCNT0, R16 RETI .ORG 0x300 T1_OV_ISR: ; Timer1がオーバーフローしたら、PD3の出力をトグルして、 IN R16, PORTD LDI R17, 1 << PD3 EOR R16, R17 OUT PORTD, R16 ; Timer1の初期カウント値をセットし直す。 LDI R16, HIGH(INIT1) STS TCNT1H, R16 LDI R16, LOW(INIT1) STS TCNT1L, R16 RETI