SAM4E單片機之旅——18、通過AFEC(ADC)獲取輸入的電壓
很多時候,一個電壓不僅僅需要定性(高電平或者低電平),而且要定量(了解具體電壓的數(shù)值)。這個時候就可以用到模數(shù)轉(zhuǎn)換器(ADC)了。這次的內(nèi)容是測量開發(fā)板搭載的滑動變阻器(VR1)的電壓,然后把ADC轉(zhuǎn)換的結(jié)果通過UART打印出來。同時,也簡單介紹了校準的方法。
SAM4E芯片中,ADC是由AFEC管理的。同時,AFEC可以使用一個多路復用器以選擇需要轉(zhuǎn)換的信號的通道,也可以通過平均多次ADC轉(zhuǎn)換的結(jié)果以提高轉(zhuǎn)換精確度。
一、電路圖通過順時針方向旋轉(zhuǎn)該變阻器,PB1引腳電壓將變大,其電壓變化范圍為0—3.3V。使用的AFEC為AFEC0,通道編號為5。
通過JP3可以選擇參考電壓的大小。默認情況下,參考電壓為3.3 V。
需要注意的是,而在JP3短接2、3腳時,參考電壓為3.0 V。
二、ADC電氣特性該AFEC有效的時鐘范圍為1—20 MHz,最大采樣頻率是1 MHz。同時也需記下啟動、跟蹤、設(shè)置等時間,這在使用AFEC時會用到。另外,傳送時間在芯片手冊中沒有詳細說明,只說明將TRANSFER字段設(shè)置為1。
由于需要使用較高波特率進行UART通信,所以將MCK設(shè)置為96 MHz。在此情況下,能設(shè)置的最高的AFEC時鐘頻率為16 MHz(將AFEC_MR的PRESCAL參數(shù)設(shè)置為2),即每個AFEC時鐘的周期為62.5 ns。
由此可以計算出,從關(guān)閉狀態(tài)下,完全啟動AFEC最多需要512個AFEC時鐘。在實際應(yīng)用中,這個數(shù)字可以減小。
三、AFEC初始化準備工作為將MCK設(shè)置為96 MHz,開啟UART并讓printf通過UART輸出。
PMC及GPIO設(shè)置。
AFEC工作模式。有兩個寄存器可以設(shè)置AFEC的工作模式:
1234567891011121314AFEC0->AFEC_MR =AFEC_MR_TRGEN_DIS // 關(guān)閉硬件觸發(fā)| AFEC_MR_SLEEP // 轉(zhuǎn)換完成后進入睡眠模式| AFEC_MR_PRESCAL(2) // AFEC CLK = 96M / 6 = 16 M| AFEC_MR_STARTUP_SUT512 // MAX 32 us| AFEC_MR_SETTLING_AST3 // MIN 100 ns| AFEC_MR_ANACH_ALLOWED| AFEC_MR_TRACKTIM(2) // MIN 160 ns| AFEC_MR_TRANSFER(1)| AFEC_MR_USEQ_NUM_ORDER;AFEC0->AFEC_EMR =AFEC_EMR_RES_NO_AVERAGE // 進行 12bit 采樣;設(shè)置增益參數(shù)及關(guān)閉差分模式:
12AFEC0->AFEC_CGR = AFEC_CGR_GAIN5(0);AFEC0->AFEC_DIFFR &= ~((uint32_t)1 << 5); // 不使用差分模式啟用通道:
1AFEC0->AFEC_CHER = AFEC_CHER_CH5;四、實現(xiàn)轉(zhuǎn)換指定通道的輸入
1234567891011uint16_t GetADCValue(intch){// 軟觸發(fā)以開始轉(zhuǎn)換AFEC0->AFEC_CR = AFEC_CR_START;// 等待轉(zhuǎn)換完成(通過查詢相應(yīng)的EOC位判斷轉(zhuǎn)換是否完成)while((AFEC0->AFEC_ISR & (1<輪詢滑動變阻器的電壓,并在電壓波動超過指定閥值時打印出當前電壓。
1234567891011121314151617constintmin_diff = 10; // 閥值intdiff;uint16_t adcv; // ADC轉(zhuǎn)換的結(jié)果uint16_t last_adcv = ~0;while(1){adcv = GetADCValue(5);//判斷電壓波動是否超過閥值diff = (int32_t)adcv - last_adcv;if(!(diff > (-min_diff) && diff < min_diff)){last_adcv = adcv;printf("%dnr", (int)adcv);}// 等待for(volatileinti=0; i< 0xFFFF; ++i);}五、校準在運行該示例時,發(fā)現(xiàn)當滑動變阻器VR1逆時鐘旋至極限,即PB1引腳電壓為0V時,ADC的輸出為2048左右。而當PB1電壓約為3.3 V的一半時,ADC輸出值約為4095——即達到輸出的最大值。
可以推測出存在一個約為2048的偏移誤差。這個誤差在一個ASF的示例中被提及:“AFEC內(nèi)部的偏移為0x800……”。所以我們需要對此進行校準:
1234AFEC0->AFEC_CSELR = 5;//AFEC內(nèi)部偏移為 0x800//該校準在參考電壓為3.3V 時有效AFEC0->AFEC_COCR = AFEC_COCR_AOFF(0x800);AFEC_COCR的寄存器是作用于AFEC內(nèi)部的DAC的:
同時,通過該模塊圖也可以知道增益與偏移校準作用于輸入V的方式如下:
偏移電壓:
V_offset = ( offset / 4096 ) * V_ref
ADC進行轉(zhuǎn)換的電壓:
V_adc_in = ( V – V_offset) * gain
最后,將轉(zhuǎn)換的數(shù)值加上0x800。