Timer0、Timer1の両方のオーバーフロー割り込みを同時に使う

pp.330-331

今度はTimer0、Timer1の両方のオーバーフロー割り込みを同時に使ってみる。

  • メインループでは、PORTCに入力された値をPORTBから出力する。
  • それと並行して、Timer0がオーバーフローするたびにPD4の出力をトグルする。
  • さらにそれと並行して、Timer1がオーバーフローするたびにPD3の出力をトグルする。

f:id:ti-nspire:20200510162324p:plain:h300 f:id:ti-nspire:20200510162439j:plain:h300 f:id:ti-nspire:20200510162046p:plain:h300

; スタックポインタの初期化マクロ
.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

f:id:ti-nspire:20200510162751p:plain:w500