CTCモードのTimer0で生成した時間遅延に何サイクルを要しているか数える

1回のループに何サイクルかかっているのかを1命令ずつ数え上げてみる。クロックとの対応を見るため、PB0からクロックが出力されるようヒューズを設定した。

今、クロックはノミナル8 MHzなので1サイクルは1 ÷ 8 MHz = 0.125 us。下のプログラムは1ループに33サイクルかかるので、1ループは0.125 us * 33 = 4.125 usになるはずである。

.MACRO INITSTACK
    LDI R20, HIGH(RAMEND)
    OUT SPH, R20
    LDI R20, LOW(RAMEND)
    OUT SPL, R20
.ENDMACRO

.EQU CMP = 0x0A; コンペア値
; コメントにサイクル数を示す。カッコ内は(実行前のカウント値:実行後のカウント値)。
    INITSTACK
    SBI DDRB, 6
    LDI R17, 0b01000000
    OUT PORTB, R17
    LDI R16, 0b01000000
    LDI R20, CMP
    OUT OCR0A, R20
    LDI R20, 2
    OUT TCCR0A, R20
BEGIN:
    RCALL DELAY       ; 3
    EOR R17, R16      ; 1
    OUT PORTB, R17    ; 1
    RJMP BEGIN        ; 2
DELAY:
    LDI R20, 0        ; 1
    OUT TCNT0, R20    ; 1(00)
    LDI R20, 1        ; 1(00)
    OUT TCCR0B, R20   ; 1(00)
AGAIN:
    SBIS TIFR0, OCF0A ; 1(00:01) 1(03:04) 1(06:07) 1(09:0A, マッチ)        2(01:03, OCF0Aが立っているので次の命令をスキップ)
    RJMP AGAIN        ; 2(01:03) 2(04:06) 2(07:09) 2(0A:01, OCF0Aがセット) _(__)
    LDI R20, 0        ;                                                   1(03:04)
    OUT TCCR0B, R20   ;                                                   1(04:05, Timer0が停止)
    LDI R20, 0b10     ;                                                   1(05)
    OUT TIFR0, R20    ;                                                   1(05, OCF0Aがクリア)
    RET               ;                                                   4(05)

黄色がPB6、緑色がCLKO (PB0)。
f:id:ti-nspire:20200418070608p:plain:w400
f:id:ti-nspire:20200418070623p:plain:w400 f:id:ti-nspire:20200418070634p:plain:w400