单片机数字滤波算法如何实现?(附代码)

2023-05-16


ID:技术让梦想更伟大

整理:李肖遥

单片机主要作用是控制外围的器件,并实现一定的通信和数据处理。

但在某些特定场合,不可避免地要用到数学运算,尽管单片机并不擅长实现算法和进行复杂的运算。

下面主要是介绍如何用单片机实现数字滤波。

在单片机进行数据采集时,会遇到数据的随机误差,随机误差是由随机干扰引起的,其特点是在相同条件下测量同一量时,其大小和符号会现无规则的变化而无法预测,但多次测量的结果符合统计规律。

为克服随机干扰引起的误差,硬件上可采用滤波技术,软件上可采用软件算法实现数字滤波。滤波算法往往是系统测控算法的一个重要组成部分,实时性很强。

采用数字滤波算法克服随机干扰的误差具有以下优点:

  1. 数字滤波无需其他的硬件成本,只用一个计算过程,可靠性高,不存在阻抗匹配问题。尤其是数字滤波可以对频率很低的信号进行滤波,这是模拟滤波器做不到的。

  2. 数字滤波使用软件算法实现,多输入通道可共用一个滤波程序,降低系统开支。

  3. 只要适当改变滤波器的滤波程序或运算,就能方便地改变其滤波特性,这对于滤除低频干扰和随机信号会有较大的效果。

  4. 在单片机系统中常用的滤波算法有限幅滤波法、中值滤波法、算术平均滤波法、加权平均滤波法、滑动平均滤波等。

限幅滤波算法

该运算的过程中将两次相邻的采样相减,求出其增量,然后将增量的绝对值,与两次采样允许的最大差值A进行比较。

A的大小由被测对象的具体情况而定,如果小于或等于允许的最大差值,则本次采样有效;否则取上次采样值作为本次数据的样本。

算法的程序代码如下:

 1#define A //允许的最大差值
 2
 3char data; //上一次的数据
 4
 5char filter()
 6
 7{
 8
 9    char datanew; //新数据变量
10
11    datanew=get_data(); //获得新数据变量
12
13    if((datanew-data)>A||(data-datanew>A))
14
15        return data;
16
17    else
18
19        return datanew;
20
21}

说明:

限幅滤波法主要用于处理变化较为缓慢的数据,如温度、物体的位置等。使用时,关键要选取合适的门限制A。通常这可由经验数据获得,必要时可通过实验得到。

中值滤波算法

该运算的过程是对某一参数连续采样N次(N一般为奇数),然后把N次采样的值按从小到大排列,再取中间值作为本次采样值,整个过程实际上是一个序列排序的过程。

算法的程序代码如下:

 1#define N 11 //定义获得的数据个数 2 3char filter()
 4
 5{
 6 7    char value_buff[N]; //定义存储数据的数组 8 9    char count,i,j,temp;
1011    for(count=0;count<N;count++)
1213    {
1415        value_buf[count]=get_data();
1617        delay(); //如果采集数据比较慢,那么就需要延时或中断1819    }
2021    for(j=0;j<N;j++)
2223    {
2425        if(value_buff[i]>value_buff[i+1])
2627        {
2829            temp=value_buff[i];
3031            value_buff[i]=value_buff[i+1];
3233            value_buff[i+1]=temp;
3435        }
3637    }
3839return value_buff[(N-1)/2];
4041}

说明:中值滤波比较适用于去掉由偶然因素引起的波动和采样器不稳定而引起的脉动干扰。若被测量值变化比较慢,采用中值滤波法效果会比较好,但如果数据变化比较快,则不宜采用此方法。

算术平均滤波算法

该算法的基本原理很简单,就是连续取N次采样值后进行算术平均。

算法的程序代码如下:

 1char filter()
 2
 3{
 4
 5    int sum=0;
 6
 7    for(count=0;count<N;count++)
 8
 9    {
10
11        sum+=get_data();
12
13        delay():
14
15    }
16
17    return (char)(sum/N);
18
19}

说明:算术平均滤波算法适用于对具有随机干扰的信号进行滤波。这种信号的特点是有一个平均值,信号在某一数值附近上下波动。

信号的平均平滑程度完全到决于N值。当N较大时,平滑度高,灵敏度低;当N较小时,平滑度低,但灵敏度高。为了方便求平均值,N一般取4、8、16、32之类的2的整数幂,以便在程序中用移位操作来代替除法。

加权平均滤波算法

由于前面所说的“算术平均滤波算法”存在平滑度和灵敏度之间的矛盾。为了协调平滑度和灵敏度之间的关系,可采用加权平均滤波。

它的原理是对连续N次采样值分别乘上不同的加权系数之后再求累加,加权系数一般先小后大,以突出后面若干采样的效果,加强系统对参数变化趋势的认识。

各个加权系数均小于1的小数,且满足总和等于1的结束条件。这样加权运算之后的累加和即为有效采样值。其中加权平均数字滤波的数学模型是:

式中:D为N个采样值的加权平均值:XN-i为第N-i次采样值;N为采样次数;Ci为加权系数。加权系数Ci体现了各种采样值在平均值中所占的比例。

一般来说采样次数越靠后,取的比例越大,这样可增加新采样在平均值中所占的比重。

加权平均值滤波法可突出一部分信号抵制另一部分信号,以提高采样值变化的灵敏度。

样例程序代码如下:

 1char codejq[N]={1,2,3,4,5,6,7,8,9,10,11,12}; //code数组为加权系数表,存在程序存储区
 2
 3char codesum_jq=1+2+3+4+5+6+7+8+9+10+11+12;
 4
 5char filter()
 6
 7{
 8
 9    char count;
10
11    char value_buff[N];
12
13    int sum=0;
14
15    for(count=0;count<N;count++)
16
17    {
18
19        value_buff[count]=get_data();
20
21        delay();
22
23    }
24
25    for(count=0;count<N;count++)
26
27        sum+=value_buff[count]*jq[count];
28
29    return (char)(sum/sum_jq);
30
31}

滑动平均滤波算法

以上介绍和各种平均滤波算法有一个共同点,即每获取一个有效采样值必须连续进行若干次采样,当采速度慢时,系统的实时得不到保证。

这里介绍的滑动平均滤波算法只采样一次,将一次采样值和过去的若干次采样值一起求平均,得到的有效采样值即可投入使用。

如果取N个采样值求平均,存储区中必须开辟N个数据的暂存区。

每新采集一个数据便存入暂存区中,同时去掉一个最老数据,保存这N个数据始终是最新更新的数据。采用环型队列结构可以方便地实现这种数据存放方式。

程序代码如下:

 1char value_buff[N];
 2
 3char i=0;
 4
 5char filter()
 6
 7{
 8
 9    char count;
10
11    int sum=0;
12
13    value_buff[i++]=get_data();
14
15    if(i==N)
16
17        i=0;
18
19    for(count=0;count<N;count++)
20
21        sum=value_buff[count];
22
23    return (char)(sum/N);
24
25}


低通滤波

将普通硬件RC低通滤波器的微分方程用差分方程来表求,变可以采用软件算法来模拟硬件滤波的功能,经推导,低通滤波算法如下:

1Yn=a* Xn+(1-a) *Yn-1
2
3式中 Xn——本次采样值
4
5Yn-1——上次的滤波输出值;
6
7a——滤波系数,其值通常远小于1;
8
9Yn——本次滤波的输出值。

由上式可以看出,本次滤波的输出值主要取决于上次滤波的输出值(注意不是上次的采样值,这和加权平均滤波是有本质区别的),本次采样值对滤波输出的贡献是比较小的,但多少有些修正作用,这种算法便模拟了具体有教大惯性的低通滤波器功能。滤波算法的截止频率可用以下式计算:

1fL=a/2Pit pi为圆周率3.14…
2
3式中 a——滤波系数;
4
5t——采样间隔时间;
6
7例如:当t=0.5s(即每秒2次),a=1/32时;
8
9fL=(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(小数)中。

点击查看往期内容

(关注芯片之家)

往期好文阅读 

芯片之家精选文章合集 (一):收藏起来慢慢看

芯片之家精选文章合集 (二):收藏起来慢慢看

点击阅读????

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单片机数字滤波算法如何实现?(附代码) 的相关文章

  • 1、STM32CubeMX和STM32Cube库(HAL)详细介绍

    目录 前言 STM32Cube生态 STM32Cube 是什么 xff1f STM32Cube 软件工具套件 STM32Cube Embedded 软件 STM32CubeMX 编辑 前言 也许大家在学习正点原子或者其他32视频和代码的时候
  • 安卓SATA自动挂载实例

    平台 xff1a IMX6 OS 安卓4 2和安卓4 4 查看挂载log信息 xff1a logcat s Vold MountService 手动挂载 xff1a mount t ntfs dev block mnt mount t v
  • linux驱动开发 - 12_platform 平台驱动模型

    文章目录 platform 平台驱动模型1 platform 总线platform匹配过程 2 platform 驱动platform 驱动框架如下所示 xff1a 3 platform 设备platform 设备信息框架如下所示 xff1
  • 多旋翼飞行器设计与控制(二):基本组成

    一 前言核心问题 二 总体介绍多旋翼系统内部布局 三 机架机身起落架涵道 四 动力系统概述螺旋桨电机电调电池 五 指挥控制系统遥控器和接收器自动驾驶仪地面站数传 一 前言 核心问题 xff08 1 xff09 多旋翼组成结构 机架动力系统控
  • 多旋翼飞行器设计与控制(三):机架设计

    一 布局设计机身基本布局旋翼的安装旋翼和机体半径 xff1a 尺寸和机动性关系 xff1a 重心位置 xff1a 自驾仪安装位置 xff1a 气动布局 xff1a 二 结构设计机体基本设计原则减振设计减噪设计 一 布局设计 机身基本布局 交
  • SLAM学习——使用ARUCO_marker进行AR投影

    一 简介 1 1 目标 增强现实技术 xff08 Augmented Reality xff0c 简称 AR xff09 xff0c 是一种实时地计算摄影机影像的位置及角度并加上相应图像 视频 3D模型的技术 xff0c 这种技术的目标是在
  • k8s安装Prometheus

    注 xff1a 必须要先搭建网页管理容器 xff1b k8s部署dashboard kali yao的博客 CSDN博客 1 Prometheus的概述 Prometheus是一个最初在SoundCloud上构建的开源监控系统 它现在是一个
  • Logstash完成ELK集群

    注 xff1a 本文与同步 9条消息 搭建Elasticsearch和kibana完成初步ELK日志分析平台搭建 kali yao的博客 CSDN博客 logstash搭建 1 logstash介绍 什么是logstash 是一个数据采集
  • SQL基本语句及用法

    目录 一 基本SQL语句用法及概述 1 常用MySQL命令 2 语法规范 3 SQL语句分类 二 数据查询语言 1 基础查询 1 xff09 查询的字段列表可以是字段 常量 表达式 函数等 2 xff09 使用别名 xff0c 字段名和别名
  • PyCharm 社区版 安装 教程(Windows)

    注 xff1a 如果已经安装过python 3 5 及以上版本的解释执行器则跳过此步骤 下载 PyCharm 社区版 软件 PyCharm windows 版本 安装包如下 Thank you for downloading PyCharm
  • 监控zabbix面试题

    目录 1 我们可以用zabbix监控哪些 2 zabbix的主动监控与被动监控 3 Zabbix监控做过哪些 4 zabbix监控mysql的四大性能指标 5 配置zabbix自定义监控流程 6 安全组是什么 xff0c 限制了3306的入
  • 【ros学习】12.ros启动gazebo时摄像头的发布进程被杀死,导致rqt_image_view无法显示画面

    ros启动gazebo时摄像头的发布进程被杀死 xff0c 导致rqt image view即使订阅了正确的话题也无法显示画面 原因是gazebo的版本过低 xff0c 与Rviz不兼容 ubuntu16 04匹配的ros版本是kineti
  • 系统运维面试题

    目录 1 什么是运维 什么是游戏运维 2 在工作中 xff0c 运维人员经常需要跟运营人员打交道 xff0c 请问运营人员是做什么工作的 xff1f 3 请描述下linux 系统的开机启动过程 4 为什么连接的时候是三次握手 xff0c 关
  • Xshell的使用

    本文修改于 xff1a 高效使用XSHELL 简书 jianshu com https www jianshu com p 67b83d3f2e40 一 XShell的概述 1 XSHELL是什么 Xshell是用于Windows平台的功能
  • linux下解压rar和7z压缩文件

    在windows下我们压缩解压文件通常后缀为rar xff0c 在linux下我们压缩解压文件通常后缀为tar 默认在linux下我们不能解压压缩rar文件 我们可以下载rarlinux安装包实现解压压缩后缀为rar的包 下载地址 xff1
  • Filebeat输出json格式的日志并指定message字段的值

    目录 1 开启json格式所需的字段概述 2 配置示例 3 如果问题没有解决可点击官网 1 开启json格式所需的字段概述 filebeat配置input要有以下字段 json keys under root true json overw
  • Prometheus添加邮件告警和企业微信机器人告警

    我们将在 Prometheus 服务器上编写警报规则 xff0c 这些规则将使用我们收集的指标并在指定的阈值或标准上触发警报 xff0c 收到警报后 xff0c Alertmanager 会处理警报并根据其标签进行路由 一旦路径确定 xff
  • 麒麟ARM64制作nginx,java,php,node基础镜像

    一 环境准备 1 网上搜底层镜像 麒麟容器基础镜像 xff1a docker search kylin 镜像准备 docker pull kylin 注 xff1a 最好自己制作底层镜像 2 自己做底层镜像 注 xff1a 做镜像时需要在麒
  • docker部署简易Prometheus

    注 xff1a 部署前可以先系统的学习一下 xff1a Introduction Prometheus中文技术文档 在之后需要书写自定义告警的 xff0c 需要在学习一下PromQL语言 xff0c 一般网上也能搜到 xff0c 可以在安装
  • k8s面试题-进阶

    1 简述etcd及其特点 etcd是CoreOS团队发起的开源项目 xff0c 是一个管理配置信息和服务发现 xff08 service discovery xff09 的项目 xff0c 它的目标是构建一个高可用的分布式键值 xff08

随机推荐