你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32利用傅里叶反变换进行数字滤波经验分享

[复制链接]
攻城狮Melo 发布时间:2024-5-29 16:51
前面介绍过一期在STM32中进行傅里叶变换的教程,我们成功的对一段信号进行了傅里叶变换,获得其频率谱。
& H4 `) G& a, {% i- P1 e 3B_8}BWR[]ZBFD2U~56EA@W.png
0 Z; b6 E; z" p1 ^3 q% @' H  i
+ g5 J4 O, Y9 t) B' B+ e9 v同样的,我们也同样介绍了双边频谱:FFT的结果是一个双边频谱,他不仅仅包含了实数的频谱也包含了负频率的频谱。4 q. s  x  M' I! G9 R' J+ o+ X
1 A0 f2 E; |5 M* l8 Z( P
我们的采样长度为FFT_Lenth,同样的傅里叶变换的长度也是FFT_Lenth,而由于双边频谱的存在,我们的FFT结果数组长度是2*FFT_Lenth,并且通常直流信号会被统计两次。
8 C) |* g2 S7 f& g- v
3 S+ Z3 h$ g& R6 s
事实上对于我们的时域信号而言,我们采集到的数据仅仅只是实部信号(虚部信号之所以叫做虚部信号也正是因为在复平面上)。" @1 c0 d3 j! H) U$ B

  n* I2 e. m8 x& ^& E1 b6 b
微信图片_20240529165125.png 9 Y( K! l, b# Y  N' Z: d' f9 c( r

  i3 ~7 Q$ B- p$ O% H在大名鼎鼎的火柴人数学中也体现了这一点。- R% |- e5 B  f$ M

. _( w3 H8 F/ B5 |+ s
微信图片_20240529165122.png
5 M$ h2 U: p" }
+ {- G9 P  l/ a) Y
而真正的信号应该是一个在复平面上的合信号,但是对于我们而言虚数轴上并没有什么意义。- f% _  |; a. a: ?* H. u

0 \- J0 J6 _# a" L! c
因此我们在计算FFT的时候也会主动的不向原始信号虚数轴上填充数据。
7 {& B* ]" N' i, _" S
5 y) Z+ F- d1 N4 X' Q. k) C
  1.     for(int i=0; i < FFT_LENGTH; i++)
    " @. E" ~4 k, Q3 c7 \  p( m/ }
  2.     {0 J8 Y% \( ^" L, E+ \
  3.       FFT_InputBuf[2*i]=(ADC_1_Value_DMA )*3.3/4096; //实部
    3 m( {9 q* V9 m  X2 X1 T
  4.       FFT_InputBuf[2*i+1]=0;          //虚部
    : K9 p# O0 N9 O
  5.     }
复制代码
' o0 h6 f& E2 l- q1 {  B% o
但是,即便是我们主动的忽略了时域信号中的虚部,但是FFT的结果中依旧包含了负频率的双边频谱  U5 t/ h6 e. C( g" X
/ j9 \7 D0 G3 C: _8 {
微信图片_20240529165119.png
  H/ H: @6 [% [% p, P. \. w/ M0 \3 V
% i1 O$ z' h5 F7 E$ Y因此,当我们利用得到频谱的时候,通常情况下只考虑他的单边频谱,而负频率通常是不考虑的。! {% _/ f! j( I6 h6 o6 \" M7 k3 A6 ]: ~

' R( P' D/ Y, S好了,说了那么多我们还是聊聊我们接下去要干什么,FFT在STM32中的应用有许多文章都在对其进行介绍,但是几乎没有文章有介绍IFFT也就是傅里叶反变换。
) {6 ^7 R8 W9 k! \1 r' M/ X$ a/ e1 b. d  r0 T; C* x  N/ u
也对,通常我们知道的时域信号,我们通过傅里叶变换之后将其转换为频域信号,但是很少有知道频域的情况下对其进行傅里叶反变换,因为首先是应用场合比较少,其次是好像没什么必要。
; ?7 s9 N! B; M- F) M. i- a6 n3 X# U5 {$ _
但是如果我们可以实现傅里叶反变换,那能不能通过对其频率信息的修改,即修改频域的值,实现一种滤波效果。7 Q9 `5 d" `' y+ x3 p1 Z

