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

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

[复制链接]
攻城狮Melo 发布时间:2024-5-29 16:51
前面介绍过一期在STM32中进行傅里叶变换的教程,我们成功的对一段信号进行了傅里叶变换,获得其频率谱。
( S( A/ D& m  l, x 3B_8}BWR[]ZBFD2U~56EA@W.png 1 J6 x; L" ^% E7 Y0 i, ?. }! }1 _

/ z  @& [- E& G6 k* B同样的,我们也同样介绍了双边频谱:FFT的结果是一个双边频谱,他不仅仅包含了实数的频谱也包含了负频率的频谱。3 ^- y* s! g6 _! X1 N" l; T
) t6 Y- {! c6 R+ \( L2 W
我们的采样长度为FFT_Lenth,同样的傅里叶变换的长度也是FFT_Lenth,而由于双边频谱的存在,我们的FFT结果数组长度是2*FFT_Lenth,并且通常直流信号会被统计两次。; _4 U( g0 R; J- Y1 n# w! l1 y0 S
9 X4 [- O% G+ u' I5 v. \& H
事实上对于我们的时域信号而言,我们采集到的数据仅仅只是实部信号(虚部信号之所以叫做虚部信号也正是因为在复平面上)。
6 h6 _) L) r$ K+ v$ d: n0 E$ v* U% J. o4 u( G' @
微信图片_20240529165125.png
% ?8 d0 [/ a9 M0 p1 K9 ~: I
+ \4 }/ M! e( D( Q
在大名鼎鼎的火柴人数学中也体现了这一点。
. _0 ?1 O0 ^8 n4 C+ Z  E( P  d5 \, T
微信图片_20240529165122.png
7 O' h. r. `( K
8 y5 H: D8 |$ O6 }0 f# L
而真正的信号应该是一个在复平面上的合信号,但是对于我们而言虚数轴上并没有什么意义。" q) u+ s, I" N4 i# W" J' f, X' R

5 ?9 R0 O6 _3 g- ^
因此我们在计算FFT的时候也会主动的不向原始信号虚数轴上填充数据。
! E5 z& d0 `0 q  i
* X( ~3 A* w! a
  1.     for(int i=0; i < FFT_LENGTH; i++)
    ) C# D( h* y% x3 t! a
  2.     {8 m, Y# l. J; u5 Y* [8 u
  3.       FFT_InputBuf[2*i]=(ADC_1_Value_DMA )*3.3/4096; //实部
    % p( l6 H6 c% l# S
  4.       FFT_InputBuf[2*i+1]=0;          //虚部' B3 [$ f: U) i3 ?$ ?6 ~4 U$ n6 a1 r
  5.     }
复制代码
2 A: Q- L% a8 t9 t
但是,即便是我们主动的忽略了时域信号中的虚部,但是FFT的结果中依旧包含了负频率的双边频谱
' L% V3 K; w! D; S0 b$ T" ?9 S" p0 t8 o/ `
微信图片_20240529165119.png
5 W! _( `( K/ G0 s# O( F( O# n8 w( t! B0 l: K
因此,当我们利用得到频谱的时候,通常情况下只考虑他的单边频谱,而负频率通常是不考虑的。& H, Y( m; o, S- c; i5 H  Q
3 ~; `+ `0 ~5 ]0 x' V: T. B* S
好了,说了那么多我们还是聊聊我们接下去要干什么,FFT在STM32中的应用有许多文章都在对其进行介绍,但是几乎没有文章有介绍IFFT也就是傅里叶反变换。
+ T8 L' s3 G  K7 H7 F7 u. ]( w* C8 g% s# g2 `
也对,通常我们知道的时域信号,我们通过傅里叶变换之后将其转换为频域信号,但是很少有知道频域的情况下对其进行傅里叶反变换,因为首先是应用场合比较少,其次是好像没什么必要。
( q0 B1 y3 P/ _; s" M
% {7 a9 f7 V  O* j) N# k' z8 N但是如果我们可以实现傅里叶反变换,那能不能通过对其频率信息的修改,即修改频域的值,实现一种滤波效果。
8 e. _) D  F. W: Y2 J6 L8 K6 r" C& o9 x1 D6 i2 u( \
假如我们的信号采样率为10KHZ即10240,而我们的FFT长度是1024,那么我们的输出数组结果所对应的频率差,即相邻两个数据对应的频率差为10240/1024 = 10HZ6 g) Q8 K* e* S+ f9 m5 d
7 B. t. R6 L; O, Q: g
微信图片_20240529165115.png 9 A( i. c* \; @# W! W) z% p  E/ S

5 V5 [3 g9 j9 _8 @" @那么例如我们将FFT的结果中前2*X项赋值为0(因为输出的结果中包含了一个实部数据和一个虚部数据)并且FFT_Lenth~FFT_Lenth*2的值均为负频率。
/ U+ z, G3 X1 A6 @, X' w; w
! ]  M( r0 {: p0 r这样子我们就可以实现一个X*10(频率差)的一个高通滤波器(低频段被删除了),之后我们通过傅里叶反变换实现还原原始信号。
. I" h% d/ T4 H  M1 L% Y5 T0 h& g8 H, N
这里需要注意的是,DSP库中没有给出IFFT的算法,因此我们选用最常见到的累加法求其IFFT的结果。
# H; d, Q& R3 v- W" k1 W' t3 u' v! ]
  1.     for (int i = 0; i < FFT_LENGTH; i++) {  
    # G7 k) c3 l5 Z/ b- Z
  2.     FFT_OutputBuf = 0.0f;   
    : Z! X5 L" H. g$ v! |: s" F  h7 A
  3.     for (int k = 0; k < FFT_LENGTH; k++) {  
    * Z. Y; N9 m" p* W, d
  4.         // 累加复数乘法结果到原始信号  & f2 K* j( U$ B; e2 _/ [5 `- Z
  5.         float32_t phase = -2.0f * 3.1415926 * i * k / FFT_LENGTH; // 计算相位  2 u, K2 a2 G: i' a" [/ B1 l
  6.         float32_t real_part = cosf(phase) * FFT_InputBuf[2*k] + sinf(phase) * FFT_InputBuf[k*2+1];  
    + ~: k5 B  a. \2 g, s0 F# }- p- l
  7.         //float32_t imag_part = -sinf(phase) * FFT_InputBuf[k*2+0] + cosf(phase) * FFT_InputBuf[k*2+1];虚部信号  
    + S8 M8 V" c2 }, _, y  I% a% B
  8.         FFT_OutputBuf += real_part; // 只取实部累加,因为原始信号是实数  
    $ Z( u  f5 E; h  ?. ]5 O6 c( T& K
  9.     }  
    ( ^2 S$ O& ?$ x% z) O' k
  10.   
    * }0 h% q: l4 o; m& r% ?2 t
  11. }
复制代码

! f. ]5 \' Q; Z这里不具体介绍原理,总之我们看看效果。' x% h& i4 D% u) O% Q
微信图片_20240529165111.jpg . ?) R; `6 }5 Y. h: p- }$ t

& r$ f) d1 H4 |- Q9 s+ r% k将信号采集之后经过FFT变换之后再通过IFFT反变换为时域信号。% v/ p7 z5 W6 I! ~9 e2 c
3 \! i5 o8 y/ ]/ ^' y+ e) U  U. k
这里我们采集了3KHZ的信号并进行了还原,可以看到并没有什么失真。4 I/ ]; o% P) A

+ N1 d/ Q! _( H# R' v# e
微信图片_20240529165107.png 2 |7 o3 k: B$ r$ t

% L5 X8 B8 A' ^; [9 F8 v. j% G4 g三角波的还原,可以看到似乎叠加了一个什么信号,但是不是很明显。# w" ~/ |9 w) N9 R6 ^+ Q

# n# z! M/ ~: e6 }4 c  E& E$ [" P. `
微信图片_20240529165103.png
3 ^, A" P7 j# a, ?
( ?  p- k' }) \% A- D
调制信号的还原,可以看到信号还原度还是非常高的。  }- J9 R1 B! E4 c

' s- _% G' M9 e
微信图片_20240529165059.png
' V/ A) c' Z. f. V
* K% `/ k" {$ X' Y
两个正弦波,100HZ+500HZ的累加信号,可以看到其还原度也是非常高的。$ b# r( E  ]4 I7 r- \; c

8 F  |% R. }2 J: S5 a: G在这里我们应用一下我们之前的方法,将某个频段的信号去除。) }+ M/ c: u+ T9 F: X2 w% S3 z

* N1 L8 _% V. I" n1 A
微信图片_20240529165056.png
' M1 W; l, D8 C

$ ]7 D; [* W! v可以看到,我们非常轻松的从500HZ的信号中提取到了100HZ的信号。
4 b4 \/ Q* y3 E5 d3 n" T) m# A4 Z% _1 F; V6 b
微信图片_20240529165053.png
; q- l" r0 J1 b) u* L+ x: F9 T* _1 S* X3 M4 j7 V' B
方波中提取其基波频率。
7 X) |8 S/ y/ s' t& K" N4 L9 m' j8 }8 |
微信图片_20240529165050.jpg 1 I/ D% ~6 |2 S+ ]; d% U! d) l: Y7 Q
6 R4 s6 W: W; u) \8 G1 Y
以及还有方波信号的 还原。% a, R4 H+ |9 f& P0 Q5 t! h
; e; N9 ]2 ]7 a) f. U1 Y- y
并且这个方法 的滤波精度相当之高。
% {5 Y3 X2 M5 N: I& y
- |# m7 d- e4 t8 a0 @$ z
微信图片_20240529165043.jpg
) }3 _$ \4 g4 A4 }2 x# M+ p; r) e
从一个900HZ叠加1000HZ的信号中将1000HZ的分量去掉。8 D6 C7 l9 A& ]5 Z4 W. i

9 \8 B' `- Q5 Y. B+ i+ `$ j& L- E" I
1 d1 {0 M2 i) {6 R7 ?/ ~  S转载自:电路小白: O. S6 W& ~2 L+ u% O
如有侵权请联系删除
3 F( v9 k$ F( D- [5 n2 g: K6 b% Z+ c" @7 l
赞 收藏 评论0 发布时间:2024-5-29 16:51

举报

0个回答

所属标签

相似技术帖

官网相关资源

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