数字滤波算法(一)——滑动平均滤波算法

2023-11-13

一、数字滤波器简介

数字滤波器是指通过一定的数据逻辑构成的可以滤除输入信号中的特定的噪声的算法,这里所指的数字滤波器主要包括平均值滤波、FIR滤波、CIC滤波等,在之后的实验中,我们将介绍不同数字滤波器的原理,通过MATLAB和FPGA分别实现不同数字滤波器,为之后工程中的应用打下基础。

二、滑动平均滤波

2.1 滑动平均滤波原理

若输入采样点的个数为N个,假设采用8倍的滑动平均滤波,其滑动平均滤波的原理如下:

  1. 滤波器输出的第一个数据在8个采样周期之后,即首先对输入的8个数据进行平均,平均结果为x_0=(x0+x1+…+x7)/8
  2. 8个周期之后即可以实现数据的滑动输入,并且滤波器输出为x_i=((7*x_i-1)+xi+7)/8 , i=1,2……

2.2 MATLAB实现

%%N倍滑动滤波算法
clear;
clc;
 
%数据输入
fileID = fopen('gnd_ch3.txt');
data = textscan(fileID,'%s');
data = data{1,1};
k = 1;
for i = 1 : length(data)-11
    if strcmp(data(i),'61') && strcmp(data(i+1),'64')
        Ain(k) = (((hex2dec(strcat(data(i+5),data(i+6),data(i+7)))*20/2^24)-10)*1e6)/50;
        k = k + 1;
    end
end
 
%变量定义
N = 8;%滑动滤波倍数
M = length(Ain);%输入数据个数
INIT_NUM = 0;%初始数据和
INIT_AVE = 0;%初始数据均值
NUM = 0;%数据和
AVE = 0;%数据均值
Aout = zeros(1,M);%数据输出
 
%初始均值
%求初始和
for i = 1:1:N-1
    INIT_NUM = INIT_NUM + Ain(1,i); 
end
%求初始均值
INIT_AVE = INIT_NUM / N;
Aout(1,N) = INIT_AVE;
AVE = INIT_AVE;
 
%滑动均值
for i = 1:1:M-N
    NUM = (AVE * (N-1)) + Ain(1,i + N);
    AVE = NUM / N;
    Aout(1,i + N) = AVE;
end
 
figure
plot(Ain(N+100:M));
hold on;
plot(Aout(N+100:M));

绘图结果:

8倍滑动滤波

 

16倍滑动滤波

 

64倍滑动滤波

 

2.3 FPGA实现

1. 代码实现参考Move_Mean_filter工程

`timescale 1ns / 1ps
/******************************************************************************************************
**Author	   :CKM
**E-mail       :15594951527@163.com
**Times		   :2022/4/10
**Editor       :vs_code/notepad++
**EDATools     :vivado 2017.4
**Module_name  :move_mean_filter
**Functions    :实现输入数据DATA_NUM位,MUL_NUM倍滑动滤波算法
*******************************************************************************************************/

module move_mean_filter#(
    parameter                                    DATA_NUM = 24              ,//数据位宽
    parameter                                    MUL_NUM  = 8               ,//滑动倍数
    parameter                                    MOV_NUM  = 3                 
    )(          
    input                                         clk_i                      ,
    input                                         rst_n                      ,
    input         [DATA_NUM-1            : 0]     Ain                        , 
    output  reg   [DATA_NUM-1            : 0]     Aout                        
    );          

/*---------------------------------------------常量定义------------------------------------------------*/
    localparam                                    IDLE      =  6'b000_001    ;//空闲状态
    localparam                                    INIT_NUM  =  6'b000_010    ;//初始化赋值状态
    localparam                                    INIT_MEAN =  6'b000_100    ;//初始化赋值缓冲状态
    localparam                                    NUM       =  6'b001_000    ;//滑动滤波状态
    localparam                                    NUM_BUFF  =  6'b010_000    ;//滑动滤波缓冲状态
    localparam                                    MEAN      =  6'b100_000    ;//等待状态

/*---------------------------------------------变量定义------------------------------------------------*/
    reg       [ 5                    : 0]         current_state              ;//现态
    reg       [ 5                    : 0]         next_state                 ;//次态
    reg       [DATA_NUM - 1          : 0]         Ain_temp1                  ;//输入数据缓冲1 
    reg       [DATA_NUM - 1          : 0]         Ain_temp2                  ;//输入数据缓冲2 
    reg       [31                    : 0]         init_cnt                   ;//初始化计数器
    reg       [ 7                    : 0]         buffer_cnt                 ;//初始化计数器
    reg       [47                    : 0]         init_num                   ;//初始化数据和
    reg       [47                    : 0]         num                        ;//数据和
    reg       [24                    : 0]         A                          ;
    reg       [ 7                    : 0]         B                          ;
    reg       [24                    : 0]         C                          ;
    wire      [47                    : 0]         P                          ;
    wire      [47                    : 0]         PCOUT                      ;

/*---------------------------------------------程序开始------------------------------------------------*/
    //输入数据缓冲
    always @(posedge clk_i or negedge rst_n) begin
        if(!rst_n)begin
            Ain_temp1 <= 0;
            Ain_temp2 <= 0;
        end
        else begin
            Ain_temp1 <= Ain;
            Ain_temp2 <= Ain_temp1;
        end
    end

    //滑动滤波算法
    //1.状态确定
    always @(posedge clk_i or negedge rst_n) begin
        if(!rst_n)begin
            current_state <= 0;
        end
        else begin
            current_state <= next_state;
        end
    end
    //2.状态切换
    always @(*)begin
        if(!rst_n)begin
            next_state <= IDLE;
        end
        else begin
            case(current_state)
                IDLE     :begin 
                    if(Ain_temp2 != Ain_temp1)begin
                        next_state <= INIT_NUM;
                    end
                    else begin
                        next_state <= IDLE;
                    end
                end
                INIT_NUM  :begin
                    if(init_cnt == MUL_NUM)begin
                        next_state <= INIT_MEAN;
                    end
                    else begin
                        next_state <= INIT_NUM;
                    end
                end
                INIT_MEAN:begin 
                    next_state <= NUM;
                end
                NUM     :begin 
                    if(Ain_temp2 != Ain_temp1)begin
                        next_state <= NUM_BUFF;
                    end
                    else begin
                        next_state <= NUM;
                    end
                end
                NUM_BUFF:begin 
                    next_state <= MEAN;
                end
                MEAN     :begin 
                    next_state <= NUM;
                end
                default  :begin end
            endcase
        end
    end
    //3.各状态逻辑
    always @(posedge clk_i or negedge rst_n) begin
        if(!rst_n)begin
            init_cnt   <= 0;
            buffer_cnt <= 0;
            init_num   <= 0;
            num        <= 0;
            Aout       <= 0;
            A          <= 0;
            B          <= 0;
            C          <= 0;
        end
        else begin
            case(next_state)
                IDLE     :begin
                    init_cnt   <= 0;
                    buffer_cnt <= 0;
                    if(Ain_temp2 != Ain_temp1)begin 
                        init_num   <= Ain;
                    end
                    else begin
                        init_num   <= init_num;
                    end
                    num        <= 0;
                    Aout       <= Ain;
                    A          <= 0;
                    B          <= 0;
                    C          <= 0;
                end
                INIT_NUM     :begin
                    if(Ain_temp2 != Ain_temp1)begin 
                        init_cnt   <= init_cnt + 1;
                        init_num   <= init_num + Ain;
                    end
                    else begin
                        init_cnt   <= init_cnt;
                        init_num   <= init_num;
                    end
                    buffer_cnt <= 0;
                    num        <= 0;
                    Aout       <= Aout;
                    A          <= 0;
                    B          <= 0;
                    C          <= 0;
                end
                INIT_MEAN:begin 
                    init_cnt   <= init_cnt;
                    buffer_cnt <= 0;
                    init_num   <= init_num;
                    num        <= 0;
                    if(init_cnt == MUL_NUM)begin
                        Aout <= init_num >> MOV_NUM;
                    end
                    else begin
                        Aout <= Aout;
                    end
                    A          <= 0;
                    B          <= 0;
                    C          <= 0;
                end
                NUM      :begin 
                    init_cnt   <= init_cnt;
                    buffer_cnt <= 0;
                    init_num   <= init_num;
                    num        <= num;
                    Aout       <= Aout;
                    A <= Aout;
                    B <= MUL_NUM - 1;
                    C <= Ain;
                end
                NUM_BUFF :begin 
                    init_cnt   <= init_cnt;
                    buffer_cnt <= buffer_cnt + 1;
                    init_num   <= init_num;
                    num <= P;   
                    Aout <= Aout;     
                    A <= A;
                    B <= B;
                    C <= C;
                end
                MEAN     :begin 
                    init_cnt   <= init_cnt;
                    buffer_cnt <= 0;
                    init_num   <= init_num;
                    num <= num;
                    Aout<= num >> MOV_NUM;
                    A <= A;
                    B <= B;
                    C <= C;
                end
                default  :begin end
            endcase
        end
    end
    
    //乘加器例化
    xbip_multadd_0 your_instance_name (
    .CLK            (clk_i      )       ,// input wire CLK
    .CE             (1'b1       )       ,// input wire CE      
    .SCLR           (1'b0       )       ,// input wire SCLR
    .A              (A          )       ,// input wire [23 : 0] A
    .B              (B          )       ,// input wire [7 : 0] B
    .C              (C          )       ,// input wire [23 : 0] C
    .SUBTRACT       (1'b0       )       ,// input wire SUBTRACT
    .P              (P          )       ,// output wire [47 : 0] P
    .PCOUT          (PCOUT      )        // output wire [47 : 0] PCOUT
    );

endmodule

2. 功能仿真结果:

(1)4倍滑动滤波

 

 

(2)8倍滑动滤波

(3)16倍滑动滤波

3. 将该滑动滤波模块应用于AD7734数据采集,AD7734采集到的数据进行滑动平均滤波,测试该算法与理论分析是否一致

(1)64倍滑动滤波效果

在线抓取信号

将串口接收到的数据利用matlab画图得

(2)16倍滑动滤波效果

在线抓取信号

将串口接收到的数据利用matlab画图得

(3)8倍滑动滤波效果

在线抓取信号

将串口接收到的数据利用matlab画图得

       通过以上的实验可以看出,虽然滑动平均滤波的算法十分简单,但是以上的实验可以充分的理解了该算法的内涵与实现。滑动滤波倍数设置的越小,滤波效果越不好,但反应信号变化的实时性却很好;滑动滤波倍数设置的越大,滤波效果越很好,但反应信号变化的实时性变差。因此在实际应用中,如要用到该算法,需要权衡滤波效果和信号实时性这两个对立的性能,从而选择最优的滑动滤波倍数。

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

数字滤波算法(一)——滑动平均滤波算法 的相关文章

  • Android Alarm闹钟API使用心得

    前言 有什么办法可以在不打开App的时候 也能够触发一些操作呢 比如说发送通知 解决这个需求的办法有很多种选择 比如说官方推荐的WorkManager API 可以在后台执行一次性 耗时 定时的任务 但WorkManager是严格遵循电池优

随机推荐

  • MySQL配置了主从,重启步骤

    停应用 gt 停数据库 先备后主 gt 启数据库 先主后备 gt 启应用 关闭MySQL从库 在从库操作 a 先查看当前的主从同步状态 show slave status G 看是否双yes b 执行stop slave c 停止从库服务
  • CUDA与已有的VS项目结合

    先新建一个简单的控制台应用程序 项目名称为Test00301 如下图所示 然后在项目中新建一个名为Test01 cu文件 如下图所示 然后在解决方案资源管理器中选择该项目并点击右键 在弹出的菜单中选择 生成自定义 如下图所示 在弹出的 Vi
  • 关于Selenium WebDriver的geckodriver

    Selenium作为网站UI测试利器 为黑盒功能测试人员所喜爱 下载Selenium的最新版本地址 http selenium release storage googleapis com index html 友情提示 如果一直下载不了
  • 【IDEA】windows、mac下IDEA下载的驱动包在哪

    1 概述 因为我们是内外网分离的 内网不连接网络 因此在内网的IDEA下载驱动包的的时候 遇到问题 然后因为不知道需要什么样的驱动包 然后就先在外网找了一下 然后在拷贝到内网 打算这么做 mac 下 System Volumes Data
  • flutter混编ios打包生成ipa文件

    项目场景 flutter集成到原有ios项目上 将项目打包生成ipa文件 在通过爱思助手或者分发服务器分发安装 解决方案 1 在flutter module项目路径下 通过以下命令打包 其中 no codesign表示不使用证书签名 后续会
  • AvalonJs入门二 复选框全选反选+layui分页

    前言 今天给大家带来初识Avalon的第二篇文章 复选框的全选操作和Avalon layUI的分页 Demo1 神奇的全选反选 Avalon的双工绑定duplex和监听事件 watch 第一篇文章的第一个例子大家是否还记得 文本框输入什么内
  • Vue.js之事件的绑定(v-on: 或者 @ )

    1 Vue js事件绑定的一般格式 v on click function v on click mouseout mouseover click 2 Vue js事件绑定的实现 2 1 JavaScript代码
  • STM32 使用HAL库实现微秒级长延时

    STM32 使用HAL库实现微秒级长延时 背景 定时器初始化 主程序中的设计 背景 STM32 HAL库中有一个延时函数HAL Delay 可以实现毫秒级的延时 能够满足一般延时需求 在有些场合下 我们需要更精准的延时 同时可能会有较长时间
  • 智慧校园小程序-微信小程序毕业设计(附下载链接)

    2023年微信小程序毕业设计 智慧校园 点我下载项目资源 智慧校园小程序 校园是一个充满创造力和活力的地方 教育和互联网发展向纵深发展 智慧校园小程序开发是当前校园建设中不可或缺的互联网工具 通过智慧校园小程序 可以整合更多的校园服务基础设
  • 2022年油价的暴涨让你意识到了什么?

    2022年才刚刚开始 油价便以迅雷不及掩耳之势快速上涨几次 从本月3月3日24时起 油价上升之窗开启 从全国来看 92号汽油每升上涨0 2元 95号汽油每升上涨0 22元 0号柴油也不甘落后也每升上涨0 22元 而近几天国际原油价格上升幅度
  • 【目标检测】33、AutoAssign:Differentiable Label Assignment for Dense Object Detection

    文章目录 一 背景 二 方法 2 1 Prior level Center Weighting 2 2 Instance level Confidence Weighting 2 3 Loss 三 效果 论文 AutoAssign Diff
  • Oracle 10g RAC Dataguard Faileover

    环境 1 Oracle 10g RAC Oracle 10g RAC Dataguard最大性能模式配置 2 rac1 rac2 Primary Database 3 vmrac1 vmrac2 Physical Standby Datab
  • C语言课设学生籍贯信息记录簿(大作业)

    一 任务概述 文章仅供参考 进一步掌握和利用C语言进行课程设计的能力 进一步理解和运用结构化程序设计的思想和方法 初步掌握开发一个小型实用系统的基本方法 二 设计功能 1 创建信息链表并以磁盘文件保存 2 读取磁盘文件并显示输出所有学生的籍
  • alibaba druid数据库连接池详解

    1 介绍 Druid连接池是阿里巴巴开源的数据库连接池项目 Druid连接池为监控而生 内置强大的监控功能 监控特性不影响性能 功能强大 能防SQL注入 内置Loging能诊断Hack应用行为 2 下载 git地址 https github
  • 漏洞信息收集之——指纹识别

    指纹识别 目录 指纹识别 目的 常见指纹检测的对象 常见指纹识别方式 1 特定文件的MD5 2 正常页面或错误网页中包含的关键字 3 请求头信息的关键字匹配 4 部分URL中包含的关键字 比如wp includes dede等URL关键特征
  • luci 开发中一些小总结

    一 只保存不应用 当修改或者增加一项配置后 如果不是点击 保存 应用 按钮 而是点击 保存 按钮 这些配置不会保存各个到配置文件中 而是暂时保存到如下临时目录下 tmp uci 例如 当修改了网络配置 没有应用时 会生成一个 tmp uci
  • vue-quill-editor富文本编辑器多个音频上传显示覆盖问题

    新建的时候没有问题 正常提交 修改时候后台传过来的数据正确 但是渲染会导致前一个audio被后面一个覆盖掉 刷新audio标签就没有了 1 覆盖问题 将代码 that refs editRef content data content 改成
  • vue拖拽实现app或小程序装修界面

    vue拖拽实现app或小程序装修 一 最终效果图 参考引用作者 作者 李白不吃茶v 原作者源代码git地址 大神的源代码 这里是引用 二 需要安装的依赖 安装 vuedraggable 语法 npm install vuedraggable
  • 对于poll的总结

    参考书籍 linux高性能服务器编程 是个人对看书的总结 上文一致 poll系统调用和select类似 个人认为poll和select掌握一个就好了 也是在指定时间内轮询一定数量的文件描述符 以测试其中是否有就绪者 关于poll的原型 in
  • 数字滤波算法(一)——滑动平均滤波算法

    一 数字滤波器简介 数字滤波器是指通过一定的数据逻辑构成的可以滤除输入信号中的特定的噪声的算法 这里所指的数字滤波器主要包括平均值滤波 FIR滤波 CIC滤波等 在之后的实验中 我们将介绍不同数字滤波器的原理 通过MATLAB和FPGA分别