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

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

[复制链接]
攻城狮Melo 发布时间:2024-5-29 16:51
前面介绍过一期在STM32中进行傅里叶变换的教程,我们成功的对一段信号进行了傅里叶变换,获得其频率谱。
* l$ v) n: a6 l* M3 V# D 3B_8}BWR[]ZBFD2U~56EA@W.png ' R' B+ A9 o7 d. u' Q" d
6 w- U, k' @8 J! a& I
同样的,我们也同样介绍了双边频谱:FFT的结果是一个双边频谱,他不仅仅包含了实数的频谱也包含了负频率的频谱。
5 X( O2 W- A! P! ?% {$ M$ a8 ^: N; ?$ `
我们的采样长度为FFT_Lenth,同样的傅里叶变换的长度也是FFT_Lenth,而由于双边频谱的存在,我们的FFT结果数组长度是2*FFT_Lenth,并且通常直流信号会被统计两次。
  S! k) S  `6 N  w3 c

+ M6 _7 P( n. d$ k. @$ m& E事实上对于我们的时域信号而言,我们采集到的数据仅仅只是实部信号(虚部信号之所以叫做虚部信号也正是因为在复平面上)。/ W( Y: a# S% y/ |- e

7 L" {/ s& D0 b
微信图片_20240529165125.png
3 d3 t! @; k3 D% M( [5 P

) C2 T3 y; U% I& T4 D/ P在大名鼎鼎的火柴人数学中也体现了这一点。$ Z% `9 W6 |7 Q4 C1 }6 o

! d; E) O$ D' O! l1 F
微信图片_20240529165122.png 5 s1 g% {/ Z1 ]; U+ O
5 T# B3 |1 Q. t/ V) z% ?) s
而真正的信号应该是一个在复平面上的合信号,但是对于我们而言虚数轴上并没有什么意义。: r. L0 k" [+ s( g9 R9 h3 j( M8 N
& E# x6 y( B# I- H; t  h
因此我们在计算FFT的时候也会主动的不向原始信号虚数轴上填充数据。% S2 j4 o# {! E; s( {
1 V1 @2 e; J. ^0 v( |
  1.     for(int i=0; i < FFT_LENGTH; i++)  B2 r9 ^4 Y% i- ^, s" H4 `
  2.     {& B! \. j% F: Z4 a7 T( y  T
  3.       FFT_InputBuf[2*i]=(ADC_1_Value_DMA )*3.3/4096; //实部
    2 ]2 V3 U& _& j) O+ D' \3 k
  4.       FFT_InputBuf[2*i+1]=0;          //虚部
    0 N* h" {) C2 [
  5.     }
复制代码

' {4 @, d/ B+ g, g' H: |( e但是,即便是我们主动的忽略了时域信号中的虚部,但是FFT的结果中依旧包含了负频率的双边频谱) K, O& p8 g+ Z
% ]+ w# g9 G0 ?: o  @
微信图片_20240529165119.png % Y2 r  w& r/ l3 K. n: G& y

- P& }% A2 X6 N0 ~因此,当我们利用得到频谱的时候,通常情况下只考虑他的单边频谱,而负频率通常是不考虑的。
9 J, Y. _  f/ U2 z& ^9 u6 ]

; {# \: T, E+ v1 @4 t0 E好了,说了那么多我们还是聊聊我们接下去要干什么,FFT在STM32中的应用有许多文章都在对其进行介绍,但是几乎没有文章有介绍IFFT也就是傅里叶反变换。9 `" n* P# q) I7 I4 v% C* Q
$ x, v$ T9 F5 L* Z4 w
也对,通常我们知道的时域信号,我们通过傅里叶变换之后将其转换为频域信号,但是很少有知道频域的情况下对其进行傅里叶反变换,因为首先是应用场合比较少,其次是好像没什么必要。
& P) U' j& N* U: M# j- L
! P3 i6 `0 ^8 E0 v" p但是如果我们可以实现傅里叶反变换,那能不能通过对其频率信息的修改,即修改频域的值,实现一种滤波效果。
4 b; }$ H4 F9 ]5 g% `7 z3 z9 `, Y; d* F7 N) |2 F6 Q, r0 |* B6 y/ |, H! v
假如我们的信号采样率为10KHZ即10240,而我们的FFT长度是1024,那么我们的输出数组结果所对应的频率差,即相邻两个数据对应的频率差为10240/1024 = 10HZ
$ a+ I, M# c/ x5 K, |1 T) U# u6 P/ w4 j; w1 M
微信图片_20240529165115.png
% i0 v) Y: Z8 L. d7 s* g# q
  d0 P; }4 G9 M" I: |) j
那么例如我们将FFT的结果中前2*X项赋值为0(因为输出的结果中包含了一个实部数据和一个虚部数据)并且FFT_Lenth~FFT_Lenth*2的值均为负频率。
: A0 N8 i7 e2 E5 V5 K- K+ H! g1 C  {
这样子我们就可以实现一个X*10(频率差)的一个高通滤波器(低频段被删除了),之后我们通过傅里叶反变换实现还原原始信号。
! l$ U; ^( b$ C% Q5 ^2 w9 \- M0 g+ {# o" Z7 Z3 _! V9 X
这里需要注意的是,DSP库中没有给出IFFT的算法,因此我们选用最常见到的累加法求其IFFT的结果。
1 F* ^- l  T: t; ~% u
. U6 n7 w4 E- [% f8 j
  1.     for (int i = 0; i < FFT_LENGTH; i++) {  6 L6 ]1 ?+ d' [" e- R# q3 U
  2.     FFT_OutputBuf = 0.0f;   , _6 k! C& M2 J% s/ e# G$ K
  3.     for (int k = 0; k < FFT_LENGTH; k++) {  - n, [4 \% }$ f, R
  4.         // 累加复数乘法结果到原始信号  5 |. @5 ]+ C( Q3 @6 o" S4 w+ v
  5.         float32_t phase = -2.0f * 3.1415926 * i * k / FFT_LENGTH; // 计算相位  
    & F7 Y5 `  a# m; H
  6.         float32_t real_part = cosf(phase) * FFT_InputBuf[2*k] + sinf(phase) * FFT_InputBuf[k*2+1];  : u6 t6 z3 Q0 n; X
  7.         //float32_t imag_part = -sinf(phase) * FFT_InputBuf[k*2+0] + cosf(phase) * FFT_InputBuf[k*2+1];虚部信号  4 x# Y. I) f7 `: e& T5 K% p
  8.         FFT_OutputBuf += real_part; // 只取实部累加,因为原始信号是实数  
    : [* x4 I0 ?# z/ b
  9.     }  % H0 v# T2 W3 J  F  d  ~* v- A
  10.   
    * F) _7 `1 f, X4 n( j/ T1 P
  11. }
复制代码

& |! w+ m2 ?3 `( j1 I" @, N这里不具体介绍原理,总之我们看看效果。* u) |, L1 P8 H" o& Q$ Y! o
微信图片_20240529165111.jpg
! l+ t, [7 S7 i9 i. X  L8 E, i
8 F" T7 i- X/ V" z6 {* H  w* s将信号采集之后经过FFT变换之后再通过IFFT反变换为时域信号。' d9 @+ m& e- ?) V, D5 W, Z) B1 u" d% R
! R& F9 y3 q! @! j
这里我们采集了3KHZ的信号并进行了还原,可以看到并没有什么失真。
/ S( s' N# k. \6 |% C* K" Q2 H
5 b; j% o  U7 v" R
微信图片_20240529165107.png + ]7 |2 T; t" `) r/ v
* o/ I8 R7 R6 Z" g: p* s
三角波的还原,可以看到似乎叠加了一个什么信号,但是不是很明显。
4 s0 E. G& q3 P5 [* A; h1 H7 D5 O8 A$ b7 E
微信图片_20240529165103.png
& V# l. R6 g' }# r
9 i. `3 D8 J5 a  Q. g
调制信号的还原,可以看到信号还原度还是非常高的。
( I; C; ?5 V5 N5 V) L5 H& n% D2 i( V# Z" Q+ v
微信图片_20240529165059.png 2 f! B9 h! Y- C0 B( H
! ~0 I, ?4 w0 i5 |* ~) h- @
两个正弦波,100HZ+500HZ的累加信号,可以看到其还原度也是非常高的。
; x# d" V1 l, C7 Z- z2 p
7 `$ @5 @* z) D% A+ A# y0 c' z在这里我们应用一下我们之前的方法,将某个频段的信号去除。% I" X) W- M2 ^8 h
7 k+ p$ C) ]2 }! ]% y3 F" Q* C; _
微信图片_20240529165056.png 7 Y* s* ?, p2 z7 s9 L; g
- T' q# I1 V/ f/ q
可以看到,我们非常轻松的从500HZ的信号中提取到了100HZ的信号。
( [& @6 `3 I9 C3 v8 l! t& q, [& p3 w' a0 X- B4 f
微信图片_20240529165053.png * n1 U4 k8 U% ]2 u4 i
: z1 E; D1 x+ U5 y. v
方波中提取其基波频率。
) K6 N' z8 X  D& g0 d( b
$ z: |! {; S1 R. O
微信图片_20240529165050.jpg ; B* `2 L4 ]& v9 _. Y2 L

. K5 B' F) U3 r以及还有方波信号的 还原。& M: V& N" L3 U
8 d+ p+ u( \9 @. R6 v! j: G( X
并且这个方法 的滤波精度相当之高。  R8 \' r) `$ q

0 F& C) \" S1 G, L* q
微信图片_20240529165043.jpg ( x2 G- }  g4 W- g

( _* Q  G3 p! Z4 F1 B" d从一个900HZ叠加1000HZ的信号中将1000HZ的分量去掉。' Z* k  \1 x- k# s, w% B3 ~- O

, X' K2 ]. s% P8 b" {4 J* g
) W5 b1 S, c5 ^转载自:电路小白
: `) G6 F! k* _. p: B. E如有侵权请联系删除+ u0 `7 Y! |+ j+ f5 T
- u' Q9 U9 A/ Y
收藏 评论0 发布时间:2024-5-29 16:51

举报

0个回答

所属标签

相似技术帖

官网相关资源

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