前言:本文為手把手教學(xué)ADC采樣及各式濾波算法的教程,本教程的MCU采用STM32F103ZET6。以HAL庫(kù)的ADC采樣函數(shù)為基礎(chǔ)進(jìn)行教學(xué),通過(guò)各式常見(jiàn)濾波的實(shí)驗(yàn)結(jié)果進(jìn)行分析對(duì)比,搭配VOFA+工具直觀的展示濾波效果。
實(shí)驗(yàn)效果圖:
一、ADC采樣
1.1 ADC簡(jiǎn)介
單片機(jī)是數(shù)字芯片,只認(rèn)識(shí)由0和1組成的邏輯序列。但實(shí)際情況下,生活中還有許多非0和1的模擬物理量存在,例如溫度,濕度等。這時(shí)候往往需要使用到AD轉(zhuǎn)換,AD轉(zhuǎn)換的英文就是Analog(模擬) to Digital(數(shù)字) ,由模擬量轉(zhuǎn)化為數(shù)字量;同理DA,則為Digital to Analog,數(shù)字量轉(zhuǎn)化為模擬量。
ADC,Analog to Digital Converter 的縮寫(xiě),中文名稱(chēng)模數(shù)轉(zhuǎn)換器。它可以將外部的模擬信號(hào)轉(zhuǎn)化成數(shù)字信號(hào)。使用它去讀取IO口上的數(shù)值將不再是簡(jiǎn)單的0或1,而是連續(xù)可變的數(shù)值。ADC采樣就是把隨時(shí)間連續(xù)變化的模擬量轉(zhuǎn)換為時(shí)間離散的模擬量。
ADC幾個(gè)比較重要的參數(shù):
(1)測(cè)量范圍:測(cè)量范圍對(duì)于 ADC 來(lái)說(shuō)就好比尺子的量程,ADC 測(cè)量范圍決定了你外接的設(shè)備其信號(hào)輸出電壓范圍,不能超過(guò) ADC 的測(cè)量范圍(比如,STM32系列的 ADC 正常就不能超過(guò)3.3V)。
(2)分辨率:假如 ADC 的測(cè)量范圍為 0-5V,分辨率設(shè)置為12位,那么我們能測(cè)出來(lái)的最小電壓就是 5V除以 2 的 12 次方,也就是 5/4096=0.00122V。很明顯,分辨率越高,采集到的信號(hào)越精確,所以分辨率是衡量 ADC 的一個(gè)重要指標(biāo)。
(3)采樣時(shí)間:當(dāng) ADC 在某時(shí)刻采集外部電壓信號(hào)的時(shí)候,此時(shí)外部的信號(hào)應(yīng)該保持不變,但實(shí)際上外部的信號(hào)是不停變化的。所以在 ADC 內(nèi)部有一個(gè)保持電路,保持某一時(shí)刻的外部信號(hào),這樣 ADC 就可以穩(wěn)定采集了,保持這個(gè)信號(hào)的時(shí)間就是采樣時(shí)間。
(4)采樣率:也就是在一秒的時(shí)間內(nèi)采集多少次。很明顯,采樣率越高越好,當(dāng)采樣率不夠的時(shí)候可能會(huì)丟失部分信息,所以 ADC 采樣率是衡量 ADC 性能的另一個(gè)重要指標(biāo)(詳細(xì)參考信號(hào)處理方向書(shū)籍)
1.2 STM32的ADC
STM32 擁有 1~3 個(gè) ADC(STM32F101/102 系列只有 1 個(gè) ADC,STM32F103系列則有3個(gè)ADC和1個(gè)DAC),這些 ADC 可以獨(dú)立使用,也可以使用雙重模式(提高采樣率)。STM32 的 ADC 是 12 位逐次逼近型的模擬數(shù)字轉(zhuǎn)換器。它有 18 個(gè)通道,可測(cè)量 16 個(gè)外部和 2 個(gè)內(nèi)部信號(hào)源。各通道的 A/D 轉(zhuǎn)換可以單次、連續(xù)、掃描或間斷模式執(zhí)行。ADC 的結(jié)果可以左對(duì)齊或右對(duì)齊方式存儲(chǔ)在 16 位數(shù)據(jù)寄存器中。
特別說(shuō)明:
ADC 是12位逐次逼近型模數(shù)轉(zhuǎn)換器,
輸出數(shù)值范圍是 0 ~ 2^12 -1(0 ~ 4095),滿(mǎn)量程是 3.3V ,
分辨率就是最低有效位(LSB)的對(duì)應(yīng)輸入電壓值。
分辨率 =3300/4095 ≈ 0.806mV。
STM32F10X 系列將 ADC 的轉(zhuǎn)換分為 2 個(gè)通道組:規(guī)則通道組和注入通道組。規(guī)則通道相當(dāng)于正常運(yùn)行的程序,而注入通道呢,就相當(dāng)于中斷打斷式通道選擇。在程序正常執(zhí)行的時(shí)候,中斷是可以打斷程序執(zhí)行的。同這個(gè)類(lèi)似,注入通道的轉(zhuǎn)換可以打斷規(guī)則通道的轉(zhuǎn)換, 在注入通道被轉(zhuǎn)換完成之后,規(guī)則通道才得以繼續(xù)轉(zhuǎn)換。
二、VOFA+
2.1 VOFA+簡(jiǎn)介
VOFA+是一款直觀、靈活、強(qiáng)大的插件驅(qū)動(dòng)高自由度的上位機(jī),在與電氣打交道的領(lǐng)域里,如自動(dòng)化、嵌入式、物聯(lián)網(wǎng)、機(jī)器人等,都能看到VOFA+的身影。VOFA+的名字來(lái)源于:Volt/伏特、Ohm/歐姆、Fala/法拉、Ampere/安培,是電氣領(lǐng)域的基礎(chǔ)單位,與他們的發(fā)明者——4位電子物理學(xué)領(lǐng)域的科學(xué)巨人,分別同名。他們的首字母共同構(gòu)成了VOFA+的名字。
VOFA+特點(diǎn)概覽:
平臺(tái)支持:Windows、Linux、MacOS;
接口支持:串口(超高波特率,穩(wěn)定支持)、網(wǎng)口(TCP客戶(hù)端/服務(wù)端,UDP);
協(xié)議支持:協(xié)議為插件,已開(kāi)源,人人可編寫(xiě)。目前已支持CSV風(fēng)格的字符串協(xié)議,和十六進(jìn)制浮點(diǎn)數(shù)組形式的字節(jié)流協(xié)議;
控件支持:控件為插件,已開(kāi)源,人人可編寫(xiě)。目前已支持波形圖、按鈕、狀態(tài)燈、圖片、滑動(dòng)條、3D立方控件(可更換模型)等;
數(shù)據(jù)維度自由化:2維度與3維,一個(gè)也不能拉下;
自主研發(fā)的波形控件:支持每通道百萬(wàn)采樣點(diǎn)的繪制,性能強(qiáng)勁;
自主研發(fā)的波形控件:無(wú)縫嵌入了實(shí)時(shí)直方統(tǒng)計(jì)和點(diǎn)數(shù)可設(shè)置的傅里葉變換,可以使用VOFA+進(jìn)行數(shù)據(jù)分析。
2.2 VOFA+使用方法
VOFA+的數(shù)據(jù)協(xié)議引擎有3種:FireWater,JustFloat,RawData。每種數(shù)據(jù)協(xié)議引擎都有自己特殊的使用效果,讀者朋友可以根據(jù)自己的實(shí)際需要去選擇使用。作者這里主要給大家演示一下FireWater協(xié)議下的VOFA+使用效果和方法。
FireWater協(xié)議是CSV風(fēng)格的字符串流,直觀簡(jiǎn)潔,編程像printf簡(jiǎn)單。但由于字符串解析消耗更多的運(yùn)算資源(無(wú)論在上位機(jī)還是下位機(jī)),建議僅在通道數(shù)量不多、發(fā)送頻率不高的時(shí)候使用。
將鼠標(biāo)放到FireWater協(xié)議上,可以很貼心的得到使用格式幫助。如上圖所示,我們使用printf("simples:%f, %f ", sin(t1), sin(t2)")函數(shù)進(jìn)行打印測(cè)試。
#include "math.h" #include "stdio.h" .... int main(void) { /* USER CODE BEGIN 1 */ float t1 = 0; float t2 = 0; /* USER CODE END 1 */ ....... while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ t1 += 0.1; t2 += 0.5; printf("simples:%f, %f ", sin(t1), sin(t2)); HAL_Delay(100); } /* USER CODE END 3 */ }
1、選擇串口通訊、端口號(hào)、波特率等參數(shù)設(shè)置;
2、去控件中選擇波形圖,拉入tab中,右鍵選擇Y軸將2個(gè)輸入I0與I1都選中,之后開(kāi)啟串口連接;
3、運(yùn)行上位機(jī),使用波形圖控件讀取下位機(jī)參數(shù);
三、濾波算法與效果
受限于MCU自身的ADC外設(shè)缺陷,其精度和穩(wěn)定性通常較差,很多場(chǎng)景下需要采取濾波補(bǔ)償。
濾波的作用就是減少噪聲與干擾對(duì)數(shù)據(jù)測(cè)量的影響。
3.1、不添加濾波算法采樣
直接采集3.3V的電壓:
VOFA+讀取到的數(shù)據(jù):
上圖借助VOFA+上位機(jī)可以清楚看出未使用濾波的ADC采樣波動(dòng)還是比較明顯的,但是作者主觀干啥F1系列的ADC確實(shí)好像比F4系列的ADC穩(wěn)定些。(之所以不是4096可能是因?yàn)?a target="_blank">電源未達(dá)到3.3v)
四、濾波算法
4.1、一階互補(bǔ)濾波
方法:取a=0~1,本次濾波結(jié)果=(1-a)本次采樣值+a上次濾波結(jié)果
優(yōu)點(diǎn):對(duì)周期性干擾具有良好的抑制作用適用于波動(dòng)頻率較高的場(chǎng)合
缺點(diǎn):相位滯后,靈敏度低滯后程度取決于a值大小不能消除濾波頻率高于采樣頻率的1/2的干擾信號(hào)
代碼如下:
//一階互補(bǔ)濾波 int firstOrderFilter(int newValue, int oldValue, float a) { return a * newValue + (1-a) * oldValue; } ADC_value=HAL_ADC_GetValue(&hadc1);//獲取ADC1的數(shù)值 //主函數(shù) while(1){ HAL_ADC_Start(&hadc1); //開(kāi)啟ADC1,放置在while循環(huán)中 Filtering_Value = firstOrderFilter(HAL_ADC_GetValue(&hadc1),ADC_value,0.3); //濾波算法 HAL_Delay(10); //延遲函數(shù),防止采樣失效 printf("ADC_value:%d ", ADC_value); }
VOFA+軟件的效果圖:
結(jié)論:
一階互補(bǔ)濾波的局限性還是很大的,效果非常一般。
4.2、中位值濾波
方法:連續(xù)采樣N次(N取奇數(shù))把N次采樣值按大小排列取中間值為本次有效值
優(yōu)點(diǎn):能有效克服因偶然因素引起的波動(dòng)干擾;對(duì)溫度、液位等變化緩慢的被測(cè)參數(shù)有良好的濾波效果
缺點(diǎn):對(duì)流量,速度等快速變化的參數(shù)不宜
代碼如下:
//中值濾波算法 int middleValueFilter(int N) { int value_buf[N]; int i,j,k,temp; for( i = 0; i < N; ++i) { value_buf[i] = HAL_ADC_GetValue(&hadc1); } for(j?=?0?;?j? value_buf[k+1]) { temp = value_buf[k]; value_buf[k] = value_buf[k+1]; value_buf[k+1] = temp; } } } return value_buf[(N-1)/2]; }
VOFA+軟件的效果圖:
結(jié)論如下:
中值濾波對(duì)消除異常值和平穩(wěn)化AD采樣都具有十分有效的結(jié)果。
4.3、算術(shù)平均濾波
方法:連續(xù)取N個(gè)采樣值進(jìn)行算術(shù)平均運(yùn)算;
N值較大時(shí):信號(hào)平滑度較高,但靈敏度較低
N值較小時(shí):信號(hào)平滑度較低,但靈敏度較高
N值的選?。阂话懔髁?,N=12;壓力:N=4
優(yōu)點(diǎn):試用于對(duì)一般具有隨機(jī)干擾的信號(hào)進(jìn)行濾波。這種信號(hào)的特點(diǎn)是有一個(gè)平均值,信號(hào)在某一數(shù)值范圍附近上下波動(dòng)。
缺點(diǎn):測(cè)量速度較慢或要求數(shù)據(jù)計(jì)算較快的實(shí)時(shí)控制不適用。
代碼:
//算術(shù)平均值濾波 int averageFilter(int N) { int sum = 0; short i; for(i = 0; i < N; ++i) { sum += HAL_ADC_GetValue(&hadc1); } return sum/N; }
VOFA+軟件的效果圖:
結(jié)論:
算術(shù)平均濾波表現(xiàn)出了一定的平穩(wěn)性,同時(shí)具有波動(dòng)的伴隨性(合理選擇N值可能達(dá)到很好的效果)。
4.4、滑動(dòng)平均濾波
方法:把連續(xù)取N個(gè)采樣值看成一個(gè)隊(duì)列,隊(duì)列的長(zhǎng)度固定為N。每次采樣到一個(gè)新數(shù)據(jù)放入隊(duì)尾,并扔掉原來(lái)隊(duì)首的一次數(shù)據(jù)(先進(jìn)先出原則)。把隊(duì)列中的N個(gè)數(shù)據(jù)進(jìn)行算術(shù)平均運(yùn)算,就可獲得新的濾波結(jié)果。
N值的選取:流量,N=12;壓力:N=4;液面,N=4~12;溫度,N=1~4
優(yōu)點(diǎn):對(duì)周期性干擾有良好的抑制作用,平滑度高;試用于高頻振蕩的系統(tǒng)
缺點(diǎn):靈敏度低;對(duì)偶然出現(xiàn)的脈沖性干擾的抑制作用較差,不適于脈沖干擾較嚴(yán)重的場(chǎng)合
比較浪費(fèi)RAM(改進(jìn)方法,減去的不是隊(duì)首的值,而是上一次得到的平均值)
代碼:
//平滑均值濾波 #define N 10 int value_buf[N]; int sum=0; int curNum=0; intmoveAverageFilter() { if(curNum < N) { value_buf[curNum] = HAL_ADC_GetValue(&hadc1); sum += value_buf[curNum]; curNum++; return sum/curNum; } else { sum -= sum/N; sum += HAL_ADC_GetValue(&hadc1); return sum/N; } }
VOFA+軟件的效果圖:
結(jié)論:
平滑均值濾波相較于普通的算術(shù)平均濾波,突出一個(gè)平滑特性。
可以從上述VOFA+的波形圖看出,平滑濾波可以有效抵消AD采樣的刺噪并穩(wěn)定化采集(據(jù)作者同門(mén)實(shí)戰(zhàn)反應(yīng)平滑濾波的效果還是非常好的,尤其在控制方面)。
4.5、限幅平均濾波
方法:相當(dāng)于“限幅濾波法”+“遞推平均濾波法”
每次采樣到的新數(shù)據(jù)先進(jìn)行限幅處理再送入隊(duì)列進(jìn)行遞推平均濾波處理
優(yōu)點(diǎn):對(duì)于偶然出現(xiàn)的脈沖性干擾,可消除有其引起的采樣值偏差。
缺點(diǎn):比較浪費(fèi)RAM
代碼如下:
//限幅平均濾波 #define A 50 //限制幅度閾值 #define M 12 int data[M]; int First_flag=0; intLAverageFilter() { int i; int temp,sum,flag=0; data[0] = HAL_ADC_GetValue(&hadc1); for(i=1;iA || ((data[i-1]-temp)>A)) { i--; flag++; } else { data[i]=temp; } } for(i=0;i
VOFA+軟件的效果圖:
結(jié)論:
限幅平均濾波類(lèi)似于縫合怪,但是效果是非常顯著的,它有效的解決了實(shí)際場(chǎng)景下突變?cè)肼晫?duì)AD采樣的影響,但是消耗內(nèi)存。
4.6、卡爾曼濾波
核心思想:根據(jù)當(dāng)前的儀器"測(cè)量值" 和上一刻的 “預(yù)測(cè)量” 和 “誤差”,計(jì)算得到當(dāng)前的最優(yōu)量,再預(yù)測(cè)下一刻的量。里面比較突出的是觀點(diǎn)是:把誤差納入計(jì)算,而且分為預(yù)測(cè)誤差和測(cè)量誤差兩種,通稱(chēng)為噪聲。還有一個(gè)非常大的特點(diǎn)是:誤差獨(dú)立存在,始終不受測(cè)量數(shù)據(jù)的影響。
優(yōu)點(diǎn):巧妙的融合了觀測(cè)數(shù)據(jù)與估計(jì)數(shù)據(jù),對(duì)誤差進(jìn)行閉環(huán)管理,將誤差限定在一定范圍。適用性范圍很廣,時(shí)效性和效果都很優(yōu)秀。
缺點(diǎn):需要調(diào)參,參數(shù)的大小對(duì)濾波的效果影響較大。
代碼如下:
//卡爾曼濾波 int KalmanFilter(int inData) { static float prevData = 0; //先前數(shù)值 static float p = 10, q = 0.001, r = 0.001, kGain = 0; // q控制誤差 r控制響應(yīng)速度 p = p + q; kGain = p / ( p + r ); //計(jì)算卡爾曼增益 inData = prevData + ( kGain * ( inData - prevData ) ); //計(jì)算本次濾波估計(jì)值 p = ( 1 - kGain ) * p; //更新測(cè)量方差 prevData = inData; return inData; //返回濾波值 }
VOFA+軟件的效果圖:
結(jié)論:
VOFA+顯示的波形圖開(kāi)源看出卡爾曼濾波有一定的去噪穩(wěn)定特性的,雖然效果不是特別優(yōu)秀。
卡爾曼濾波的普適性很強(qiáng),尤其在控制與多傳感器融合方向,只要參數(shù)調(diào)整的好,效果出奇優(yōu)秀。
五、實(shí)驗(yàn)總結(jié)
ADC作為嵌入式開(kāi)發(fā)過(guò)程中必須掌握的外設(shè),往往項(xiàng)目中是需要設(shè)置濾波器的。RC硬件濾波效果一般的話(huà),可以用軟件來(lái)湊。同時(shí)濾波算法各式各樣,原理也各不相同,希望讀者朋友在實(shí)際的工程項(xiàng)目中,不要盲目的追求各種牛逼的濾波算法,其實(shí)適合該工程的濾波就是好濾波。
來(lái)源:https://blog.csdn.net/black_sneak/article/details/129629485
-
單片機(jī)
+關(guān)注
關(guān)注
6034文章
44543瀏覽量
634156 -
adc
+關(guān)注
關(guān)注
98文章
6481瀏覽量
544330 -
STM32
+關(guān)注
關(guān)注
2269文章
10883瀏覽量
355456 -
模數(shù)轉(zhuǎn)換器
+關(guān)注
關(guān)注
26文章
3173瀏覽量
126784 -
濾波算法
+關(guān)注
關(guān)注
2文章
88瀏覽量
13718
原文標(biāo)題:STM32的ADC采樣及各式濾波實(shí)現(xiàn)(HAL庫(kù),含VOFA+教程)
文章出處:【微信號(hào):mcu168,微信公眾號(hào):硬件攻城獅】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論