• <tbody id="wslfv"><pre id="wslfv"></pre></tbody>
    <span id="wslfv"></span>
    <tbody id="wslfv"><pre id="wslfv"></pre></tbody>
    <th id="wslfv"><track id="wslfv"><rt id="wslfv"></rt></track></th>

    <li id="wslfv"><acronym id="wslfv"></acronym></li>
    更多課程 選擇中心

    嵌入式培訓
    達內IT學院

    400-111-8989

    七個C語言算法+單片機常用算法(詳解)

    • 發布:嵌入式培訓
    • 來源:嵌入式資訊
    • 時間:2020-08-10 15:32

    算法的描述:是對要解決一個問題或要完成一項任務所采取的方法和步驟的描述,包括需要什么數據(輸入什么數據、輸出什么結果)、采用什么結構、使用什么語句以及如何安排這些語句等。通常使用自然語言、結構化流程圖、偽代碼等來描述算法。

    1、限幅濾波法

    對于隨機干擾 , 限幅濾波是一種有效的方法;

    基本方法:比較相鄰n 和 n - 1時刻的兩個采樣值y(n)和 y(n – 1),根據經驗確定兩次采樣允許的最大偏差。如果兩次采樣值的差值超過最大偏差范圍 ,認為發生可隨機干擾 ,并認為后一次采樣值y(n)為非法值 ,應予刪除 ,刪除y(n)后 ,可用y(n – 1) 代替y(n);若未超過所允許的最大偏差范圍 ,則認為本次采樣值有效。

    下面是限幅濾波程序:( A 值可根據實際情況調整,value 為有效值 ,new_value 為當前采樣值濾波程序返回有效的實際值 )

    #define A 10

    char value;

    char filter()

    { char new_value;

    new_value = get_ad();

    if ( ( new_value - value > A ) || ( value - new_value > A )) return value;

    return new_value;

    }

    2、中位值濾波法

    中位值濾波法能有效克服偶然因素引起的波動或采樣不穩定引起的誤碼等脈沖干擾;

    對溫度 液位等緩慢變化的被測參數用此法能收到良好的濾波效果 ,但是對于流量壓力等快速變化的參數一般不宜采用中位值濾波法;

    基本方法:對某一被測參數連續采樣 n次(一般 n 取奇數) ,然后再把采樣值按大小排列 ,取中間值為本次采樣值。

    下面是中位值濾波程序:

    #define N 11

    char filter()

    { char value_buf[N], count,i,j,temp;

    for ( count=0;count

    { value_buf[count] = get_ad(); delay(); }

    for (j=0;j

    { for (i=0;i

    { if ( value_buf>value_buf[i+1] )

    {temp = value_buf; value_buf = value_buf[i+1]; value_buf[i+1] = temp; }

    }

    }

    return value_buf[(N-1)/2];

    }

    3、算術平均濾波法

    算術平均濾波法適用于對一般的具有隨機干擾的信號進行濾波。這種信號的特點是信號本身在某一數值范圍附近上下波動 ,如測量流量、 液位;

    基本方法:按輸入的N 個采樣數據 ,尋找這樣一個 Y ,使得 Y 與各個采樣值之間的偏差的平方和最小。

    編寫算術平均濾波法程序時嚴格注意:

    一.為了加快數據測量的速度 ,可采用先測量數據 存放在存儲器中 ,測完 N 點后 ,再對 N 個數據進行平均值計算;

    二.選取適當的數據格式 ,也就是說采用定點數還是采用浮點數。其程序如下所示:

    #define N 12

    char filter()

    {int sum = 0,count;

    for ( count=0;count

    { sum+=get_ad(); delay();}

    return (char)(sum/N);

    }

    4、遞推平均濾波法

    基本方法:采用隊列作為測量數據存儲器 , 設隊列的長度為 N ,每進行一次測量 ,把測量結果放于隊尾 ,而扔掉原來隊首的一個數據 ,這樣在隊列中始終就有 N 個 “最新” 的數據。當計算平均值時 ,只要把隊列中的 N 個數據進行算數平均 ,就可得到新的算數平均值。這樣每進行一次測量 ,就可得到一個新的算術平均值。

    #define N 12

    char value_buf[N],i=0;

    char filter()

    { char count; int sum=0;

    value_buf[i++] = get_ad();

    if ( i == N ) i = 0;

    for ( count=0;count

    sum = value_buf[count];

    return (char)(sum/N);

    }

    5、一階滯后濾波法

    優點:對周期性干擾具有良好的抑制作用,適用于波動頻率較高的場合;

    缺點:相位滯后,靈敏度低.滯后程度取決于a值大小.不能消除濾波頻率高于采樣頻率的1/2的干擾信號。程序如下:

    #define a 50

    char value;

    char filter()

    { char new_value;

    new_value = get_ad();

    return (100-a)*value + a*new_value;

    }

    6、PID控制算法

    在過程控制中,按偏差的比例(P)、積分(I)和微分(D)進行控制的PID控制器(亦稱PID調節器)是應用最為廣泛的一種自動控制器;

    對于過程控制的典型對象──“一階滯后+純滯后”與“二階滯后+純滯后”的控制對象,PID控制器是一種最優控制;

    PID調節規律是連續系統動態品質校正的一種有效方法,它的參數整定方式簡便,結構改變靈活(PI、PD、…)。

    一 模擬PID調節器

    PID調節器各校正環節的作用:

    比例環節:即時成比例地反應控制系統的偏差信號e(t),偏差一旦產生,調節器立即產生控制作用以減小偏差;

    積分環節:主要用于消除靜差,提高系統的無差度。積分時間常數TI越大,積分作用越弱,反之則越強;

    微分環節:能反應偏差信號的變化趨勢(變化速率),并能在偏差信號的值變得太大之前,在系統中引入一個有效的早期修正信號,從而加快系統的動作速度,減小調節時間。

    PID調節器是一種線性調節器,它將給定值r(t)與實際輸出值c(t)的偏差的比例(P)、積分(I)、微分(D)通過線性組合構成控制量,對控制對象進行控制。

    程序片段如下:

    #include

    #include

    typedef struct PID {

    double SetPoint; // 設定目標Desired value

    double Proportion; // 比例常數Proportional Const

    double Integral; // 積分常數Integral Const

    double Derivative; // 微分常數Derivative Const

    double LastError; // Error[-1]

    double PrevError; // Error[-2]

    double SumError; // Sums of Errors

    } PID;

    主程序:

    double sensor (void)

    {

    return 100.0; }

    void actuator(double rDelta)

    {}

    void main(void)

    {

    PID sPID;

    double rOut;

    double rIn;

    PIDInit ( &sPID );

    sPID.Proportion = 0.5;

    sPID.Derivative = 0.0;

    sPID.SetPoint = 100.0;

    for (;;) {

    rIn = sensor ();

    rOut = PIDCalc ( &sPID,rIn );

    actuator ( rOut );

    }

    }

    7、開根號算法

    單片機開平方的快速算法

    因為工作的需要,要在單片機上實現開根號的操作。目前開平方的方法大部分是用牛頓迭代法。我在查了一些資料以后找到了一個比牛頓迭代法更加快速的方法。不敢獨享,介紹給大家,希望會有些幫助。

    1.原理

    因為排版的原因,用pow(X,Y)表示X的Y次冪,用B[0],B[1],...,B[m-1]表示一個序列,其中[x]為下標。

    假設:

    B[x],b[x]都是二進制序列,取值0或1。

    M = B[m-1]*pow(2,m-1) + B[m-2]*pow(2,m-2) + ... + B[1]*pow(2,1) + B[0]*pow(2,0)

    N = b[n-1]*pow(2,n-1) + b[n-2]*pow(2,n-2) + ... + b[1]*pow(2,1) + [0]*pow(2,0)

    pow(N,2) = M

    (1) N的最高位b[n-1]可以根據M的最高位B[m-1]直接求得。

    設 m 已知,因為 pow(2, m-1) <= M <= pow(2, m),所以 pow(2, (m-1)/2) <= N <= pow(2, m/2)

    如果 m 是奇數,設m=2*k+1,

    那么 pow(2,k) <= N < pow(2, 1/2+k) < pow(2, k+1),

    n-1=k, n=k+1=(m+1)/2

    如果 m 是偶數,設m=2k,

    那么 pow(2,k) > N >= pow(2, k-1/2) > pow(2, k-1),

    n-1=k-1,n=k=m/2

    所以b[n-1]完全由B[m-1]決定。

    余數 M[1] = M - b[n-1]*pow(2, 2*n-2)

    (2) N的次高位b[n-2]可以采用試探法來確定。

    因為b[n-1]=1,假設b[n-2]=1,則 pow(b[n-1]*pow(2,n-1) + b[n-1]*pow(2,n-2), 2) = b[n-1]*pow(2,2*n-2) + (b[n-1]*pow(2,2*n-2) + b[n-2]*pow(2,2*n-4)),

    然后比較余數M[1]是否大于等于 (pow(2,2)*b[n-1] + b[n-2]) * pow(2,2*n-4)。這種比較只須根據B[m-1]、B[m-2]、...、B[2*n-4]便可做出判斷,其余低位不做比較。

    若 M[1] >= (pow(2,2)*b[n-1] + b[n-2]) * pow(2,2*n-4), 則假設有效,b[n-2] = 1;

    余數 M[2] = M[1] - pow(pow(2,n-1)*b[n-1] + pow(2,n-2)*b[n-2], 2) = M[1] - (pow(2,2)+1)*pow(2,2*n-4);

    若 M[1] < (pow(2,2)*b[n-1] + b[n-2]) * pow(2,2*n-4), 則假設無效,b[n-2] = 0;余數 M[2] = M[1]。

    (3) 同理,可以從高位到低位逐位求出M的平方根N的各位。

    使用這種算法計算32位數的平方根時最多只須比較16次,而且每次比較時不必把M的各位逐一比較,尤其是開始時比較的位數很少,所以消耗的時間遠低于牛頓迭代法。

    3. 實現代碼

    這里給出實現32位無符號整數開方得到16位無符號整數的C語言代碼。

    /****************************************/

    /*Function: 開根號處理 */

    /*入口參數:被開方數,長整型 */

    /*出口參數:開方結果,整型 */

    /****************************************/

    unsigned int sqrt_16(unsigned long M)

    {

    unsigned int N, i;

    unsigned long tmp, ttp; // 結果、循環計數

    if (M == 0) // 被開方數,開方結果也為0

    return 0;

    N = 0;

    tmp = (M >> 30); // 獲取最高位:B[m-1]

    M <<= 2;

    if (tmp > 1) // 最高位為1

    {

    N ++; // 結果當前位為1,否則為默認的0

    tmp -= N;

    }

    for (i=15; i>0; i--) // 求剩余的15位

    {

    N <<= 1; // 左移一位

    tmp <<= 2;

    tmp += (M >> 30); // 假設

    ttp = N;

    ttp = (ttp<<1)+1;

    M <<= 2;

    if (tmp >= ttp) // 假設成立

    {

    tmp -= ttp;

    N ++;

    }

    }

    return N;

    }

    版權聲明:轉載文章來自公開網絡,版權歸作者本人所有,推送文章除非無法確認,我們都會注明作者和來源。如果出處有誤或侵犯到原作者權益,請與我們聯系刪除或授權事宜。

    預約申請免費試聽課

    填寫下面表單即可預約申請免費試聽!怕錢不夠?可就業掙錢后再付學費! 怕學不會?助教全程陪讀,隨時解惑!擔心就業?一地學習,可全國推薦就業!

    上一篇:單片機常用的七個C語言算法
    下一篇:3大技巧5個基本功成為優秀工程師就是這么簡單!

    單片機:寫1清零,寫0清零,有什么區別?

    嵌入式工程師一定不要亂用全局變量

    嵌入式培訓靠譜嗎?就業怎么樣?

    新手如何學習單片機?

    • 掃碼領取資料

      回復關鍵字:視頻資料

      免費領取 達內課程視頻學習資料

    • 視頻學習QQ群

      添加QQ群:1143617948

      免費領取達內課程視頻學習資料

    Copyright ? 2021 Tedu.cn All Rights Reserved 京ICP備08000853號-56 京公網安備 11010802029508號 達內時代科技集團有限公司 版權所有

    選擇城市和中心
    黑龍江省

    吉林省

    河北省

    湖南省

    貴州省

    云南省

    廣西省

    海南省

    欧美一级高清片,一级欧美免费大片视频,欧美三级在线电影免费 百度 好搜 搜狗
    <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>