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

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

[复制链接]
攻城狮Melo 发布时间:2024-5-29 16:51
前面介绍过一期在STM32中进行傅里叶变换的教程,我们成功的对一段信号进行了傅里叶变换,获得其频率谱。, k( O9 p" a1 M
3B_8}BWR[]ZBFD2U~56EA@W.png ; W2 M6 U1 f3 |$ Q( H/ D, L& ~9 i$ h
: d5 [$ A" j% |! `9 T+ x
同样的,我们也同样介绍了双边频谱:FFT的结果是一个双边频谱,他不仅仅包含了实数的频谱也包含了负频率的频谱。
( L8 v$ ~, Z  q: \6 s; f3 P5 ^" ^2 I1 p' H! `# S7 d& b
我们的采样长度为FFT_Lenth,同样的傅里叶变换的长度也是FFT_Lenth,而由于双边频谱的存在,我们的FFT结果数组长度是2*FFT_Lenth,并且通常直流信号会被统计两次。
( S- F% y* p* b  S1 O
" w) I# \* a" e+ J$ W/ h3 g
事实上对于我们的时域信号而言,我们采集到的数据仅仅只是实部信号(虚部信号之所以叫做虚部信号也正是因为在复平面上)。  u# P# a; F* @9 g' C; G
5 i' `! z# H( B! w" g/ v7 D4 I/ r6 Y7 D
微信图片_20240529165125.png
$ }' ~, A) L* }# o3 u; {. ^: w- T

* P! [# A( H6 N' |在大名鼎鼎的火柴人数学中也体现了这一点。
3 D$ `9 X3 n9 _6 V* ]' ^
5 G9 Q9 y1 ^0 ?4 r: W& I! \  t
微信图片_20240529165122.png 7 J6 Z: B: S0 C/ h

7 v5 c, t1 h! b& H( ~! F3 ]8 n
而真正的信号应该是一个在复平面上的合信号,但是对于我们而言虚数轴上并没有什么意义。, `! y; |8 e7 Q+ B

7 N% _" x0 [6 r, \; N
因此我们在计算FFT的时候也会主动的不向原始信号虚数轴上填充数据。
3 A& t5 |1 D) D( O4 G9 {( _+ K1 K9 Y6 K, p9 @$ a1 p
  1.     for(int i=0; i < FFT_LENGTH; i++)
    # S2 N; \3 N3 v, U
  2.     {
    9 g: Z9 u+ W" {  i* H
  3.       FFT_InputBuf[2*i]=(ADC_1_Value_DMA )*3.3/4096; //实部
    ( z0 {# f/ Y# i$ Y4 o/ d) `
  4.       FFT_InputBuf[2*i+1]=0;          //虚部2 @) y! s3 B2 Q& J
  5.     }
复制代码
/ m6 t2 Z+ J( p' J# \9 s
但是,即便是我们主动的忽略了时域信号中的虚部,但是FFT的结果中依旧包含了负频率的双边频谱
( Y! ]+ l1 x( y1 E( |& u1 e# ~
' m1 e  D; U; D. I' z
微信图片_20240529165119.png
1 q+ i3 q+ I1 _6 ~, p: `4 @) J
因此,当我们利用得到频谱的时候,通常情况下只考虑他的单边频谱,而负频率通常是不考虑的。
: \$ n4 y7 a+ Q7 |2 q

$ o# Q0 X* t  q# a9 F) m, t/ \, N好了,说了那么多我们还是聊聊我们接下去要干什么,FFT在STM32中的应用有许多文章都在对其进行介绍,但是几乎没有文章有介绍IFFT也就是傅里叶反变换。
6 }" P) w6 Y( V1 E) x
7 Y2 A% m  F: u; _; C也对,通常我们知道的时域信号,我们通过傅里叶变换之后将其转换为频域信号,但是很少有知道频域的情况下对其进行傅里叶反变换,因为首先是应用场合比较少,其次是好像没什么必要。: {5 ^; u3 I, C5 i/ V
8 [' ?) J1 m8 y  f! A6 e
但是如果我们可以实现傅里叶反变换,那能不能通过对其频率信息的修改,即修改频域的值,实现一种滤波效果。6 x7 v1 j1 q$ z* B
7 ]7 c2 i( N5 m
假如我们的信号采样率为10KHZ即10240,而我们的FFT长度是1024,那么我们的输出数组结果所对应的频率差,即相邻两个数据对应的频率差为10240/1024 = 10HZ
, V0 Z) N8 H8 _* d% t* ]! S; v+ O8 ?" P/ D2 D( H, F
微信图片_20240529165115.png
  i- s7 `9 p/ @* M1 ~' v
$ T0 O' b( d/ u) F& t
那么例如我们将FFT的结果中前2*X项赋值为0(因为输出的结果中包含了一个实部数据和一个虚部数据)并且FFT_Lenth~FFT_Lenth*2的值均为负频率。8 ~  Y  P& q% N( B

0 Q) N- V7 t# G这样子我们就可以实现一个X*10(频率差)的一个高通滤波器(低频段被删除了),之后我们通过傅里叶反变换实现还原原始信号。. B7 V, a7 O' s2 K( r* s# f* X
7 w- o- g( ~0 q  Q& j
这里需要注意的是,DSP库中没有给出IFFT的算法,因此我们选用最常见到的累加法求其IFFT的结果。
# H" j% p# c! L$ |" h& g( s
9 x9 \) j3 _5 D
  1.     for (int i = 0; i < FFT_LENGTH; i++) {  5 d$ v! M- a" s8 Y' L. c3 M) \
  2.     FFT_OutputBuf = 0.0f;   
    : @0 Y( O" G! j. z$ U1 y$ y
  3.     for (int k = 0; k < FFT_LENGTH; k++) {  
    3 b  h* T' x0 R$ R7 O2 K9 [
  4.         // 累加复数乘法结果到原始信号  
    ' u/ d& [8 i  i& h8 r: ^: V* j
  5.         float32_t phase = -2.0f * 3.1415926 * i * k / FFT_LENGTH; // 计算相位  1 q, z. q/ s& ?5 Y/ E) k  ?
  6.         float32_t real_part = cosf(phase) * FFT_InputBuf[2*k] + sinf(phase) * FFT_InputBuf[k*2+1];  
    9 A( d" K# L6 R1 l1 E! h: ~/ T  \
  7.         //float32_t imag_part = -sinf(phase) * FFT_InputBuf[k*2+0] + cosf(phase) * FFT_InputBuf[k*2+1];虚部信号  " {" l  \7 ]1 T
  8.         FFT_OutputBuf += real_part; // 只取实部累加,因为原始信号是实数  
    7 Q, \4 K: K1 W2 m
  9.     }  ( V( _) \3 c: S
  10.   6 D; m9 r) S; n  d9 x
  11. }
复制代码

' n" X2 ~1 |$ J, I这里不具体介绍原理,总之我们看看效果。
; @. }, G  z6 u% o5 v/ o4 J 微信图片_20240529165111.jpg
- I4 Y' e" v! n  c/ k
7 v& H6 v1 {1 H& T# b# x, j& m将信号采集之后经过FFT变换之后再通过IFFT反变换为时域信号。- f& }( w( m7 H* `) I8 S8 C  m: K

  n, m8 P, ]/ S. U0 f6 Z, [这里我们采集了3KHZ的信号并进行了还原,可以看到并没有什么失真。1 F* [" i. p+ e1 B. ~4 b9 h

/ p$ o. l0 ?! p1 V% n! O% b
微信图片_20240529165107.png
  A) q/ C- _5 q6 L, p# f/ R8 M. @" \

! g: E1 K8 @+ ?: {2 f2 m三角波的还原,可以看到似乎叠加了一个什么信号,但是不是很明显。
3 i2 Z5 e( e. b8 y$ Z7 @6 p8 c- A$ ]6 Z2 Z* k; i: i4 r
微信图片_20240529165103.png
2 n* ?+ ~- N  e, A. j9 M4 X7 \
1 ^  X1 q- w" D8 b5 T2 c
调制信号的还原,可以看到信号还原度还是非常高的。  z4 }6 ]3 L1 M2 p# ~

1 H4 x7 d) a: z6 A. V( K. N
微信图片_20240529165059.png
4 I) V5 i2 ^. s, J9 z  T  g
  c; ?" j0 r8 R3 [5 o1 P
两个正弦波,100HZ+500HZ的累加信号,可以看到其还原度也是非常高的。2 n& G( q3 k( t$ m
$ d+ S7 D1 N( D+ D5 u$ o
在这里我们应用一下我们之前的方法,将某个频段的信号去除。
  M/ g# G7 A- |- v2 E9 C0 B
6 x4 _. n" |7 J& K; d
微信图片_20240529165056.png & Z+ D% r  b" \* [
0 q2 {, J" Z1 j$ I
可以看到,我们非常轻松的从500HZ的信号中提取到了100HZ的信号。
! F* V+ W" s5 \  C6 j
1 A- I8 r) |. J2 N; }
微信图片_20240529165053.png
1 m' M" U# ^! N8 L  P- S
4 r& k" E0 \/ b  t方波中提取其基波频率。
! e) V& x# E. t$ r4 U& o" e% N, l8 A) _
微信图片_20240529165050.jpg
6 |  U3 m& ]* v3 h7 h3 b- L: w
- m- l. k& H. T* a以及还有方波信号的 还原。( B; N! W0 V( W+ I4 N
3 k2 a3 o1 p6 Z
并且这个方法 的滤波精度相当之高。; M2 R; W7 n0 Q
* S2 e$ Q: l+ W4 x
微信图片_20240529165043.jpg 9 W9 k) y& F5 u3 Y' O3 A4 ]

, D! y! }. J: J) \% o; w从一个900HZ叠加1000HZ的信号中将1000HZ的分量去掉。- X9 }* a% D# q  _

; Z& V4 Y" @. W* P4 L: S/ k4 L3 P) R! W- P% t7 c3 O) v
转载自:电路小白$ D8 Y& N6 F" ?: }' {
如有侵权请联系删除( L- \- H/ w6 f+ L" i/ e
/ V7 h1 k7 [, F& [# W
收藏 评论0 发布时间:2024-5-29 16:51

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版