CTCモードのTimer0で時間遅延を生成する

p.288

今度は、タイマーオーバーフローではなくコンペアマッチを利用して時間遅延を生成してみる。CTCはClear Timer on Compare Match。

一定の時間が経過するたびにPB6の出力をトグルする。コードはほぼテキストのままである。クロックは内蔵の8 MHz、コンペア値を50にした結果、約9.1 usの時間遅延が生成された。

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

    ; スタックポインタを初期化して、
    INITSTACK

    ; PB6のIOをOUTにして、
    SBI DDRB, 6

    ; PB6からHを出力して、(トグルの初期値なのでLにしても同じ)
    LDI R17, 0b01000000
    OUT PORTB, R17
    
    ; PB6をトグルするためのマスクビットをセットして、
    LDI R16, 0b01000000

    ; Timer0のコンペア値Aを設定して、
    LDI R20, 50
    OUT OCR0A, R20

    ; Timer0をCTCモードにして、
    LDI R20, 2
    OUT TCCR0A, R20

BEGIN:
    ; 待って、
    RCALL DELAY

    ; PB6の出力をトグルして、
    EOR R17, R16
    OUT PORTB, R17

    ; を無限に繰り返す。
    RJMP BEGIN

DELAY:
    ; Timer0をリセットして、
    LDI R20, 0
    OUT TCNT0, R20

    ; CS00ビット(ビット0)を1 (クロックを1分周)にしてTimer0でカウントをスタートする。
    LDI R20, 1
    OUT TCCR0B, R20

AGAIN:
    ; Timer0がコンペア値Aにマッチするまでとどまって、(すなわちコンペアマッチフラグAがセットされたら次の命令をスキップして、)
    ; Skip if Bit in I/O Register is Set
    SBIS TIFR0, OCF0A
    RJMP AGAIN

    ; Timer0のコンペアマッチフラグAがセットされたらTimer0をストップして、
    LDI R20, 0
    OUT TCCR0B, R20

    ; Timer0のコンペアマッチフラグA(ビット1)をクリアして、     
    LDI R20, 0b10
    OUT TIFR0, R20

    ; 遅延函数を抜ける。
    RET

f:id:ti-nspire:20200417071140p:plain