单片机中常用滤波算法

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

单片机中常用滤波算法

限幅滤波算法:

将两次相邻的采样值相减,求出其增量的绝对值,与两次采样允许的最大差值A进行比较。A的大小由被测对象的具体情况而定,如果小于或等于允许的最大差值,则本次采样值有效;否则取上次采样值做本次采样数据的样本。(用于处理变化缓慢的数据)

#define A

char data

char f ilter_1()

{

char data_new;

datanew = get_data();

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

return data;

return datanew;

}

中值滤波算法:

对某一个参数连续采样N次(N为奇),然后排序(从小到大)再取中间值作为本次采样值。(去掉偶然因素引起的波动和采样器不稳定而引起的脉动干扰,要求变化缓慢)

#define N 11

char filter_2()

{

char value_buf[N];

char count , i , j , temp;

for(count=0;count

{

value_buf[count] = get_data();

delay();

}

for(i=0; i

for(j=0 ; j

if(value_buf[i] > value_buf[j])

{

交换两值;

}

}

算术平均滤波算法:

连续N次取样,算术平均,适用于对具有随机干扰的信号进行滤波;

char filter_3()

{

int Sum=0;

for(count =0;count

{

Sum+=get_data();

delay();

}

return (char) (Sum/N) ;

}

加权平均滤波运算法:

为了协调平滑度和灵敏度之间的关系,对连续N次采样值分别乘上不同的加权系数之后再求累加和,加权系数一般先小后大,以突出后面若干采样的效果。

char code jq[N]={0,1,2,3,····12};

char code sum_jq=1+2+ (12)

char filter_4()

{

char count;

char value_buf[N];

int sum=0;

for(count=0;count

{

value_buf[count]=get_data();

delay();

}

for(count=0;count<0;count++)

{

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

}

return (char) (sum / sumjq);

}

滑动平均滤波算法:

只采样一次,将这一次采样值和过去的若干次采样值一起求平均,得到的有效采样值一起求平均,得到的有效采样值即可投入使用;(采用环状队列结构可以方便地实现这种数据存放方式)char value_buf[N];

char i=0;

char filter_5()

{

char count ;

int sum=0;

value_buf[i++]=get_data();

if(i==N)

i=0;

for(count=0;count

{

sum=value_buf[count];

}

return (char) (sum/N);

}

51单片机PID的算法实现程序

用整型变量来实现PID算法,由于是用整型数来做的,所以也不是很精确,但是对于很多的使用场合,这个精度也够了,关于系数和采样电压全部是放大10倍处理的.所以精度不是很高. 但是也不是那么低,大部分的场合都够了. 实在觉得精度不够, 可以再放大10倍或者100倍处理,但是要注意不超出整个数据类型的范围就可以了.本程序包括PID计算和输出两部分.当偏差>10度全速加热,偏差在10度以内为PID计算输出. 具体的参考代码参见下面:*/

//================================================================

// pid.H

// Operation about PID algorithm procedure

// C51编译器Keil 7.08

//================================================================

// 作者:zhoufeng

// Date :2007-08-06

// All rights reserved.

//================================================================

#include

#include

typedef unsigned char uint8;

typedef unsigned int uint16;

typedef unsigned long int uint32;

/**********函数声明************/

void PIDOutput ();

void PIDOperation ();

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

typedef struct PIDValue

{

uint32 Ek_Uint32[3]; //差值保存,给定和反馈的差值

uint8 EkFlag_Uint8[3]; //符号,1则对应的为负数,0为对应的为正数

uint8 KP_Uint8;

uint8 KI_Uint8;

uint8 KD_Uint8;

uint16 Uk_Uint16; //上一时刻的控制电压

uint16 RK_Uint16; //设定值

uint16 CK_Uint16; //实际值

}PIDValueStr;

PIDValueStr PID;

uint8 out ; // 加热输出

uint8 count; // 输出时间单位计数器

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

PID = Uk + KP*[E(k)-E(k-1)]+KI*E(k)+KD*[E(k)-2E(k-1)+E(k-2)];(增量型PID算式)

函数入口: RK(设定值),CK(实际值),KP,KI,KD

函数出口: U(K)