數(shù)字濾波是數(shù)據(jù)處理是常用、靈活、有效的方法。前面的按鍵程序已經(jīng)用到了濾波,屬于開關(guān)量濾波,這里要討論的是模擬量濾波程序,包括最常用的兩種方法,中值濾波和平均值濾波。
中值濾波的原理是,每次取最近幾個數(shù)的中間值作為輸出數(shù)據(jù),每個波形的最高和最低幾個數(shù)被濾掉,優(yōu)點是基本保留原有數(shù)據(jù),能有效抑制大幅值低頻尖峰干擾,俗稱椒鹽噪聲。
平均值濾波,就是對最近一些數(shù)求平均,是最常用最簡單的方法,對高頻低幅值隨機噪聲有效,缺點是會損失原始數(shù)據(jù)中的高頻分量,對高幅值干擾會擴大影響。下面的程序中應(yīng)用了移位平均算法,效率高,且不受求平均的數(shù)據(jù)數(shù)目大小的影響。兩種濾波方式都有一定延時。
AverageFilter.h
#ifndef __AVERAGEFILTER__
#define __AVERAGEFILTER__
extern "C" { // 兼容C,按C語言編譯,Keil5中的包含文件已經(jīng)加入了C++兼容,不用再加這一段
#pragma diag_remark 368 //消除 warning: #368-D: class " #include "stm32f10x.h" #pragma diag_default 368 // 恢復(fù)368號警告 } #define AF_MAXWINDOW 150 // 最大窗寬150 class AverageFilter { // Construction public: AverageFilter( s32 ini, u16 nNum ); // Properties public: u16 m_number; // 指定平均的個數(shù),最多150 u16 m_seek; // 游標(biāo) s32 m_summation; // 指定數(shù)組的總和 s32 m_input[AF_MAXWINDOW]; // 數(shù)據(jù)緩存 private: // Methods public: s32 filter( s32 vi ); // 濾波算法 // Overwrite public: }; #endif AverageFilter.cpp /** ****************************************************************************** * @file AverageFilter.cpp * @author Mr. Hu * @version V1.0.0 STM32F103VET6 * @date 06/06/2019 * @brief 均值濾波 ****************************************************************************** * @remarks * 采用移位平均法,大大提高效率,不受數(shù)據(jù)數(shù)量的影響 */ /* Includes ------------------------------------------------------------------*/ extern "C" { // 兼容C,按C語言編譯,Keil5中的包含文件已經(jīng)加入了C++兼容,不用再加這一段 #pragma diag_remark 368 //消除 warning: #368-D: class " #pragma diag_default 368 // 恢復(fù)368號警告 } #include "AverageFilter.h" /** * @date 06/06/2019 * @brief 均值濾波 * @param ini 初始值,避免前幾個輸出數(shù)偏差太大 * @param nNum 濾波數(shù)量,最大150,越大效果越好,但延時較多 * @retval None */ AverageFilter::AverageFilter( s32 ini, u16 nNum ) : m_number(nNum) , m_seek(0) , m_summation(0) { if( m_number > AF_MAXWINDOW ) // 控制在數(shù)組范圍內(nèi) m_number = AF_MAXWINDOW; // 初始化數(shù)組 for( int i = 0; i < AF_MAXWINDOW; i++ ) { m_input[i] = ini; } // 初始化總和 m_summation = ini * m_number; } /** * @date 06/06/2019 * @brief 濾波算法,采用移位算法,減去第一個,加上最后一個。 * @param vi 輸入數(shù)據(jù) * @retval 濾波后輸出數(shù)據(jù) */ s32 AverageFilter::filter( s32 vi ) { m_summation += ( vi - m_input[m_seek] ); // 總和中減去最早的數(shù),加上新數(shù) // 用循環(huán)方法記錄輸入數(shù)據(jù) assert_param(m_number <= AF_MAXWINDOW); m_input[m_seek] = vi; if (++m_seek >= m_number) m_seek = 0; // 返回平均值 return m_summation / m_number; } MedianFilter.h #ifndef __MEDIANFILTER__ #define __MEDIANFILTER__ extern "C" { // 兼容C,按C語言編譯,Keil5中的包含文件已經(jīng)加入了C++兼容,不用再加這一段 #pragma diag_remark 368 //消除 warning: #368-D: class " #include "stm32f10x.h" #pragma diag_default 368 // 恢復(fù)368號警告 } #define DF_MAXWINDOW 21 // 最大窗寬,奇數(shù),太大了反而不好 class MedianFilter { // Construction public: MedianFilter( s32 ini, u16 nNum ); // Properties public: u16 m_dfMedian; // 半窗寬,最大10 u16 m_seek; // 輸入數(shù)據(jù)指針 s32 m_input[DF_MAXWINDOW]; // 輸入數(shù)據(jù),循環(huán)使用,不用移位,提高效率 s32 m_sort[DF_MAXWINDOW]; // 排序數(shù)據(jù),最近輸入的數(shù)據(jù)排序,取中間值輸出 private: // Methods public: s32 filter( s32 vi ); // 濾波算法 // Overwrite public: }; #endif MedianFilter.cpp /** ****************************************************************************** * @file MedianFilter.cpp * @author Mr. Hu * @version V1.0.0 STM32F103VET6 * @date 06/05/2019 * @brief 中值濾波 ****************************************************************************** * @remarks * 中值濾波的原理是,每次取最近幾個數(shù)的中間值作為輸出數(shù)據(jù),每個波形的最高和最低 * 幾個數(shù)被濾掉,優(yōu)點是基本保留原有數(shù)據(jù),相當(dāng)于去掉幾個最高數(shù),去掉幾個最低數(shù),能有 * 效抑制大幅值低頻尖峰干擾,俗稱椒鹽噪聲。 */ /* Includes ------------------------------------------------------------------*/ extern "C" { // 兼容C,按C語言編譯,Keil5中的包含文件已經(jīng)加入了C++兼容,不用再加這一段 #pragma diag_remark 368 //消除 warning: #368-D: class " #pragma diag_default 368 // 恢復(fù)368號警告 } #include "MedianFilter.h" /** * @date 06/05/2019 * @brief 中值濾波 * @param ini 初始值,前幾個輸出數(shù)都是這個值 * @param nNum 濾波數(shù),最大10,越大效果越好,但延時較多 * @retval None */ MedianFilter::MedianFilter( s32 ini, u16 nNum ) : m_dfMedian(nNum) , m_seek(0) { if( m_dfMedian > (DF_MAXWINDOW - 1) / 2 ) // 中值限制在數(shù)組范圍內(nèi) m_dfMedian = (DF_MAXWINDOW - 1) / 2; // 初始化兩個數(shù)組 for( int i = 0; i < DF_MAXWINDOW; i++ ) { m_input[i] = ini; m_sort[i] = ini; } } /** * @date 06/05/2019 * @brief 濾波算法 * @param vi 輸入數(shù)據(jù) * @retval 濾波后輸出數(shù)據(jù) */ s32 MedianFilter::filter( s32 vi ) { u8 w1 = m_dfMedian * 2; // 窗寬-1 assert_param(w1 < DF_MAXWINDOW); // 計算將要移除的值在排序數(shù)組中的位置 u8 j = 0; for (; j <= w1 && m_input[m_seek] != m_sort[j]; j++); // 移除最早的數(shù)據(jù)并把新數(shù)據(jù)插入到適當(dāng)?shù)奈恢?p> // 如果新數(shù)據(jù)在較小半段,數(shù)據(jù)后移,否則數(shù)據(jù)前移,實現(xiàn)排序 // 只處理大于和小于情況,等于時不動 if (vi < m_input[m_seek]) { // 向前移 while (j > 0 && vi < m_sort[j-1]) { j--; m_sort[j + 1] = m_sort[j]; } } else if (vi > m_input[m_seek]) { // 向后移 while (j < w1 && vi > m_sort[j+1]) { j++; m_sort[j - 1] = m_sort[j]; } } // 加入新值 assert_param(j >= 0 && j < w); m_sort[j] = vi; // 用循環(huán)方法記錄輸入數(shù)據(jù),高效 m_input[m_seek] = vi; if (++m_seek > w1) m_seek = 0; // 返回中間值 return m_sort[m_dfMedian]; }
上一篇:STM32實戰(zhàn)六 PWM加移相正交
下一篇:STM32實戰(zhàn)八 DAC/ADC
推薦閱讀
史海拾趣
隨著市場的不斷變化和客戶需求的日益多樣化,兵字公司意識到,要想在市場中保持領(lǐng)先地位,就必須不斷進行技術(shù)創(chuàng)新。于是,公司投入大量研發(fā)資源,成功研發(fā)出了小型精密互感器。這一創(chuàng)新產(chǎn)品不僅填補了市場空白,還為公司帶來了可觀的收益。同時,兵字公司也憑借這一技術(shù)突破,進一步鞏固了在電子元器件領(lǐng)域的領(lǐng)先地位。
進入21世紀,Cree在功率器件領(lǐng)域取得了重大突破。2004年,Cree開始大范圍采用氮化鎵(GaN)材料,并成功將其應(yīng)用于大功率RF器件產(chǎn)品設(shè)計。這些GaN射頻器件主要服務(wù)于美國軍工領(lǐng)域,如“薩德”導(dǎo)彈防御系統(tǒng),其超寬的頻率覆蓋和大功率射頻功率技術(shù)無人能及。這一技術(shù)的成功應(yīng)用,不僅提升了Cree的技術(shù)實力,也為其打開了新的市場空間。
ADI的創(chuàng)業(yè)故事始于1965年,創(chuàng)始人Ray Stata與Matthew Lorber在美國馬薩諸塞州劍橋市的一座公寓地下室開始了他們的創(chuàng)業(yè)之路。最初,ADI并沒有直接涉足芯片制造,而是專注于開發(fā)運算放大器等分立器件,以提供精確放大的改良型電信號。這一決策是基于當(dāng)時新興市場的需求,展現(xiàn)了兩位創(chuàng)始人的市場敏銳度和創(chuàng)新精神。
ADI的創(chuàng)業(yè)故事始于1965年,創(chuàng)始人Ray Stata與Matthew Lorber在美國馬薩諸塞州劍橋市的一座公寓地下室開始了他們的創(chuàng)業(yè)之路。最初,ADI并沒有直接涉足芯片制造,而是專注于開發(fā)運算放大器等分立器件,以提供精確放大的改良型電信號。這一決策是基于當(dāng)時新興市場的需求,展現(xiàn)了兩位創(chuàng)始人的市場敏銳度和創(chuàng)新精神。
在技術(shù)創(chuàng)新的基礎(chǔ)上,Component General Inc公司開始積極拓展市場。公司不僅在國內(nèi)市場取得了良好的銷售業(yè)績,還積極開拓國際市場,與多家海外企業(yè)建立了合作關(guān)系。同時,公司也注重品牌建設(shè),通過參加各種行業(yè)展會、舉辦技術(shù)研討會等方式,提升公司的知名度和影響力。
BRIGHT公司的歷史可以追溯到1985年,由一群熱愛音樂的年輕人和電子工程師共同創(chuàng)立。在1987年,他們成功推出了全球第一支無線耳機,這一創(chuàng)新產(chǎn)品迅速在市場上獲得了巨大的成功。這一成就的背后,是創(chuàng)始人在一次偶然中被家里的電線絆倒后產(chǎn)生的靈感。他意識到,將有線耳機轉(zhuǎn)變?yōu)闊o線耳機將帶來巨大的便利和舒適體驗。這一創(chuàng)新不僅改變了耳機行業(yè)的格局,也為BRIGHT公司奠定了堅實的基礎(chǔ)。
請大家隨時關(guān)注,關(guān)于小車蹺蹺板分析馬上上線! 本帖最后由 paulhyde 于 2014-9-15 09:18 編輯 大家好!請大家再等待一會兒,2007年電子設(shè)計大賽F題(小車蹺蹺板)分析馬上就要整理上線了!! … 查看全部問答∨ |
本帖最后由 paulhyde 于 2014-9-15 09:26 編輯 電賽小車大家都用什么樣的電源 貌似一般的電池跑一下就不行了 不知道大家都用什么樣的 … 查看全部問答∨ |
防盜報警系統(tǒng)斷線呼救無線網(wǎng)研究與應(yīng)用 針對借助固定電話通信的防盜報警器在話線遭到破壞情況下,無法將警情送達接警中心或用戶手機的現(xiàn)象,提出一種電路簡單、通信可靠、占用信道時間短、成本低廉的話線斷線無線呼救系統(tǒng)。給出完整的硬件電路,其中包括話線斷線與摘機檢測電路,ASK調(diào)制 ...… 查看全部問答∨ |
求救!在LM3s8962使用LwIP建立TCP連接時遇到的問題 無操作系統(tǒng),通過以下程序在keil中建立TCP客戶端時,總是會在 tcp_connect()函數(shù)里出現(xiàn)問題(FaultISR),但在IAR中式可以的,為什么?lwipopt.h配置是一樣的,只不過在IAR中使用的是LwIP1.3.0而在Keil中使用的是LwIP1.3.1.?,F(xiàn) ...… 查看全部問答∨ |
求鋰電池給3.3V供電的解決方案,便宜通用的穩(wěn)壓塊 求鋰電池給3.3V供電的解決方案,電流要求不大,給單片機及少數(shù)功耗不大的外設(shè)供電,但是要求電源芯片本身功耗要低!還要便宜通用好買。 另外對于鋰電池電壓降到接近3.3V甚至3.3v以下,一般怎么處理?認為已經(jīng)欠壓(實際對鋰電池本身來說還沒有吧? ...… 查看全部問答∨ |
設(shè)計資源 培訓(xùn) 開發(fā)板 精華推薦
- 人工智能在汽車行業(yè)中的應(yīng)用
- 麥格納集成式艙內(nèi)感知系統(tǒng) 引領(lǐng)車輛安全創(chuàng)新
- 2025世界人工智能大會上的各種機器人
- 際上導(dǎo)航:高精度組合定位感知技術(shù)在智能輔助駕駛中的應(yīng)用
- 量產(chǎn)元年的人形機器人,要破局C端?
- 上半年賺304億元的寧德時代,給出固態(tài)電池量產(chǎn)時間表
- 新泗威車載后排航空座椅控制顯示器 | 申報2025第七屆金輯獎最佳技術(shù)實踐應(yīng)用獎
- L3 智駕,需要殺手級座艙
- 2025動力電池中場戰(zhàn)局,正力新能“三化策略”應(yīng)戰(zhàn)
- 智能手機共存解決方案協(xié)同合作使用共用天線
- 動手學(xué)電源第一季:DIY 小風(fēng)扇,F(xiàn)an一夏!
- 人人都愛易電源——轉(zhuǎn)發(fā)有禮!
- 恩智浦開發(fā)板交流火熱進行中
- ADI有獎直播:基準電壓源產(chǎn)品技術(shù)及應(yīng)用選擇 7月25日上午10:00-11:30 不容錯過~
- 開發(fā)板芯幣競拍,每日一款!今日競拍開發(fā)板:大黃蜂開發(fā)板
- 免費申請 | Nordic Semiconductor nPM1300-EK PMIC 評估套件
- 預(yù)約有禮:以光代電,硅光芯片了解一下~ 走進工程師網(wǎng)絡(luò)學(xué)堂直播,贏好禮
- EEWorld有獎主題征文來了~現(xiàn)金獎勵等你來拿!