目錄
一、前言
二、實現步驟
? ? ? ? 1.STM32CUBEMX配置
? ? ? ? 2.Keil工程程序設計
三、結語
一、前言
? ? ? ? 本文通過STM32CUBEMX實現對ADC的數據采集和濾波操作,幫助各位開發者完成與模擬量輸入的采集工作。
二、實現步驟
? ? ? ? 1.STM32CUBEMX配置
? ? ? ? 以STM32F103C8T6為例,打開STM32CUBEMX,配置好系統時鐘為72MHz后,在ADC中使能IN1、IN2(數量不限,但兩個以上有額外操作)
? ? ? ? 隨后,由于我們選擇了兩個輸入口,因此我們還需要按照下圖進行配置。先將Number of conversion設置為2,隨后將Rank 2的channel設置為Channel 1(此處對應IN1)
? ? ? ? 這樣的配置可以實現同時采集兩個通道的值。
? ? ? ? 隨后使能連續轉換模式,如下圖。
? ? ? ? 按照下圖步驟配置DMA。
? ? ? ? 隨后使能中斷,配置中斷優先級。
? ? ? ? 再次來到時鐘樹配置頁,關閉錯誤提示。
? ? ? ? 修改下圖處配置,將ADC采集頻率設定為12MHz。
? ? ? ? 配置完工程的其他必要信息后,生成代碼并打開。
? ? ? ? 2.Keil工程程序設計
? ? ? ? 先定義ADC-DMA數據數組,此處定義數組大小為100,代表采集100次數據。
? ? ? ? 隨后在主函數初始化部分開啟DMA采集。
? ? ? ? 開啟后,相關數據將會被采集并存儲在ADC數組中,以上述配置為例,數組內的存儲順序是ADC[0]是IN0的值,ADC[1]是IN1的值,ADC[2]是IN0的值......一直循環,如下表所示。?
數據 | ADC[0] | ADC[1] | ADC[2] | ADC[...] | ADC[98] | ADC[99] |
采集口 | IN0 | IN1 | IN0 | ... | IN0 | IN1 |
?
? ? ? ? 對于得到的值,我們還需要進行轉換才能得到真正的電壓值。以上使用的代碼和轉換公式如下。
uint32_t ADC[100]={0};
HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ADC,100);電壓值Val=ADC[0]/4096.0 *量程
? ? ? ? 上述的情況下,相當于我們一共采集的100次的值,每個通道50次,而我們只使用第一次的值,這不符合編程規范,我們應該對其取平均值做濾波處理。濾波函數如下。
float GetValue(int start,int step,int size){int i,count=0;float value=0;for(i=start;i<size;i+=step){value+=ADC[i]/4096.0*3.3;count++;}return value/count;
}
? ? ? ? 這時,我們可以調用函數來獲取平均值了。以本文配置為例,start代表起始為0,步長為2,最大為100。
float val=GetValue(0,2,100);
? ? ? ? 隨后我們可以對值進行打印或其他操作。
三、結語
? ? ? ? 通過上述步驟,我們可以實現DMA方式采集ADC的數據,并且通過對數據進行平均值濾波的處理后得到穩定的ADC值,這種方法可以運用于搖桿、光敏等等傳感器的數據采集上,穩定性好、可靠性高。
? ? ? ? 如果對上述相關程序有疑義,歡迎評論區交流。水平有限,僅作技術分享;若有錯誤,懇請批評指正。