1-17 修改了顺序执行程序和滑动平均滤波的错误
C语言 结构体
枚举体
头文件
预处理指令
函数指针
C语言中文网 http://c.biancheng.net/view/2031.html
代码风格 【C语言|C语言程序思路与几种常用的滤波】工程
缩进
注释
vscode
通信 uart iic spi 硬件协议,模拟协议
写数据,写命令,读数据
串口发送,接收,中断
非阻塞延时
int timecnt=-1;
//当前计数值(倒计时)
......
{
if(something && timecnt==-1)
{
timecnt=1000;
//1000ms倒计时
}
if(timecnt==0)//倒计时结束
{
timecnt=-1;
//计时器复位
somefun();
//倒计时结束后执行的程序
}
}
......
timer_irq_handle()//定时器中断函数,周期一般1ms
{
if(timecnt>0)
timecnt--;
......
}
顺序执行程序思路
int process[5];
//5步
......if(something_start && !process[1])//起始步
{
if(!process[0])
{
initfun0();
//初始化程序,可省略
process[0]=1;
//置位本步标志位
}
somefun0();
//持续执行程序
}if(something1 && process[0] && !process[2])//步1
{
if(!process[1])
{
initfun1();
//初始化程序
process[1]=1;
//置位本步标志位
}
somefun1();
//持续执行程序
}
if(something2 && process[1] && !process[3])//步2
{
if(!process[2])
{
initfun2();
//初始化程序
process[2]=1;
}
somefun2();
//持续执行程序
}
......if(something_end && process[x])//结束步,process[x]是最后一步
{
memset(process,0,sizeof(process));
//清零所有标志位
}
滤波 软件滤波在嵌入式的数据采集和处理中有着很重要的作用。
以下几种软件滤波方法参考“匠人的百宝箱”,下文为根据自己的理解修改整理,对原作者表示感谢。
原文章来源不明,百度 十种常见的滤波方法
1.算术平均滤波 A、方法:
连续取N个采样值进行算术平均运算
N值较大时:信号平滑度较高,但灵敏度较低
N值较小时:信号平滑度较低,但灵敏度较高
N值的选取:一般流量,N=12;压力:N=4
B、优点:
适用于对一般具有随机干扰的信号进行滤波
这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动
C、缺点:
对于测量速度较慢或要求数据计算速度较快的实时控制不适用
float filter(int N)//N为采样次数
{
float value;
for(int i=0;
i
2.限幅滤波 A、方法:
根据经验判断,确定两次采样允许的最大偏差值(设为A),
每次检测到新值时判断:
如果本次值与上次值之差<=A,则本次值有效;
如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值
B、优点:
能有效克服因偶然因素引起的脉冲干扰
C、缺点
无法抑制周期性的干扰
平滑度差
#define ABS(x) (((x) > 0) ? (x) : (-(x)))//绝对值宏函数
float filter(float A) //A为允许偏差值
{
static float new_value,last_value;
//静态变量或全局变量
last_value = https://www.it610.com/article/new_value;
new_value = get_value();
if ( ABS(new_value - last_value)> A )
return last_value;
return new_value;
}
另外,还有一种限幅滤波比较常用,如果超过上(下)限位,则本次值 = 上(下)限位
void filter(float *value, float min, float max)
{
if(*value>max) *value = https://www.it610.com/article/max;
else if(*value < min) *value = min;
}
//以下为调用时
value = get_value();
filter(&value,min,max);
限幅滤波一般搭配其他滤波来用,如限幅平均滤波
3.一阶滞后滤波(低通) A、方法:
取a=0~1
本次滤波结果= a*本次采样值+(1-a)*上次滤波结果
B、优点:
对周期性干扰具有良好的抑制作用
适用于波动频率较高的场合
C、缺点:
相位滞后,灵敏度低
滞后程度取决于a值大小
不能消除滤波频率高于采样频率的1/2的干扰信号
float filter( float a)
{
static float new_value,last_value;
//静态变量或全局变量 last_value = https://www.it610.com/article/new_value;
new_value = get_value();
new_value = a * (new_value - last_value) + last_value;
return new_value;
}
4.中位值滤波 A、方法:
连续采样N次(N取奇数)
把N次采样值按大小排列
取中间值为本次有效值
B、优点:
能有效克服因偶然因素引起的波动干扰
对温度、液位的变化缓慢的被测参数有良好的滤波效果
C、缺点:
对流量、速度等快速变化的参数不宜
#define N 100
float value_buf[N];
int filter()
{
float sum=0,temp;
for(int count=0;
count value_buf[i+1] )
{
temp = value_buf[i];
value_buf[i] = value_buf[i+1];
value_buf[i+1] = temp;
}
}
}
return value_buf[(N-1)/2];
//中位值平均滤波
//for(int count = 1;
count < N-1;
count++)
//sum += value[count];
//return (int)(sum/(N-2));
}
5.滑动平均滤波 A、方法:
把连续取N个采样值看成一个队列
队列的长度固定为N
每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据.(先进先出原则)
把队列中的N个数据进行算术平均运算,就可获得新的滤波结果
N值的选取:流量,N=12;压力:N=4;液面,N=412;温度,N=14
B、优点:
对周期性干扰有良好的抑制作用,平滑度高
适用于高频振荡的系统
C、缺点:
灵敏度低
对偶然出现的脉冲性干扰的抑制作用较差
不易消除由于脉冲干扰所引起的采样值偏差
不适用于脉冲干扰比较严重的场合
#define N 12
int value_buf[N];
float filter()
{
float sum=0;
for(int i=N-1;
i>=1;
i--)
{
value_buf[i] = value_buf[i-1];
//数据后移,高位被替换掉
}
value_buf[0] = get_value();
//新值给第0个元素 for(int i=0;
i
6.互补滤波 A、方法:
对通过两种途径得到的采集值进行加权融合
本次滤波结果 = a * 方法A的采集值 + (1-a) * 方法B的采集值
B、优点
融合两种方案的结果,取长补短
C、缺点:
灵敏度低,不适应频率较高的数据
floatfilter(float a)
{
float value_a, value_b, value;
value_a = get_a();
value_b = get_b();
value = https://www.it610.com/article/a * (value_a -value_b) + value_b;
return value;
}
推荐阅读
- C语言|程序环境和预处理 C语言入门到入土(进阶篇)
- C语言|C语言文件操作 C语言入门到入土(进阶篇)
- C语言|一篇解单链表(0基础看)(C语言)《数据结构与算法》
- C语言|一篇解自定义类型(结构体,位段,枚举,联合 C语言入门到入土(进阶篇))
- C语言|(指针)C语言从入门到入土(入门篇)
- C语言|如何让朋友也能玩自己写的游戏(.exe文件如何附带静态链接库)C语言从入门到入土(入门特别篇)
- C语言|C语言总结这一篇就够了(不收藏必后悔系列)
- C语言中 static 关键字的使用方面总结
- C语言|学习C语言编程,推荐你看这6本书