FrontPage > マイクロコントローラ > AVRの覚書

A/D変換

ATmega328PのADC入力に可変抵抗を接続し、A/D変換した値を
LCDに表示してみる。

1. レジスタ

  • ADMUX (ADC Multiplexer Selection Register)
    bit7bit6bit5bit4bit3bit2bit1bit0
    REFS1REFS0ADLAR-MUX3MUX2MUX1MUX0
    • REFS1,REFS0
      基準電圧にAREFピン入力を使用するので"00"を設定。
    • ADLAR
      A/D変換結果を左詰しないので"0"を設定。
    • MUX[3:0]
      アナログ入力にADC5(PC5)ピンを使用するので、"0101"を設定。

  • ADCSRA (ADC Control and Status Resister A)
    bit7bit6bit5bit4bit3bit2bit1bit0
    ADENADSCADATEADIFADIEADPS2ADPS1ADPS0
    • ADEN
      AD変換を有効にするため、"1"を設定。
    • ADSC
      AD変換開始時に"1"を設定。
    • ADATE(ADC Auto Trigger Enable)
      AD変換の自動起動はしないので"0"を設定。
    • ADIF(ADC Interrupt Flag)
      AD変換完了時に"1"になる。
      割り込みを利用している場合は割り込み処理実行時にクリアされる。
      今回、割り込みは利用しないので、AD変換開始前にクリアする必要がある。
      このビットをクリアするには"1"を書き込む。
    • ADIE(ADC Interrupt Enable)
      割り込みは使用しないため"0"を設定。
    • ADPS[2:0](ADC Prescaler Select Bits)
      AD変換のクロックとしてシステムクロックを128分周するので"111"を設定。

  • ADCSRB (ADC Control and Status Resister B)
    今回は自動起動しないので、初期値のまま。

  • ADCL, ADCH (The ADC Data Resister)
    AD変換結果が格納される。(10-bit右詰め、または左詰め)
    変換結果は以下の式で表される。

    変換結果 = (入力電圧 / 基準電圧) x 1024

    CプログラムからはADCで取得できる。

  • DIDR0 (Digital Input Disable Resister 0)
    bit7bit6bit5bit4bit3bit2bit1bit0
    --ADC5DADC4DADC3DADC2DADC1DADC0D
    今回はADC5をアナログ入力に使用するので、デジタル入力を
    無効にするため"0b00100000"を設定する。

2. 回路図

マイコン周りの回路は「ATmega328Pテスト用ボード」参照。
LCDとの接続は「AVR キャラクタLCDへの表示」参照

AVR_ADC_回路図.png

3. プログラム

LCD関連のソース(lcd.h, lcd.c)は「AVR キャラクタLCDへの表示」参照

  • ヘッダファイル

    (adc.h)
    #ifndef ADC_H_INCLUDED
    #define ADC_H_INCLUDED
    
    // Voltage Reference Selections
    #define ADC_REFS_AREFF	0x00						// 00
    #define ADC_REFS_AVCC	(_BV(REFS0))				// 01
    #define ADC_REFS_IN		(_BV(REFS1) | _BV(REFS0))	// 11
    
    // Input Channel Selections
    #define ADC_MUX_ADC0	0x00					// 0000
    #define ADC_MUX_ADC1	(_BV(MUX0))				// 0001
    #define ADC_MUX_ADC2	(_BV(MUX1))				// 0010
    #define ADC_MUX_ADC3	(_BV(MUX1) | _BV(MUX0))	// 0011
    #define ADC_MUX_ADC4	(_BV(MUX2))				// 0100
    #define ADC_MUX_ADC5	(_BV(MUX2) | _BV(MUX0))	// 0101
    #define ADC_MUX_VBG		(_BV(MUX3) | _BV(MUX2) | _BV(MUX1))				// 1110
    #define ADC_MUX_GND		(_BV(MUX3) | _BV(MUX2) | _BV(MUX1) | _BV(MUX0))	// 1111
    
    // ADC Prescaler Selections(Division Factor)
    #define ADC_ADPS_2		(_BV(ADPS0))							// 001
    #define ADC_ADPS_4		(_BV(ADPS1))							// 010
    #define ADC_ADPS_8		(_BV(ADPS1) | _BV(ADPS0))				// 011
    #define ADC_ADPS_16		(_BV(ADPS2))							// 100
    #define ADC_ADPS_32		(_BV(ADPS2) | _BV(ADPS0))				// 101
    #define ADC_ADPS_64		(_BV(ADPS2) | _BV(ADPS1))				// 110
    #define ADC_ADPS_128	(_BV(ADPS2) | _BV(ADPS1) | _BV(ADPS1))	// 111
    
    
    #endif	// ADC_H_INCLUDED
    

  • メインファイル

    (ADC_test.c)
    #ifndef F_CPU
    #define F_CPU 16000000UL	// 動作周波数に16MHzを指定
    #endif
    
    #include <avr/io.h>
    #include <util/delay.h>
    #include "lcd.h"
    #include "adc.h"
    
    int main(void)
    {
    	// LCD init
    	lcd_init();
    	
    	// ADC init
    	ADMUX =  ADC_REFS_AREFF | ADC_MUX_ADC5;
    	ADCSRA = _BV(ADEN) | ADC_ADPS_128;
    	DIDR0 |= _BV(ADC5D);
    
        while(1)
        {
    		// ADCスタート
    		ADCSRA |= _BV(ADIF);
    		ADCSRA |= _BV(ADSC);
    		
    		// ADC完了待ち
            loop_until_bit_is_set(ADCSRA, ADIF);
    		
    		// ADC結果取得
    		int result = ADC;
    		
    		lcd_moveCursor(0,0);
    		lcd_printInt(result);
    		
    		_delay_ms(100);
    	}
    }
    

4. ヒューズビット設定

今回は外部クロック16MHzを分周なしで使用するので、Atmel Studioの
Device Programming画面のFuses設定より、「SUT_CKSEL」に
「EXTXOSC_8MHZ_XX_16KCK_14CK_65MS」を選択。

5.実行結果

AVR_ADC_結果.jpg





添付ファイル: fileAVR_ADC_結果.jpg 332件 [詳細] fileAVR_ADC_回路図.png 348件 [詳細]

トップ   編集 凍結解除 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2015-07-09 (木) 23:18:26 (833d)