ADコンバーター / 変換が完了したら割り込む

pp.436-438
今度は変換完了時に割り込む。0 v→基準電圧→0 v→基準電圧→... の順にごくゆっくり変化する電圧をAD変換してみる。

f:id:ti-nspire:20200629134616p:plain:h315

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

; 割り込みベクタテーブルを侵さないようにするためリセット後はすぐに別の番地へ飛ぶ。
.ORG 0x00 
    RJMP MAIN

; AD変換が完了すると制御が0x2A番地へ飛んでくるのでそこからさらに割り込みハンドラーへ飛ぶ。
.ORG ADCCaddr ; 0x002A
    RJMP ADC_INT_HANDLER

MAIN:
    INITSTACK

    ; 変換結果の上位バイトをポートBに、下位バイトをポートCに出力したいので、両ポートのIOを全部OUTにする。
    LDI R16, 0xFF
    OUT DDRB, R16
    OUT DDRD, R16

    ; 基準電圧にAVCCを使う。
    LDI R16, (1 << REFS0)
    STS ADMUX, R16

    ; CPUクロックを128分周してADCへ供給する。ADCペリフェラルをイネーブルにする。変換を開始する。変換完了割り込みを許可する。
    LDI R16, 0b111 | (1 << ADEN) | (1 << ADSC) | (1 << ADIE)
    STS ADCSRA, R16

    SEI

WAIT_HERE:
    RJMP WAIT_HERE

ADC_INT_HANDLER:
    ; 下位8ビットを先に読み出す。
    LDS R16, ADCL
    OUT PORTD, R16

    ; 上位2ビットを読み出す。
    LDS R16, ADCH
    OUT PORTB, R16

    ; 変換開始ビットだけをセットし直す。
    LDS R16, ADCSRA
    ORI R16, (1 << ADSC)
    STS ADCSRA, R16

    RETI