打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

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

一、数字滤波器简介

数字滤波器是指通过一定的数据逻辑构成的可以滤除输入信号中的特定的噪声的算法,这里所指的数字滤波器主要包括平均值滤波、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实现

  1. %%N倍滑动滤波算法
  2. clear;
  3. clc;
  4. %数据输入
  5. fileID = fopen('gnd_ch3.txt');
  6. data = textscan(fileID,'%s');
  7. data = data{1,1};
  8. k = 1;
  9. for i = 1 : length(data)-11
  10. if strcmp(data(i),'61') && strcmp(data(i+1),'64')
  11. Ain(k) = (((hex2dec(strcat(data(i+5),data(i+6),data(i+7)))*20/2^24)-10)*1e6)/50;
  12. k = k + 1;
  13. end
  14. end
  15. %变量定义
  16. N = 8;%滑动滤波倍数
  17. M = length(Ain);%输入数据个数
  18. INIT_NUM = 0;%初始数据和
  19. INIT_AVE = 0;%初始数据均值
  20. NUM = 0;%数据和
  21. AVE = 0;%数据均值
  22. Aout = zeros(1,M);%数据输出
  23. %初始均值
  24. %求初始和
  25. for i = 1:1:N-1
  26. INIT_NUM = INIT_NUM + Ain(1,i);
  27. end
  28. %求初始均值
  29. INIT_AVE = INIT_NUM / N;
  30. Aout(1,N) = INIT_AVE;
  31. AVE = INIT_AVE;
  32. %滑动均值
  33. for i = 1:1:M-N
  34. NUM = (AVE * (N-1)) + Ain(1,i + N);
  35. AVE = NUM / N;
  36. Aout(1,i + N) = AVE;
  37. end
  38. figure
  39. plot(Ain(N+100:M));
  40. hold on;
  41. plot(Aout(N+100:M));

绘图结果:

8倍滑动滤波

 

16倍滑动滤波

 

64倍滑动滤波

 

2.3 FPGA实现

