簡體   English   中英

STM32 ADC 讀取不穩定

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM