声明:此内容经本人整理,供大家交流使用。不妥之处,敬请指出。QQ:779589211 吾生有涯

随机误差是有随机干搅引起的,其特点是在相同条件下测量同一个量时,其大小和符号做无规则变化而无法预测,但多次测量结果符合统计规律。为克服随机干搅引入的误差,硬件上可采用滤波技术,软件上可以采用软件算法实现数字滤波,其算法往往是系统测控算法的一个重要组成部分,实时性很强,采用汇编语言来编写。

采用数字滤波算法克服随机干搅引入的误差具有以下几个优点:

(1)数字滤波无须硬件,只用一个计算过程,可靠性高,不存在阻抗匹配问题,尤其是数字滤波可以对

频率很高或很低的信号进行滤波,这是模拟滤波器做不到的。

(2)数字滤波是用软件算法实现的,多输入通道可用一个软件“滤波器”从而降低系统开支。

(3)只要适当改变软件滤波器的滤波程序或运行参数,就能方便地改变其滤波特性,这个对于低频、脉冲

干搅、随机噪声等特别有效。

常用的数字滤波器算法有程序判断法、中值判断法、算术平均值法、加权滤波法、滑动滤波法、低通滤波法和复合滤波法。

1. 程序判断法:

程序判断法又称限副滤波法,其方法是把两次相邻的采样值相减,求出其增量(以绝对值表示)。然后与两次采样允许的最大差值△Y进行比较,△Y的大小由被测对象的具体情况而定,若小于或等于△Y,则取本次采样的值;若大于△Y,则取上次采样值作为本次采样值,即

yn -

yn-1|≤△Y,则yn有效,

yn -yn-1|>△Y,则yn-1有效。

式中 yn ——第n次采样的值;

Yn-1——第(n-1)次采样的值;

△Y——相邻两次采样值允许的最大偏差。

设R1和R2为内部RAM单元,分别存放yn-1和yn,滤波值也存放在R2单元,采用MCS-51单片机指令编写的程序判断法子程序如下:付表

2. 中值滤波法即对某一参数连续采样N次(一般N为奇数),然后把N次采样值按从小到大排队,再取中间值作为本次采样值。

设DATA为存放采样值的内存单元首地址,SAMP为存放滤波值的内存单元地址,N为采样值个数,用MCS-51指令编写的中值滤波子程序如下:副表

3.算术平均值滤波算法

算术平均滤波法就是连续取N次采样值进行算术平均,其数学表达式是:

Y=∑yi

~y=1/N ∑ yi

i=1……N

式中 ~y——N个采样值的算术平均值;

Yi ——第i个采样值;

设8次采样值依次存放在地址DATA开始的连续单元中,滤波结果保留在累加器A中,程序如下:副表

4.加权平均滤波法

算术平均滤波法存在前面所说的平滑和灵敏度之间的矛盾。采样次数太少,平滑效果差,次数太多,灵敏度下降,对参数的变化趋势不敏感。协调两者关系,可采用加权平均滤波,对连续N次采样值,分别乘上不同的加权系数之后再求累加和,加权系数一般先小后大,以突出后面若干采样的效果,加强系统对参数的变化趋势的辩识,各个加权系数均为小于1的小数,且满足总和等于1的约束条件,这样,加权运算之后的累加和即为有效采样值。为方便计算,可取各个加权系数均为整数,且总和为256,加权运算后的累加和除以256(即舍去低字节)后便是有效采样值。

设每批采样8个数据,依次存放在地址DATA开始的单元中,各加权系数是用一个表格存放在ROM中,MCS-51指令编写的算术平均滤波程序如下:副表

5.滑动平均滤波法:

