用於單片機的幾種C語言算法

2021-12-31 麵包板社區

單片機主要作用是控制外圍的器件,並實現一定的通信和數據處理。但在某些特定場合,不可避免地要用到數學運算,儘管單片機並不擅長實現算法和進行複雜的運算。下面主要是介紹如何用單片機實現數字濾波。

在單片機進行數據採集時,會遇到數據的隨機誤差,隨機誤差是由隨機幹擾引起的,其特點是在相同條件下測量同一量時,其大小和符號會現無規則的變化而無法預測,但多次測量的結果符合統計規律。為克服隨機幹擾引起的誤差,硬體上可採用濾波技術,軟體上可採用軟體算法實現數字濾波。濾波算法往往是系統測控算法的一個重要組成部分,實時性很強。

採用數字濾波算法克服隨機幹擾的誤差具有以下優點:


1、數字濾波無需其他的硬體成本,只用一個計算過程,可靠性高,不存在阻抗匹配問題。尤其是數字濾波可以對頻率很低的信號進行濾波,這是模擬濾波器做不到的。

2、數字濾波使用軟體算法實現,多輸入通道可共用一個濾波程序,降低系統開支。

3、只要適當改變濾波器的濾波程序或運算,就能方便地改變其濾波特性,這對於濾除低頻幹擾和隨機信號會有較大的效果。

4、在單片機系統中常用的濾波算法有限幅濾波法、中值濾波法、算術平均濾波法、加權平均濾波法、滑動平均濾波等。

(1)限幅濾波算法


該運算的過程中將兩次相鄰的採樣相減,求出其增量,然後將增量的絕對值,與兩次採樣允許的最大差值A進行比較。A的大小由被測對象的具體情況而定,如果小於或等於允許的最大差值,則本次採樣有效;否則取上次採樣值作為本次數據的樣本。

算法的程序代碼如下:

#defineA //允許的最大差值

chardata; //上一次的數據

char filter()

{

chardatanew; //新數據變量

datanew=get_data(); //獲得新數據變量

if((datanew-data)>A||(data-datanew>A))

return data;

else

returndatanew;

}

說明:限幅濾波法主要用於處理變化較為緩慢的數據,如溫度、物體的位置等。使用時,關鍵要選取合適的門限制A。通常這可由經驗數據獲得,必要時可通過實驗得到。

(2)中值濾波算法


該運算的過程是對某一參數連續採樣N次(N一般為奇數),然後把N次採樣的值按從小到大排列,再取中間值作為本次採樣值,整個過程實際上是一個序列排序的過程。

算法的程序代碼如下:

#define N11 //定義獲得的數據個數

char filter()

