タイマー0 / CTCモード / 途中でコンペア値をロードし直す / 割り込みを使う
pp.479-480
前回と同じようなことを今度は割り込みを使っておこなう。
下のプログラムは、コンペアマッチするたびに0,1,2,4,8,16,32,64の順番でコンペア値をロードし直す。
; スタックポインタの初期化マクロ .MACRO INITSTACK LDI R16, HIGH(RAMEND) OUT SPH, R16 LDI R16, LOW(RAMEND) OUT SPL, R16 .ENDMACRO .ORG 0x0 RJMP MAIN .ORG OC0Aaddr ; 0x1C RJMP TIMER0_COMPA WAVE_TABLE: .DB 0,1,2,4,8,16,32,64 MAIN: INITSTACK SBI DDRD, PD6 ; リセット直後から最初のパルスのrising edgeまでの長さを設定する。 LDI R20, 69 OUT OCR0A, R20 BEGIN: ; コンペアマッチA時にトグル。CTCモード。 LDI R20, (1 << COM0A0) | (1 << WGM01) OUT TCCR0A, R20 ; 1024分周してカウント。 LDI R20, (1 << CS02) | (1 << CS00) OUT TCCR0B, R20 ; コンペアマッチA割り込みを有効化。 LDI R20, 1 << OCIE0A STS TIMSK0, R20 SEI HERE: RJMP HERE TIMER0_COMPA: DEC R29 BRPL L1 ; BRPLはBranch if Plus。 LDI R30, (WAVE_TABLE << 1) ; R30はZL。 LDI R29, 7 L1: LPM R28, Z+ ; LPMはLoad Program Memory。 OUT OCR0A, R28 ; WAVE_TABLEの値を順番にコンペア値Aとしてロードし直す。 RETI