[英]STM32 ADC Reading Instability
我正在以輪詢模式讀取 5 個 ADC 通道。 對於每個通道,我得到 10 個樣本並計算平均值。 找samples數組,可見有些不穩定。 第一個讀數具有較高的值,並且它們會減少,直到最后一個樣本。 這種行為是非常重復的。 查看 output 數組 (ui32_ Raw Temp):
初讀 1855
最后閱讀 1850
原始值 output
ui32_RawTemp[0]: 1855
ui32_RawTemp[1]: 1855
ui32_RawTemp[2]: 1854
ui32_RawTemp[3]: 1852
ui32_RawTemp[4]: 1852
ui32_RawTemp[5]: 1852
ui32_RawTemp[6]: 1851
ui32_RawTemp[7]: 1851
ui32_RawTemp[8]: 1850
ui32_RawTemp[9]: 1850
對於調試,我用固定電阻器替換了連接到我的 ADC 通道的傳感器,以獲得固定的讀數。
ADC 自校准在第一個通道讀取之前執行。 每 30 秒重復一次校准和 5 次讀取。
這是原始代碼片段(針對一個頻道)。 為了更容易理解,我刪除了 ADC HAL 錯誤處理。
AVG_NUMBER 10
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
// reading TEMP1_ADC on channel 5
sConfig.Channel = ADC_CHANNEL_5;
ADC_HAL_ErrCode = HAL_ADC_ConfigChannel(&hadc1, &sConfig);
if(ADC_HAL_ErrCode != HAL_OK) {
......
}
ui32_Temp = 0;
for(ui8_AVGCounter=0; ui8_AVGCounter < AVG_NUMBER; ui8_AVGCounter++) {
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 10);
ui16_RawTemp[ui8_AVGCounter] = HAL_ADC_GetValue(&hadc1); // Read ADC register
ui32_Temp = ui32_Temp + (uint32_t)ui16_RawTemp[ui8_AVGCounter]; // Sum all read values
ui16_avgADC[0] = (uint16_t)(ui32_Temp / AVG_NUMBER); // Calculate the average
HAL_ADC_Stop(&hadc1);
}
經過一些調查,我在我的循環中添加了一個延遲,結果好多了。 現在讀數非常穩定。 但是,1ms 延遲很多!
這是經過改編的代碼片段,效果更好:
// reading TEMP1_ADC on channel 5
sConfig.Channel = ADC_CHANNEL_5;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
ADC_HAL_ErrCode = HAL_ADC_ConfigChannel(&hadc1, &sConfig);
if(ADC_HAL_ErrCode != HAL_OK) {
.....
}
ui32_Temp = 0;
for(ui8_AVGCounter=0; ui8_AVGCounter < AVG_NUMBER; ui8_AVGCounter++) {
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 10);
ui32_RawTemp[ui8_AVGCounter] = HAL_ADC_GetValue(&hadc1); // Read ADC register
HAL_ADC_Stop(&hadc1);
ui32_Temp = ui32_Temp + ui32_RawTemp[ui8_AVGCounter]; // Sum all read values
vTaskDelay(1);
}
ui16_avgADC[0] = (uint16_t)((ui32_Temp + (0.5 * AVG_NUMBER)) / AVG_NUMBER); //Round number and Calculate the average
查看新的 output 數組:
新的 output 值:
ui32_RawTemp[0]: 1855
ui32_RawTemp[1]: 1855
ui32_RawTemp[2]: 1855
ui32_RawTemp[3]: 1855
ui32_RawTemp[4]: 1855
ui32_RawTemp[5]: 1855
ui32_RawTemp[6]: 1855
ui32_RawTemp[7]: 1855
ui32_RawTemp[8]: 1856
ui32_RawTemp[9]: 1855
問題是:
對這種行為有什么解釋嗎?
我的代碼有問題嗎?
我注意到第一次閱讀是最不穩定的。 我應該在第一次 ADC 轉換之前做些什么嗎?
這是一個明顯的跡象,表明您的 ADC 輸入電路阻抗太大,內部 ADC 電容加載速度不夠快。
如果你想使用更短的采樣時間,你需要通過改變輸入電路來降低它——例如通過添加一個運算放大器(作為電壓中繼器)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.