{

charvalue_buff[N]; //定義存儲數據的數組

char count,i,j,temp;

for(count=0;count

{

value_buf[count]=get_data();

delay(); //如果採集數據比較慢,那麼就需要延時或中斷

}

for(j=0;j

{

for(value_buff[i]>value_buff[i+1]

{

temp=value_buff[i];

value_buff[i]=value_buff[i+1];

value_buff[i+1]=temp;

}

}

returnvalue_buff[(N-1)/2];

}

說明:中值濾波比較適用於去掉由偶然因素引起的波動和採樣器不穩定而引起的脈動幹擾。若被測量值變化比較慢,採用中值濾波法效果會比較好,但如果數據變化比較快,則不宜採用此方法。

(3)算術平均濾波算法


該算法的基本原理很簡單,就是連續取N次採樣值後進行算術平均。

算法的程序代碼如下:

char filter()

{

int sum=0;

for(count=0;count

{

sum+=get_data();

delay():

}

return (char)(sum/N);

}

說明:算術平均濾波算法適用於對具有隨機幹擾的信號進行濾波。這種信號的特點是有一個平均值,信號在某一數值附近上下波動。信號的平均平滑程度完全到決於N值。當N較大時,平滑度高,靈敏度低;當N較小時,平滑度低,但靈敏度高。為了方便求平均值,N一般取4、8、16、32之類的2的整數冪,以便在程序中用移位操作來代替除法。

(4)加權平均濾波算法

由於前面所說的「算術平均濾波算法」存在平滑度和靈敏度之間的矛盾。為了協調平滑度和靈敏度之間的關係,可採用加權平均濾波。它的原理是對連續N次採樣值分別乘上不同的加權係數之後再求累加,加權係數一般先小後大,以突出後面若干採樣的效果,加強系統對參數變化趨勢的認識。各個加權係數均小於1的小數,且滿足總和等於1的結束條件。這樣加權運算之後的累加和即為有效採樣值。其中加權平均數字濾波的數學模型是:

式中:D為N個採樣值的加權平均值:XN-i為第N-i次採樣值;N為採樣次數;Ci為加權係數。加權係數Ci體現了各種採樣值在平均值中所佔的比例。一般來說採樣次數越靠後,取的比例越大,這樣可增加新採樣在平均值中所佔的比重。加權平均值濾波法可突出一部分信號抵制另一部分信號,以提高採樣值變化的靈敏度。

樣例程序代碼如下:

char codejq[N]={1,2,3,4,5,6,7,8,9,10,11,12}; //code數組為加權係數表,存在程序存儲區

char codesum_jq=1+2+3+4+5+6+7+8+9+10+11+12;

char filter()

{

char count;

char value_buff[N];

int sum=0;

for(count=0;count

{

value_buff[count]=get_data();

delay();

}

for(count=0;count

sum+=value_buff[count]*jq[count];

return(char)(sum/sum_jq);

}

(5)滑動平均濾波算法


以上介紹和各種平均濾波算法有一個共同點,即每獲取一個有效採樣值必須連續進行若干次採樣,當採速度慢時,系統的實時得不到保證。這裡介紹的滑動平均濾波算法只採樣一次,將一次採樣值和過去的若干次採樣值一起求平均,得到的有效採樣值即可投入使用。如果取N個採樣值求平均,存儲區中必須開闢N個數據的暫存區。每新採集一個數據便存入暫存區中,同時去掉一個最老數據,保存這N個數據始終是最新更新的數據。採用環型隊列結構可以方便地實現這種數據存放方式。

程序代碼如下:

char value_buff[N];

char i=0;

char filter()

{

char count;

int sum=0;

value_buff[i++]=get_data();

if(i==N)

i=0;

for(count=0;count

sum=value_buff[count];

return (char)(sum/N);

}

(6)低通濾波


將普通硬體RC低通濾波器的微分方程用差分方程來表求,變可以採用軟體算法來模擬硬體濾波的功能,經推導,低通濾波算法如下:

Yn=a* Xn+(1-a) *Yn-1

式中 Xn——本次採樣值

Yn-1——上次的濾波輸出值;

,a——濾波係數,其值通常遠小於1;

Yn——本次濾波的輸出值。

由上式可以看出,本次濾波的輸出值主要取決於上次濾波的輸出值(注意不是上次的採樣值,這和加權平均濾波是有本質區別的),本次採樣值對濾波輸出的貢獻是比較小的,但多少有些修正作用,這種算法便模擬了具體有教大慣性的低通濾波器功能。濾波算法的截止頻率可用以下式計算:

fL=a/2Pit pi為圓周率3.14…

式中 a——濾波係數;

, t——採樣間隔時間;

例如:當t=0.5s(即每秒2次),a=1/32時;

fL=(1/32)/(2*3.14*0.5)=0.01Hz

當目標參數為變化很慢的物理量時,這是很有效的。另外一方面,它不能濾除高於1/2採樣頻率的幹攪信號,本例中採樣頻率為2Hz,故對1Hz以上的幹攪信號應採用其他方式濾除,

低通濾波算法程序於加權平均濾波相似,但加權係數只有兩個:a和1-a。為計算方便,a取一整數,1-a用256-a,來代替,計算結果捨去最低字節即可,因為只有兩項,a和1-a,均以立即數的形式編入程序中,不另外設表格。雖然採樣值為單元字節(8位A/D)。為保證運算精度,濾波輸出值用雙字節表示,其中一個字節整數,一字節小數,否則有可能因為每次捨去尾數而使輸出不會變化。

設Yn-1存放在30H(整數)和31H(小數)兩單元中,Yn存放在32H(整數)和33H(小數)中。

推薦閱讀:

牢記13個常用的電路基礎公式

濾波器參數還在盲調?耐心看完這篇!

在Vcc上直接並聯穩壓管會怎麼樣?

點擊下方『麵包板社區』卡片關注我們

每天學點電子技術乾貨

▲ 擊關注,後臺回復"關鍵詞",領取300 G學習資料包!

 內容合作 視頻、課程合作 | 開發板合作轉載開白 

請聯繫小助手微信:15889572951(微信同號)

點擊閱讀原文,下載《單片機外圍電路設計 (第2版) 》

相關焦點

  • 寫出高效優美的單片機C語言代碼
    下面發一些我在網上看到的技巧和自己的一些經驗來和大家分享;1、如果可以的話少用庫函數,便於不同的mcu和編譯器間的移植2、選擇合適的算法和數據結構應該熟悉算法語言,知道各種算法的優缺點,具體資料請參見相應的參考資料,有很多計算機書籍上都有介紹。
  • 單片機C語言實現求平方根算法
    C語言中要求平方根,可以在頭文件中加入#include <math.h>.然後調用sqrt(n);函數即可。但在單片機中調用此函數無疑會耗費大量資源和時間,是極不合適的。在此,總結下網上常見的四種單片機常用開方根算法:對於擁有專門的乘除法指令的單片機,可採用以下兩種方法:1、二分法對於一個非負數n,它的平方根不會小於大於(n/2+1)(謝謝@linzhi-cs提醒)。在[0, n/2+1]這個範圍內可以進行二分搜索,求出n的平方根。
  • PIC單片機C語言程序實例
    二、C語言的特點      C語言的特點可歸納如下。      1.語言簡潔      C是一種小型語言,共有32個關鍵字,9種控制語句,表示方法簡單,只需用規範的方法。就可以構造出功能很強的數據類型、語句和程序結構。如用++表示加1;一一表示減1;運算符省寫等。
  • PIC單片機C語言程序設計(4)
    b) c=b ;  ∥滿足a>b,將b 賦值給c  else c=a ;  ∥ 不滿足a>b 時, 將a 賦值給c  例2:若比較兩個整量a、b,要求其大者送x,即可用if 語句實現;讀者在閱讀一些書籍上的單片機C 語言程序時,會遇到條件語句的一種簡化形式,其格式如下:  表達式1 ?表達式2 ;表達式3  如以上if 語句的形式⑵中的例2,即可簡化為條件表達式的賦值語句;
  • 為什麼C語言是最適合單片機編程的高級語言!
    為什麼還在用C語言編程?答案是:C語言是最適合單片機編程的高級語言。 這個問題的意思應該是:現在有很多很好用的高級語言,如java,python等等,為什麼這些語言不能用來編寫單片機程序呢?那麼這個問題的答案就是:不是不能,而是不合適。
  • 單片機常用的14個C語言算法
    算法的描述:是對要解決一個問題或要完成一項任務所採取的方法和步驟的描述,包括需要什麼數據(輸入什麼數據、輸出什麼結果)、採用什麼結構、使用什麼語句以及如何安排這些語句等。通常使用自然語言、結構化流程圖、偽代碼等來描述算法。
  • 最適合單片機編程的高級語言,除了C語言,別無選擇!
    單片機為什麼還在用C語言編程?答案是:C語言是最適合單片機編程的高級語言。 這個問題的意思應該是:現在有很多很好用的高級語言,如java,python,VC等等,為什麼這些語言不能用來編寫單片機程序呢?那麼這個問題的答案就是:不能不能,而是不合適。
  • 單片機C語言編程心得
    1、.H文件介紹:在單片機C程序設計中,項目一般按功能模塊化進行結構化設計。將一個項目劃分為多個功能,每個功能的相關程序放在一個C程序文檔中,稱之為一個模塊,對應的文件名即為模塊名。一個模塊通常由兩個文檔組成,一個為頭文件*.h,對模塊中的數據結構和函數原型進行描述;另一個則為C文件*.c ,對數據實例或對象定義,以及函數算法具體實現。
  • 單片機程式語言的比較
    例如,懂得彙編語言指令就可以使用在片內ram作變量的優勢,因為片外變量需要幾條指令才能設置累加器和數據指針進行存取。同樣的,當要求使用浮點數和啟用函數時也只有具備彙編編程經驗才能避免生成龐大的、效率低的程序,對於這方面的編程,沒有彙編語言是做不到的。
  • 單片機c語言教程:C51運算符和表達式
    如果你是個DELPHI 編程愛好者或是DELPHI程式設計師,你對變量的定義也許習慣了DELPHI 的關鍵字,如 int 類型常會用關鍵字Integer來定義,在用 單片機c語言時你還想用回這個的話,你能這樣寫:本文引用地址:http://www.eepw.com.cn/article/170888.htmtypedef int integer;
  • 【愛找茬】都是C語言,單片機C語言和普通的C語言究竟有什麼差異呢?
    許多小夥伴在學完C語言後想入門單片機,但學著學著發現明明都是C語言,為什麼單片機C語言和我當初學的C語言有差異呢?今天小編就來梳理我們平時所學的C語言與單片機C語言的有什麼樣的不同。
  • C語言編程建議和技巧,同樣適用於單片機的學習
    但有時我會寫注釋,像下文一樣僅僅只是把它們用於介紹。例如:解釋全局變量的使用和類型(我總是在龐大的程序中寫注釋);作為一個不尋常或者關鍵過程的介紹;或標記出大規模計算的一節。或許除了諸如重要數據結構的聲明(對數據的注釋通常比對算法的更有幫助),這樣至關重要部分之外,需要避免對注釋的「可愛」排版和大段的注釋;基本上最好就不要寫注釋。
  • PIC單片機C語言程序設計(5)
    表4列出了加、減、乘、除、取模5種算術運算符,以及自增、自減運算符的操作說明。其中,除法運算符又分兩種情況,一是整除, 口兩個整數相除,所得商舍尾數,僅取整數部分,如5/10等於0;二是實除,即兩個實數相除,所得商也是實數,如5.0/10等於0.5。
  • 如何寫出高效優美的單片機C語言代碼?
    下面發一些我在網上看到的技巧和自己的一些經驗來和大家分享;1、如果可以的話少用庫函數,便於不同的mcu和編譯器間的移植2、選擇合適的算法和數據結構應該熟悉算法語言,知道各種算法的優缺點,具體資料請參見相應的參考資料,有很多計算機書籍上都有介紹。
  • C語言經典算法十例,附源碼
    算法是一個程序和軟體的靈魂,作為一名優秀的程式設計師,只有對一些基礎的算法有著全面的掌握,才會在設計程序和編寫代碼的過程中顯得得心應手。
  • 單片機的C語言中數組的用法
    數組在C51語言的地位舉足輕重,因此深入地了解數組是很有必要的。下面就對數組進行詳細的介紹。(1)一維數組本文引用地址:http://www.eepw.com.cn/article/201611/320327.htm一維數組是最簡單的數組,用來存放類型相同的數據。數據的存放是線性連續的。
  • 單片機常用的14個C語言算法,看過的都成了大神!
    單片機常用的14個C語言算法,看過的都成了大神! 算法(Algorithm):計算機解題的基本思想方法和步驟。
  • 基於C語言51單片機電子密碼鎖的設計與仿真
    電子密碼鎖通常使用ARM和單片機控制,單片機相對ARM實現較為簡單,功能較為完善,因此使用單片機控制較多。用單片機控制的窖碼鎖常使用彙編語言編寫程序,顯示器多數用。而本文所介紹的電子密獁鎖使用移植性及可讀性強的高級語言C語言編寫,便於修改和增減功能蚤同時採用顯示清楚數碼管,功率消耗小而且壽命長的 液晶顯示器,顯示更加直觀,使用更加方便。
  • 單片機常用的14個C語言算法,看過的據說都晉級高手了
    算法(Algorithm):計算機解題的基本思想方法和步驟。算法的描述:是對要解決一個問題或要完成一項任務所採取的方法和步驟的描述,包括需要什麼數據(輸入什麼數據、輸出什麼結果)、採用什麼結構、使用什麼語句以及如何安排這些語句等。通常使用自然語言、結構化流程圖、偽代碼等來描述算法。
  • 單片機c語言教程:C51循環語句
    在 C 語言中構成循環控制的語句有 while,do-while,for 和 goto 語句。同樣都是起到循環作用,但具體的作用和使用方法又大不一 樣。我們具體來看看。goto 語句這個語句在很多高級語言中都會有,記得小時候用 BASIC 時就很喜歡用這個語句。