1. 代码实现参考Move_Mean_filter工程

  1. `timescale 1ns / 1ps
  2. /******************************************************************************************************
  3. **Author :CKM
  4. **E-mail :15594951527@163.com
  5. **Times :2022/4/10
  6. **Editor :vs_code/notepad++
  7. **EDATools :vivado 2017.4
  8. **Module_name :move_mean_filter
  9. **Functions :实现输入数据DATA_NUM位,MUL_NUM倍滑动滤波算法
  10. *******************************************************************************************************/
  11. module move_mean_filter#(
  12. parameter DATA_NUM = 24 ,//数据位宽
  13. parameter MUL_NUM = 8 ,//滑动倍数
  14. parameter MOV_NUM = 3
  15. )(
  16. input clk_i ,
  17. input rst_n ,
  18. input [DATA_NUM-1 : 0] Ain ,
  19. output reg [DATA_NUM-1 : 0] Aout
  20. );
  21. /*---------------------------------------------常量定义------------------------------------------------*/
  22. localparam IDLE = 6'b000_001 ;//空闲状态
  23. localparam INIT_NUM = 6'b000_010 ;//初始化赋值状态
  24. localparam INIT_MEAN = 6'b000_100 ;//初始化赋值缓冲状态
  25. localparam NUM = 6'b001_000 ;//滑动滤波状态
  26. localparam NUM_BUFF = 6'b010_000 ;//滑动滤波缓冲状态
  27. localparam MEAN = 6'b100_000 ;//等待状态
  28. /*---------------------------------------------变量定义------------------------------------------------*/
  29. reg [ 5 : 0] current_state ;//现态
  30. reg [ 5 : 0] next_state ;//次态
  31. reg [DATA_NUM - 1 : 0] Ain_temp1 ;//输入数据缓冲1
  32. reg [DATA_NUM - 1 : 0] Ain_temp2 ;//输入数据缓冲2
  33. reg [31 : 0] init_cnt ;//初始化计数器
  34. reg [ 7 : 0] buffer_cnt ;//初始化计数器
  35. reg [47 : 0] init_num ;//初始化数据和
  36. reg [47 : 0] num ;//数据和
  37. reg [24 : 0] A ;
  38. reg [ 7 : 0] B ;
  39. reg [24 : 0] C ;
  40. wire [47 : 0] P ;
  41. wire [47 : 0] PCOUT ;
  42. /*---------------------------------------------程序开始------------------------------------------------*/
  43. //输入数据缓冲
  44. always @(posedge clk_i or negedge rst_n) begin
  45. if(!rst_n)begin
  46. Ain_temp1 <= 0;
  47. Ain_temp2 <= 0;
  48. end
  49. else begin
  50. Ain_temp1 <= Ain;
  51. Ain_temp2 <= Ain_temp1;
  52. end
  53. end
  54. //滑动滤波算法
  55. //1.状态确定
  56. always @(posedge clk_i or negedge rst_n) begin
  57. if(!rst_n)begin
  58. current_state <= 0;
  59. end
  60. else begin
  61. current_state <= next_state;
  62. end
  63. end
  64. //2.状态切换
  65. always @(*)begin
  66. if(!rst_n)begin
  67. next_state <= IDLE;
  68. end
  69. else begin
  70. case(current_state)
  71. IDLE :begin
  72. if(Ain_temp2 != Ain_temp1)begin
  73. next_state <= INIT_NUM;
  74. end
  75. else begin
  76. next_state <= IDLE;
  77. end
  78. end
  79. INIT_NUM :begin
  80. if(init_cnt == MUL_NUM)begin
  81. next_state <= INIT_MEAN;
  82. end
  83. else begin
  84. next_state <= INIT_NUM;
  85. end
  86. end
  87. INIT_MEAN:begin
  88. next_state <= NUM;
  89. end
  90. NUM :begin
  91. if(Ain_temp2 != Ain_temp1)begin
  92. next_state <= NUM_BUFF;
  93. end
  94. else begin
  95. next_state <= NUM;
  96. end
  97. end
  98. NUM_BUFF:begin
  99. next_state <= MEAN;
  100. end
  101. MEAN :begin
  102. next_state <= NUM;
  103. end
  104. default :begin end
  105. endcase
  106. end
  107. end
  108. //3.各状态逻辑
  109. always @(posedge clk_i or negedge rst_n) begin
  110. if(!rst_n)begin
  111. init_cnt <= 0;
  112. buffer_cnt <= 0;
  113. init_num <= 0;
  114. num <= 0;
  115. Aout <= 0;
  116. A <= 0;
  117. B <= 0;
  118. C <= 0;
  119. end
  120. else begin
  121. case(next_state)
  122. IDLE :begin
  123. init_cnt <= 0;
  124. buffer_cnt <= 0;
  125. if(Ain_temp2 != Ain_temp1)begin
  126. init_num <= Ain;
  127. end
  128. else begin
  129. init_num <= init_num;
  130. end
  131. num <= 0;
  132. Aout <= Ain;
  133. A <= 0;
  134. B <= 0;
  135. C <= 0;
  136. end
  137. INIT_NUM :begin
  138. if(Ain_temp2 != Ain_temp1)begin
  139. init_cnt <= init_cnt + 1;
  140. init_num <= init_num + Ain;
  141. end
  142. else begin
  143. init_cnt <= init_cnt;
  144. init_num <= init_num;
  145. end
  146. buffer_cnt <= 0;
  147. num <= 0;
  148. Aout <= Aout;
  149. A <= 0;
  150. B <= 0;
  151. C <= 0;
  152. end
  153. INIT_MEAN:begin
  154. init_cnt <= init_cnt;
  155. buffer_cnt <= 0;
  156. init_num <= init_num;
  157. num <= 0;
  158. if(init_cnt == MUL_NUM)begin
  159. Aout <= init_num >> MOV_NUM;
  160. end
  161. else begin
  162. Aout <= Aout;
  163. end
  164. A <= 0;
  165. B <= 0;
  166. C <= 0;
  167. end
  168. NUM :begin
  169. init_cnt <= init_cnt;
  170. buffer_cnt <= 0;
  171. init_num <= init_num;
  172. num <= num;
  173. Aout <= Aout;
  174. A <= Aout;
  175. B <= MUL_NUM - 1;
  176. C <= Ain;
  177. end
  178. NUM_BUFF :begin
  179. init_cnt <= init_cnt;
  180. buffer_cnt <= buffer_cnt + 1;
  181. init_num <= init_num;
  182. num <= P;
  183. Aout <= Aout;
  184. A <= A;
  185. B <= B;
  186. C <= C;
  187. end
  188. MEAN :begin
  189. init_cnt <= init_cnt;
  190. buffer_cnt <= 0;
  191. init_num <= init_num;
  192. num <= num;
  193. Aout<= num >> MOV_NUM;
  194. A <= A;
  195. B <= B;
  196. C <= C;
  197. end
  198. default :begin end
  199. endcase
  200. end
  201. end
  202. //乘加器例化
  203. xbip_multadd_0 your_instance_name (
  204. .CLK (clk_i ) ,// input wire CLK
  205. .CE (1'b1 ) ,// input wire CE
  206. .SCLR (1'b0 ) ,// input wire SCLR
  207. .A (A ) ,// input wire [23 : 0] A
  208. .B (B ) ,// input wire [7 : 0] B
  209. .C (C ) ,// input wire [23 : 0] C
  210. .SUBTRACT (1'b0 ) ,// input wire SUBTRACT
  211. .P (P ) ,// output wire [47 : 0] P
  212. .PCOUT (PCOUT ) // output wire [47 : 0] PCOUT
  213. );
  214. endmodule

2. 功能仿真结果:

(1)4倍滑动滤波

 

 

(2)8倍滑动滤波

(3)16倍滑动滤波

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

(1)64倍滑动滤波效果

在线抓取信号

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

(2)16倍滑动滤波效果

在线抓取信号

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

(3)8倍滑动滤波效果

在线抓取信号

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

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

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
EEMD算法原理与实现
基于FPGA器件EP1C6Q240C8实现运动控制卡的应用方案
常用数据挖掘算法从入门到精通 第二章 K
K-Means算法
R语言从入门到精通:Day15(聚类分析)
K均值聚类算法:数据聚类的常用技术
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服