ADCペリフェラル / 読み取るチャンネルを切り換える

https://github.com/ti-nspire/AVR/tree/master/night_light

ADCペリフェラル自体は1個しか内蔵されていないのでマルチプレクサを使ってチャンネルを切り換える。

f:id:ti-nspire:20190617110846p:plain:h250

#include <avr/io.h>
extern "C" { 
    #include <util/delay.h>
} 

static inline void initADC(){
    ADMUX  |= (1 << REFS0);                // AVCCを基準電圧として使うことにする。
    ADCSRA |= (1 << ADPS2) | (1 << ADPS0); // ADCへ供給するクロックの分周比を決める。32分周。
    ADCSRA |= (1 << ADEN);                 // ADCを有効化する。
}

static inline uint16_t readADC(uint8_t channel){
    ADMUX = ((0xf0 & ADMUX) | channel);    // チャンネル選択の下位4ビットだけを一旦クリアしてから目的のチャンネルをセットして、
    ADCSRA |= (1 << ADSC);                 // AD変換を開始して、
    loop_until_bit_is_clear(ADCSRA, ADSC); // AD変換が終わるのを待って、
    return ADC;                            // 10ビット値を返す。
}

int main(){
    uint16_t threshold;
    uint16_t brightness;

    DDRB = 0xff; // ポートBのIOを全部OUTにする。ポートBにLEDバーを接続する。
    
    initADC();
    while(1){
        threshold  = readADC(PC3);
        brightness = readADC(PC0);

        if(brightness<threshold){PORTB = 0xff;} // しきい値よりも暗ければLEDバーを全部点けて、
        else                    {PORTB = 0x00;} // しきい値よりも暗くなければLEDバーを全部消す。
        
        _delay_ms(500);
    }
    
    return 0;
}

f:id:ti-nspire:20190617111132j:plain:w500
f:id:ti-nspire:20190617110201p:plain:w500
f:id:ti-nspire:20190617110227p:plain:w500
これでChapter 7 Analog-to-Digital Conversion I が終わって、ようやく次回から割り込みに入る。