ADコンバーター / 自動トリガリングモード
参考: 組込み開発のための実践的プログラミング, pp.125-128
自動トリガリングモードはThe AVR Microcontroller and Embedded Systems Using Assembly and C: Using Arduino Uno and Atmel Studioでは取り上げていない。フリーランニングモードのみ、ADCペリフェラル / free runningモードを試す / AD変換値をシリアル通信でPCへ送る -で試した。自動トリガリングモードを使うと、サンプリングレートが細かく制御できる。
トリガーソースは下表のように複数のなかから選べる。ここではタイマー1コンペアマッチBをトリガーソースにしてAD変換をしてみる。トリガーソースのrising edgeでAD変換が開始される。下のコードは割り込みをかけて自動的にTIFR1
レジスタのOCF1B
フラグをクリアしているが、参考文献のコードのように手動でクリアするのでもよい。
#include <avr/io.h> #include <avr/interrupt.h> void initADC(){ // 基準電圧はAVCC。 ADMUX |= (1 << REFS0); // クロックを64分周して供給、変換完了割り込み、自動トリガリングモード、ADCをオン。 ADCSRA |= 0b110 | (1 << ADIE) | (1 << ADATE) | (1 << ADEN); // タイマー1コンペアマッチBをトリガーソースに指定。 ADCSRB |= (1 << ADTS2) | (1 << ADTS0); } void initTimer1(){ // CTCモード、クロックを256分周してカウント(31.25 kHz)。 TCCR1B |= (1 << WGM12) | (1 << CS12); // コンペア値(OCR1Aに指定する)。ここではサンプリング周期を0.5秒にする。15624 = (31.25 kHz * 0.5秒) - 1 OCR1A = 15624; // タイマー1コンペアマッチBフラグのクリアを自動化するため、割り込みを有効化する。 // フラグをクリアするためだけなのでISR()は記述しない。 TIMSK1 |= (1 << OCIE1B); } ISR(ADC_vect){ // AD変換が完了したら PORTD = ADCL; // AD変換値を読み出す。 PORTB = ADCH; } int main(){ DDRB = 0xFF; DDRD = 0xFF; initADC(); initTimer1(); sei(); ADCSRA |= (1 << ADSC); // リセット直後も変換する。しなくてもよい。 while(1); return 0; }