单片机中常用滤波算法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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)