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

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

[复制链接]
攻城狮Melo 发布时间:2024-5-29 16:51
前面介绍过一期在STM32中进行傅里叶变换的教程,我们成功的对一段信号进行了傅里叶变换,获得其频率谱。" p5 ~/ I- }# R3 j. N2 f9 N
3B_8}BWR[]ZBFD2U~56EA@W.png ' m+ k4 ~" y4 {4 Z
2 d9 D% o! Q) \+ |, m6 i/ Q" J  X
同样的,我们也同样介绍了双边频谱:FFT的结果是一个双边频谱,他不仅仅包含了实数的频谱也包含了负频率的频谱。; z& Z# l7 [3 J! E# n8 h+ K) ~
1 U9 d' i7 Z$ `
我们的采样长度为FFT_Lenth,同样的傅里叶变换的长度也是FFT_Lenth,而由于双边频谱的存在,我们的FFT结果数组长度是2*FFT_Lenth,并且通常直流信号会被统计两次。
/ W6 P$ F+ X) E3 m% G+ w4 C

, C3 N; S8 [+ ]3 h$ D事实上对于我们的时域信号而言,我们采集到的数据仅仅只是实部信号(虚部信号之所以叫做虚部信号也正是因为在复平面上)。1 p2 d/ U6 V8 P. S# s9 V

! i7 W9 q  U3 V
微信图片_20240529165125.png * L  @) |) e4 w7 t$ P! o5 A
4 t  F7 z9 a$ b  ]  I1 i0 S4 X9 g
在大名鼎鼎的火柴人数学中也体现了这一点。( d" x4 N, @. {$ N5 X' N
! ?4 Q* R9 q- N: }: F; r5 w
微信图片_20240529165122.png * w- Z4 c% D6 [" c$ k; N3 D+ u* N
, O1 E+ |4 W" e7 [  j/ G- D
而真正的信号应该是一个在复平面上的合信号,但是对于我们而言虚数轴上并没有什么意义。" h7 |1 `; Q# p5 \+ J3 _. o
* |2 t+ Z- w* X
因此我们在计算FFT的时候也会主动的不向原始信号虚数轴上填充数据。& g+ n; \. D" T% x8 m# b

/ s6 t' w6 {3 o% G3 k% _1 x
  1.     for(int i=0; i < FFT_LENGTH; i++)
    2 ^5 \5 ?* O3 D; d, W
  2.     {  u5 k+ s5 L( m( T+ I4 J1 v  Y1 m
  3.       FFT_InputBuf[2*i]=(ADC_1_Value_DMA )*3.3/4096; //实部3 \8 l+ |% t  @
  4.       FFT_InputBuf[2*i+1]=0;          //虚部5 n. L& g; y7 S0 d# Q7 t& `
  5.     }
复制代码

0 R, A. v! Q- a. ?* B5 c- n但是,即便是我们主动的忽略了时域信号中的虚部,但是FFT的结果中依旧包含了负频率的双边频谱  q7 S: D" Y+ Q9 T( T8 t, d
& p2 K) b* O" o- _1 L0 v: U+ k/ M
微信图片_20240529165119.png - R# r5 D4 N6 E& `- ~4 ?6 C' y

" A6 T" p* j' [" \7 O# ^5 i6 D因此,当我们利用得到频谱的时候,通常情况下只考虑他的单边频谱,而负频率通常是不考虑的。
' s" t* [1 u' V
" i+ I0 L% k/ m2 z
好了,说了那么多我们还是聊聊我们接下去要干什么,FFT在STM32中的应用有许多文章都在对其进行介绍,但是几乎没有文章有介绍IFFT也就是傅里叶反变换。
$ k6 ~/ a9 y% W) h# W
) n9 N. e% V- Y4 }1 I也对,通常我们知道的时域信号,我们通过傅里叶变换之后将其转换为频域信号,但是很少有知道频域的情况下对其进行傅里叶反变换,因为首先是应用场合比较少,其次是好像没什么必要。
$ R' m+ o* N6 U7 H& x/ J, b/ }
, c5 l6 a$ e2 Y但是如果我们可以实现傅里叶反变换,那能不能通过对其频率信息的修改,即修改频域的值,实现一种滤波效果。
* i( u7 ]* B8 i
- C- W8 t& u% O9 G  L( ]假如我们的信号采样率为10KHZ即10240,而我们的FFT长度是1024,那么我们的输出数组结果所对应的频率差,即相邻两个数据对应的频率差为10240/1024 = 10HZ
  I; [# a* l7 d" O+ ?, `) B3 M7 j3 @' L6 i1 q
微信图片_20240529165115.png
2 p! l: s7 I- y$ s6 m, S3 c

0 L( x$ L! Q2 k那么例如我们将FFT的结果中前2*X项赋值为0(因为输出的结果中包含了一个实部数据和一个虚部数据)并且FFT_Lenth~FFT_Lenth*2的值均为负频率。
- y" k6 u5 u$ z! i6 A2 G8 y
6 l2 S( f) L; N1 e8 O; n0 ]这样子我们就可以实现一个X*10(频率差)的一个高通滤波器(低频段被删除了),之后我们通过傅里叶反变换实现还原原始信号。
5 f3 n7 r- L8 e3 `* {( T5 @6 y# t. a4 e) G1 k' N0 d
这里需要注意的是,DSP库中没有给出IFFT的算法,因此我们选用最常见到的累加法求其IFFT的结果。% P1 q7 r& ]& Q. Y
5 D# Q2 C2 K# _, E6 P& G  ?( v1 T1 S
  1.     for (int i = 0; i < FFT_LENGTH; i++) {  
    + ?% ?! x- y( S$ W& o2 D; }9 d
  2.     FFT_OutputBuf = 0.0f;   9 `+ K) A0 B0 h, a/ T
  3.     for (int k = 0; k < FFT_LENGTH; k++) {  2 p" n( O! k2 o  ]" t
  4.         // 累加复数乘法结果到原始信号  + k$ ~& l4 s9 O3 k8 a
  5.         float32_t phase = -2.0f * 3.1415926 * i * k / FFT_LENGTH; // 计算相位  # @1 y1 y, _! x
  6.         float32_t real_part = cosf(phase) * FFT_InputBuf[2*k] + sinf(phase) * FFT_InputBuf[k*2+1];  
    * T7 V0 K& a/ c) Y$ \' @: A: m
  7.         //float32_t imag_part = -sinf(phase) * FFT_InputBuf[k*2+0] + cosf(phase) * FFT_InputBuf[k*2+1];虚部信号  / x7 r% n3 ]- u# D$ B2 i3 Y7 v
  8.         FFT_OutputBuf += real_part; // 只取实部累加,因为原始信号是实数  
    % l  D0 O& q- [' O
  9.     }  
    3 u3 v% y/ o9 B1 o; E# `
  10.   ! ?; v  x) B1 \  }$ p- _6 h5 S: o
  11. }