以上介绍的各种平均滤波算法有一个共同点,即每取得一个有效采样值必须连续进行若干次采样,当采样速度较慢(如双积分型A/D转换)或目标参数变化较快时,系统的实时性不能保证,滑动平均滤波算法只采样一次,将这一次采样值和过去的若干次采样值一起求平均,得到的有效采样值即可投入使用,如果取N个采样值求平均,RAM中必须开辟N个数据的暂存区。每新采样一个数据便存入暂存区,同时去掉一个最老的数据,保持这N个数据始终是最近的数据,这种数据存放方式可以用环行队列结构方便的实现。设环行队列为40H-4FH连续16个单元,RO作为队尾指针,滤波程序如下:副表

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(小数)中。滤波程序如下:副表

结束语:

微型计算机在仪器仪表系统中的成功应用,使传统的电子仪器以及复杂的跟踪测量装置发生了许多革命性变化。其中一个突出表现就是一个系统中包含了智能性运作。微机具有很强的分析和运算能力,智能系统可完成复杂的数据处理,智能系统采用软件硬件想结合的方法进行随机误差的数字滤波和系统误差的修正,可以实现实时修正,较准测量数据,这些都是传统仪器难以比拟的。

#include

#include

#include

#include

#include "source.h"

main()

{

filter_1();

filter_2();

filter_3();

filter_4();

filter_5();

filter_6();

filter_7();

filter_8();

filter_9();

filter_10();

}

unsigned char get_ad(void){

static unsigned char i;

return i++;

}

void delay(void){

unsigned char i=0;

while(1){

i++;

if(i>20) return;

}

}

#define A 10 //设置两次采样允许的最大偏差值

char value; //上次采用后的有效值变量

char filter_1(void){

char new_value; //本次采样值变量

new_value=get_ad(); //读入本次采样值

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

//比较是否超出最大偏差值

return value;

//如果超出,返回上次的有效值作为本次的有效值

return new_value;//

如果没有超出,返回本次的采样值作为本次的有效值

}

#define N 11 //设置连续采样的次数

char filter_2(void){

char value_buf[N];

//缓存N次采样值的存储变量

char count,i,j,temp;

//i,j是冒泡排序的下标变量,count是采样数据读入的下标变量

//temp是临时变量

for(count=0;count

{

value_buf[count]=get_ad();

delay();

}

for(j=0;j

//气泡排序,由小到大

{

for(i=0;i

{

if(value_buf[i]>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];

//将排序后N个采样值的中间值作为最后结果返回

}

#undef N

#define N 12 //设置每组参与平均运算的采样值个数

char filter_3(){

int sum=0;

//求和变量,用于存储采样值的累加值

char count;//采样数据读入的下标变量

for(count=0;count

{

sum+=get_ad();

delay();

}

return (char)(sum/N);

//讲累加值进行平均计算作为返回值

}

#undef N

#define N 12 //设置FIFO队列的长度

char value_buf[N];//FIFO队列变量

char i=0;

//队列的下标变量

char filter_4(){

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);

}

#undef N

#define N 12 //设置每组采样值的数量

char filter_5()

{

char count,i,j,temp;

//i,j是冒泡排序的下标变量,count是采样数据读入的下标变量

char value_buf[N]; // 缓冲N个采样值的存储变量

int sum=0;

//求和变量,用于存储采样值的累加值

for (count=0;count

{

value_buf[count] = get_ad();

delay();

}

for (j=0;j

//气泡排序,由小到大

{

for (i=0;i

{

if (

value_buf[i]>value_buf[i+1] )

{

temp = value_buf[i];

value_buf[i] = value_buf[i+1];

value_buf[i+1] = temp;

}

}

}

for(count=1;count

sum += value_buf[count];

//去掉两端的最小和最大采样值,对中间的N-2个采样值求和

return (char)(sum/(N-2));//

返回中间N-2个采样值的平均值

}

#undef A

#undef N

#define A 10 //设置两次采样允许的最大偏差值

#define N 12 //设置每组参与平均运算的采样值个数

char value; //上次采用后的有效值变量

char filter_6()

{

char new_value; //本次采样值变量

int sum=0;

//求和变量,用于存储采样值的累加值

char count;//采样数据读入的下标变量

for(count=0;count

{

new_value=get_ad(); //读入本次采样值

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

//比较是否超出最大偏差值

new_value=value;

//如果超出,返回上次的有效值作为本次的有效值

sum+=new_value; //累加采样的有效值

value=new_value;

delay();

}

return (char)(sum/N);

//将累加值进行平均计算作为返回值

}

#define COE 50 //定义加权系数

char value; //上一个采样值变量

char filter_7()

{

char new_value;

//本次采样值变量

new_value = get_ad();

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

//返回的本次滤波结果

}

#undef N

#define N 12 //设置FIFO队列的长度

char code coe[N] =

{1,2,3,4,5,6,7,8,9,10,11,12}; //加权系数

char code sum_coe =

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

char filter_8()

{

char count; //采样数据读入的下标变量

char value_buf[N]; //缓存N个采样值的存储变量

int sum=0;

//求和变量,用于存储采样值的累加值

for

(count=0;count

{

value_buf[count] = get_ad();

//读入采样值

delay();

}

for

(count=0;count

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

//累加采样值和系数的乘积

return (char)(sum/sum_coe);

//累加值与系数和相除作为返回结果

}

#undef N

#define N 12 //设置计数器溢出值

char filter_9()

{

char count=0; //计数变量

char new_value; //本次采样值变量

new_value = get_ad(); //读入本次采样值

while (value !=new_value);

{

count++; //计数器加1

if

(count>=N) return new_value; //如果本次采样值与当前有效值不相等,

//且计数器溢出,返回本次采样值

delay();

new_value = get_ad();

}

return value;

//如果本次采样值与当前有效值相等,则返回当前有效值

}

#undef A

#undef N

#define A 10 //设置两次采样允许的最大偏差值

#define N 12 //设置计数器溢出值

char value; //有效值变量

char filter_10()

{

char count=0; //计数变量

char new_value; //本次采样值变量

new_value = get_ad(); //读入本次采样值

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

//比较是否超出最大偏差值

new_value=value;

//如果超出,返回有效值作为本次的采样有效值

while (value !=new_value);

{

count++; //计数器加1

if

(count>=N) return new_value; //如果本次采样值与当前有效值不相等,

//且计数器溢出,返回本次采样值

delay();

new_value = get_ad();

}

return value;

//如果本次采样值与当前有效值相等,则返回当前有效值

}

单片机数字滤波c语言程序,单片机系统中数字滤波的算法【C程序整理】相关推荐

  1. c语言控制安卓桌面,让你自己编写的Android的Launcher成为系统中第一个启动应用程序,也是唯一的Launcher...

    关注嵌入式安卓物联网行业及人才培养,每日更新,欢迎订阅及留言讨论~~~ 作者:倪键树,嵌入式安卓物联网讲师. 让你自己编写的Android的Launcher成为系统中第一个启动应用程序,也是唯一的La ...

  2. c语言将注释和语句分离,C语言组卷系统中重复题问题研究

    C语言组卷系统中重复题问题研究 作者:陈星 李郴 来源:电脑知识与技术 201801期 时间:2018-06-02 摘要:在一套试卷中,重复题问题是影响考试质量的一个重要因素.该文针對C语言试卷中选择 ...

  3. Explorer.exe程序在系统中的作用

    Explorer.exe程序在系统中的作用 凡是Windows系列的操作系统,运行时都会启动一个名为Explorer.exe的进程.这个进程主要负责显示系统桌面上的图标以及任务栏,它在不同的系统中有不 ...

  4. linux ctg重装,Linux 系统中 CTG 的安装, 应用程序开发以及调试

    Linux 系统中 CTG 的安装, 应用程序开发以及调试 准备 1)CICS Transaction Gateway for Multiplatforms, CICS Transaction Gat ...

  5. mac系统中自带的邮件程序如何添加qq邮箱帐号?

    mac系统中自带的邮件程序怎么添加qq邮箱帐号?工作总最常用的就是qq邮箱,想把qq邮箱添加到mac系统自带的邮件中去,该怎么设置呢?下面我们来看看mac系统添加qq邮箱的方法. 各位使用苹果系统的小 ...

  6. luat系统中的异或校验程序

    luat系统中的异或校验程序 --[[异或校验string1:输入的须交验的字符串xordata:返回的字符串校验 ]] function BCC(string1)local xordata = bi ...

  7. 微信小程序获取系统日期和时间 —— 微信小程序教程系列(17)

    获取当前系统日期和时间 在小程序中,新建项目时,就会有一个utils.js文件,就是获取日期和时间的,代码如下: utils.js: function formatTime(date) {var ye ...

  8. 疑难杂症篇(十八)--ROS系统中使用SLAM算法建图时出现地图漂移的几种原因

    本篇主要介绍在ROS系统中使用SLAM算法建地图时出现地图定位漂移的几种原因及可以采取的措施. 1.SLAM建图时出现的定位漂移现象 2.原因分析 里程计数据发生异常: 计算机的配置不高,计算机建图过 ...

  9. Win10系统中很多磁盘碎片怎么进行整理?

    Win10系统中很多磁盘碎片怎么进行整理?电脑使用的时间长了之后,就会在磁盘中生成很多的磁盘碎片,影响我们的使用,电脑会变得卡顿.那么这个情况怎么去进行修复呢?接下来一起来看看磁盘碎片清理的操作方法分 ...

  10. 中达优控一体屏台达程序,包含中达优控屏程序

    中达优控一体屏台达程序,包含中达优控屏程序,plc程序,程序 结构清晰,注释完整 ID:3618643532025121工业自动化

最新文章

  1. 工作笔记---巡检记录
  2. “比特币耶稣”罗杰·沃推特赠币,留下BCH钱包地址就有份
  3. Java bitset转string_Java 二进制和十进制互转,二进制和BitSet互转
  4. 高通平台:USB充电
  5. CSS属性(根据继承性分为两类)
  6. tablayout支持改变选中文字大小,支持左右滑动,支持viewpager,支持三角可移动指示器...
  7. 领域应用 | 基于知识图谱的警用安保机器人大数据分析技术研究
  8. 比较一下以“反射”和“表达式”执行方法的性能差异【转】
  9. 初识EntityFramework6【转】
  10. 【leetcode】Multiply Strings(middle)
  11. Beego 使用笔记
  12. [转载]INNO SETUP注册DLL文件
  13. 基于stm32智能门锁系统
  14. 管螺纹如何标注_螺纹基础知识,螺纹的种类,螺纹的要素和螺纹的画法
  15. 基于Luckysheet实现的协同编辑在线表格支持在线导入数据库,前端导出,前端导入,后端导出
  16. Golang interface 接口详解
  17. 网吧服务器磁盘性能,网吧游戏服务端显示磁盘已满怎么解决
  18. 医院计算机系统日常维护记录表,医院计算机信息管理系统的应用及维护
  19. 阿里云RDS数据库与自建数据库做主从同步
  20. 计算机会计试题原型法的优缺点,《计算机会计学》1..doc

热门文章

  1. js通过身份证号获取出生日期,性别,年龄
  2. 非零基础自学Golang 第15章 Go命令行工具 15.4 注释文档(doc)
  3. matlab sheet名字,MATLAB得到excel多个非默认sheet名_怎样利用matlab去读取一个excel表中多个sheet的数据并导入一个sheet中?...
  4. [导入]剿杀diskman.exe木马病毒
  5. Mac 系统下VisualVM的安装
  6. 浅谈“POODLE信息泄露漏洞”
  7. 推荐一款很好用的一款扒网站的工具
  8. 3GPP TS 23501-g51 中英文对照 | 4.3.3 Interworking between 5GC via non-3GPP access and E-UTRAN connected t
  9. RGB和YCbCr颜色空间的转换及优化算法
  10. 绝缘栅型n沟道场管_N沟道增强型绝缘栅场效应管的工作原理