Timer0オーバーフロー割り込み

pp.328-329

メインループでは、ポートCに入力された値をポートBに出力するという処理を繰り返す。
それと並行して、Timer0オーバーフロー割り込みの発生するたびにPD4の出力をトグルする。

SREGレジスタIビットは、割り込み発生後にハードウェアによってクリアされ(つまり他の割り込みができない状態になる)、RETIによってセットし直される(つまり他の割り込みができる状態に戻る)。
f:id:ti-nspire:20200510103107p:plain:h315

; スタックポインタの初期化マクロ
.MACRO INITSTACK
    LDI R20, HIGH(RAMEND)
    OUT SPH, R20
    LDI R20, LOW(RAMEND)
    OUT SPL, R20
.ENDMACRO

; 割り込みベクターテーブルを侵さないようにするため、マイコンのリセット後はただちに別の番地へ飛ぶことにする。
.ORG 0
    JMP MAIN

; Timer0オーバーフロー割り込みが発生すると自動的に制御は0x20番地へ飛ぶ。
; 逆にいうと、0x20番地に制御が飛んできたらその割り込み要因はTimer0オーバーフローである。
; 0x20番地に2バイト、0x21番地に2バイト、計4バイトしかメモリーが確保されていず、
; 処理したい内容が書き切れないので、さらに別の番地へ飛ぶことにする。
.ORG 0x20
    JMP T0_OV_ISR

.ORG 0x100
MAIN:
    INITSTACK

    ; PD4のIOをOUTにして、
    SBI DDRD, 4

    ; Timer0オーバーフロー割り込みを有効化して、
    LDI R20, 1 << TOIE0
    STS TIMSK0, R20

    ; グローバル割り込みを有効化して、
    SEI

    ; Timer0の初期カウント値を設定して、
    LDI R20, 50
    OUT TCNT0, R20

    ; 分周比を1に設定してカウントを開始して、
    LDI R20, 1 << CS00
    OUT TCCR0B, R20

    ; PORTC[5:0]のIOをINのまま内部プルアップして、
    LDI R20, 0b00111111
    OUT PORTC, R20

    ; PORTB[5:0]のIOをOUTにして、
    OUT DDRB, R20

HERE:
    ; PORTC[5:0]に入力された値を読み取って、それをPORTB[5:0]に出力する。
    ; を繰り返す。
    IN R20, PINC
    OUT PORTB, R20
    RJMP HERE

.ORG 0x200
T0_OV_ISR:
    ; Timer0がオーバーフローしたら、PD4の出力をトグルして、
    IN R16, PORTD
    LDI R17, 1 << 4
    EOR R16, R17
    OUT PORTD, R16

    ; Timer0の初期カウント値をセットし直す。
    LDI R16, 50
    OUT TCNT0, R16

    RETI