6 ]+ l/ i, _9 ?1 `" \2 T假如我们的信号采样率为10KHZ即10240,而我们的FFT长度是1024,那么我们的输出数组结果所对应的频率差,即相邻两个数据对应的频率差为10240/1024 = 10HZ
# k+ `  }7 F) w- E) ^  G2 @/ y8 K4 G5 `: x
微信图片_20240529165115.png . f: X8 c1 L- _; c( ?

* \. a. S6 |! m那么例如我们将FFT的结果中前2*X项赋值为0(因为输出的结果中包含了一个实部数据和一个虚部数据)并且FFT_Lenth~FFT_Lenth*2的值均为负频率。) u. w. ~3 |% J# [1 x6 e( a/ J
/ {  ^. K- V( q4 ?5 F# q" J
这样子我们就可以实现一个X*10(频率差)的一个高通滤波器(低频段被删除了),之后我们通过傅里叶反变换实现还原原始信号。
1 }! q* [; M+ f7 s
: h8 r) w9 P& I1 C这里需要注意的是,DSP库中没有给出IFFT的算法,因此我们选用最常见到的累加法求其IFFT的结果。; i; U- i! R+ z0 b" ^* L. P

! @( j( s2 G5 \- g- O! o2 ?) j
  1.     for (int i = 0; i < FFT_LENGTH; i++) {  
    9 z* Z3 w( U( Z: I: |) ~9 ?9 t
  2.     FFT_OutputBuf = 0.0f;   ) H- i- h0 R7 `
  3.     for (int k = 0; k < FFT_LENGTH; k++) {  0 }" s3 v+ ?9 [7 a- o& k
  4.         // 累加复数乘法结果到原始信号  
      v+ f) G. J  C2 z  T5 \
  5.         float32_t phase = -2.0f * 3.1415926 * i * k / FFT_LENGTH; // 计算相位  
    5 r' c5 y8 z7 s8 b
  6.         float32_t real_part = cosf(phase) * FFT_InputBuf[2*k] + sinf(phase) * FFT_InputBuf[k*2+1];  ( s  W4 [8 D2 O! ^/ ]
  7.         //float32_t imag_part = -sinf(phase) * FFT_InputBuf[k*2+0] + cosf(phase) * FFT_InputBuf[k*2+1];虚部信号  
    + V) [9 s, L* ^, f5 Z/ p; A
  8.         FFT_OutputBuf += real_part; // 只取实部累加,因为原始信号是实数  + g6 {* X6 _. x. n, \
  9.     }  
    # Y* S: @4 Q$ t. t
  10.   
    # U8 f- X/ o* |' W
  11. }
复制代码

* Q+ z8 d2 g- n* V4 ?* _& Q: S这里不具体介绍原理,总之我们看看效果。& V! `1 G7 q: P) b3 G
微信图片_20240529165111.jpg ( L& X0 k8 u% K$ F3 h
; Y' _7 e3 W" c% O# M) Z
将信号采集之后经过FFT变换之后再通过IFFT反变换为时域信号。3 `9 b3 K* ~7 W/ y& K
& u& @$ z, H- Y* F- g' T: n
这里我们采集了3KHZ的信号并进行了还原,可以看到并没有什么失真。
5 ~1 g7 ?  j( R  s% U' m. w, g/ `/ q1 y& Z% _+ T
微信图片_20240529165107.png 8 s; A* y% u  w. [0 O6 k- ?% n8 J5 f

! Q  J( _8 s  o1 o" I三角波的还原,可以看到似乎叠加了一个什么信号,但是不是很明显。
) s. M+ k' O' s0 t& E: c, p" j/ o: ~# r
微信图片_20240529165103.png
! X  D8 e, h0 [! ]( |2 `( V
7 \& W' e; j! P/ N. y( M
调制信号的还原,可以看到信号还原度还是非常高的。
; e! g  R- c- c3 P+ s8 R
& p# W2 d) }# f$ A1 D6 b7 O& j7 B- M9 Q
微信图片_20240529165059.png 1 K2 {1 d/ r( X' B; `+ f% N
" ]6 o) @/ V/ }' S) s
两个正弦波,100HZ+500HZ的累加信号,可以看到其还原度也是非常高的。
0 q2 \# U, z# o
- n$ K$ o0 J. X4 a在这里我们应用一下我们之前的方法,将某个频段的信号去除。
* a8 d! B8 ?" j; _& m/ r9 a+ h* P( k/ A5 n6 l4 H+ F8 j
微信图片_20240529165056.png
2 e) A: }# w  O: Y8 H' {) M8 I9 m) V

6 K. R, H  N' n; e  g可以看到,我们非常轻松的从500HZ的信号中提取到了100HZ的信号。8 s4 F0 [0 b. U3 i* |. {. R

8 G: a8 q- M; A+ D  z$ m% B5 D
微信图片_20240529165053.png " _5 s- ~; ~9 K; H$ Y1 ?
: @+ x+ G" R0 {4 ]0 _: H* n
方波中提取其基波频率。
6 m+ H0 G) I. {/ y4 e- G( t; d2 b1 H% y* E  L0 N  q$ y
微信图片_20240529165050.jpg / ~( {% ~# ?' n8 x/ p2 A! ]

) d1 A9 K) E1 r7 S# L以及还有方波信号的 还原。& y# I* U0 \3 O# q
6 J, \# B1 }; M3 x
并且这个方法 的滤波精度相当之高。; A4 D' D, R) w- o' I/ H& a6 S+ E
5 @) D/ \7 U  C9 }. W2 X
微信图片_20240529165043.jpg & F5 p+ Z+ u) t; x
4 v2 m- w+ o( N6 T* O
从一个900HZ叠加1000HZ的信号中将1000HZ的分量去掉。
2 N/ J7 T- k" \6 H& ~
4 B  s" V* _, f! m" ]% c3 H0 g$ S. Y  X) ~
转载自:电路小白
+ L8 A! d# m6 [2 z如有侵权请联系删除
4 L3 ^, c; i% ^6 ~1 H1 E! n0 k/ V8 z; s; u
赞 收藏 评论0 发布时间:2024-5-29 16:51

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版