复制代码

6 a, t) D5 o8 K! q这里不具体介绍原理,总之我们看看效果。
8 ], X7 I" _. D4 g# k: G. d, Q 微信图片_20240529165111.jpg
1 W9 _6 J6 O* P& O: h: U5 ]
2 o, q' @2 T, w5 Y8 p7 u- m& K将信号采集之后经过FFT变换之后再通过IFFT反变换为时域信号。( R% r) H/ F: }

2 q& C* z2 F+ @* k这里我们采集了3KHZ的信号并进行了还原,可以看到并没有什么失真。
7 g: o5 G& F, p* ~: ]% G; }& v. G5 V. \- b/ _4 t
微信图片_20240529165107.png
1 ^3 h+ K' d3 B( x

, f& B7 K9 B& }* {+ K% q三角波的还原,可以看到似乎叠加了一个什么信号,但是不是很明显。
  b- {, a3 H$ N* q3 M, k: V6 o; E
7 u4 R, ]3 A, i' E
微信图片_20240529165103.png $ X( C- u% W8 n& v" Z/ W; s

* x. U4 M0 ^; [( F调制信号的还原,可以看到信号还原度还是非常高的。
$ p( l/ g7 W( Q" p2 L
3 p4 Y3 e; Q7 H* C
微信图片_20240529165059.png , u1 `2 x4 q/ z) Y

3 ]" Z* I  J) Y- [* M9 W两个正弦波,100HZ+500HZ的累加信号,可以看到其还原度也是非常高的。
' _+ q" i, q7 W0 a4 c+ ?8 a; r/ Y  G4 G+ `9 p/ t/ Z" ?
在这里我们应用一下我们之前的方法,将某个频段的信号去除。
1 U* O$ U0 A; _' z# K2 G3 c/ m$ q
. Y# W% l: C) Y
微信图片_20240529165056.png + E3 r" l1 Q! d+ m* B7 y

: z7 `4 Q+ P: X" n% u' E, G. f可以看到,我们非常轻松的从500HZ的信号中提取到了100HZ的信号。
  k$ y7 {- f1 [- y: P
& h7 g7 M2 r8 G2 c. z4 ]; f' m/ a4 w
微信图片_20240529165053.png
1 Z0 r: n+ [) ?
) N  D. i# d% c方波中提取其基波频率。
1 G1 g9 F$ t6 ?) D3 i5 _! K' p. ?9 X0 ]1 D1 X- K& U
微信图片_20240529165050.jpg
' w; n7 F- V" k$ L1 ]# D8 s" y  ]9 g4 m. d: z3 w( h
以及还有方波信号的 还原。* g$ J2 `9 a% q! j! p8 m' X( V
: e+ C0 Q3 h5 z3 p% V+ K
并且这个方法 的滤波精度相当之高。
5 o3 H* k8 I' m, E
( c& Q( y5 P8 W( J) F
微信图片_20240529165043.jpg ; F4 N3 z4 e  X" F/ h5 [5 Z0 @
! H- m( q2 R- w+ h/ J
从一个900HZ叠加1000HZ的信号中将1000HZ的分量去掉。* I: I4 Y$ M; @9 r! U6 _
0 ]! i( h, C  ?; Q2 j3 p
9 |' X; i3 Z/ U8 `
转载自:电路小白2 d  P' {: W% L9 p% g% Q* \8 e
如有侵权请联系删除
6 t6 V6 n, `( x, Z+ u. C& `8 ~
" y' w! ~) I. s; I! k
赞 收藏 评论0 发布时间:2024-5-29 16:51

举报

0个回答

所属标签

相似技术帖

官网相关资源

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