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

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

[复制链接]
攻城狮Melo 发布时间:2024-5-29 16:51
前面介绍过一期在STM32中进行傅里叶变换的教程,我们成功的对一段信号进行了傅里叶变换,获得其频率谱。
4 N* p6 _2 t; z) V 3B_8}BWR[]ZBFD2U~56EA@W.png 2 c" n, |0 F; W

  Z. m; R- }4 ]! H' E同样的,我们也同样介绍了双边频谱:FFT的结果是一个双边频谱,他不仅仅包含了实数的频谱也包含了负频率的频谱。
  P) j) {! Q1 ~- x$ w
3 X3 f/ `& ?: C7 ~我们的采样长度为FFT_Lenth,同样的傅里叶变换的长度也是FFT_Lenth,而由于双边频谱的存在,我们的FFT结果数组长度是2*FFT_Lenth,并且通常直流信号会被统计两次。9 q1 i& V$ T( g! o. M

& q9 a, Z! t2 k& y1 G) ~4 Z事实上对于我们的时域信号而言,我们采集到的数据仅仅只是实部信号(虚部信号之所以叫做虚部信号也正是因为在复平面上)。6 Y" I/ @; c4 l, D9 J6 w

* c7 m2 x& ~* N
微信图片_20240529165125.png
% D4 ]0 M- u$ U$ }; W: U4 y

! ]; ^( l7 c1 q5 ?' h/ f# [在大名鼎鼎的火柴人数学中也体现了这一点。( D6 W. f' v% E" G5 K7 I

) K7 P4 D2 |6 h6 Y9 a+ Y4 E
微信图片_20240529165122.png / Q' ?2 J* c+ Q7 d6 A& ^

- b* q6 W# r8 B
而真正的信号应该是一个在复平面上的合信号,但是对于我们而言虚数轴上并没有什么意义。
) R7 x/ p5 s2 T1 n7 m- F
  Z0 i! r* X+ R1 M5 h# F
因此我们在计算FFT的时候也会主动的不向原始信号虚数轴上填充数据。9 N; r. K9 g" o$ I* c2 p0 V
+ ^" J* B$ `- Y# `
  1.     for(int i=0; i < FFT_LENGTH; i++)
    2 C/ z+ K" l) W6 ^1 f9 v
  2.     {
    ( h5 ^- e5 j* H; B0 E5 M
  3.       FFT_InputBuf[2*i]=(ADC_1_Value_DMA )*3.3/4096; //实部
    ( }1 B! Q: H  }8 h
  4.       FFT_InputBuf[2*i+1]=0;          //虚部
    : B. ~4 f) |; Y5 V
  5.     }
复制代码

- Q% Z8 ^0 B6 H" d. ?# e但是,即便是我们主动的忽略了时域信号中的虚部,但是FFT的结果中依旧包含了负频率的双边频谱
  C1 j/ v- ^, T4 @; q" P9 C, S& v9 a+ g& n$ ?& P# a1 b" z
微信图片_20240529165119.png
0 r% Q- @6 t7 E  B! {
- G6 z4 d; y) d, r6 G, z  j因此,当我们利用得到频谱的时候,通常情况下只考虑他的单边频谱,而负频率通常是不考虑的。
* y2 N2 t$ f# Q7 t9 Z
/ r5 t- D" ^6 D* S
好了,说了那么多我们还是聊聊我们接下去要干什么,FFT在STM32中的应用有许多文章都在对其进行介绍,但是几乎没有文章有介绍IFFT也就是傅里叶反变换。5 n2 B: X  k9 e- I5 N

+ m2 F4 P( q; P1 ^0 [6 ]0 e也对,通常我们知道的时域信号,我们通过傅里叶变换之后将其转换为频域信号,但是很少有知道频域的情况下对其进行傅里叶反变换,因为首先是应用场合比较少,其次是好像没什么必要。
: ~; L2 q' D3 Q; Q( ~5 C+ M. l0 f6 x$ E* t" D; U0 A$ G7 x
但是如果我们可以实现傅里叶反变换,那能不能通过对其频率信息的修改,即修改频域的值,实现一种滤波效果。/ E- h; T" p5 m! \& R* H; i
- k2 t) o1 R& m  }1 o. N+ b
假如我们的信号采样率为10KHZ即10240,而我们的FFT长度是1024,那么我们的输出数组结果所对应的频率差,即相邻两个数据对应的频率差为10240/1024 = 10HZ3 ]! M8 ?! Z7 f
& ]4 C. N0 c9 ]# C+ }) H# @
微信图片_20240529165115.png 7 j% e+ R- R. @% [" L1 z
$ e1 N" B" F" N  F! ]
那么例如我们将FFT的结果中前2*X项赋值为0(因为输出的结果中包含了一个实部数据和一个虚部数据)并且FFT_Lenth~FFT_Lenth*2的值均为负频率。9 F5 \6 z% g& F( n+ y

5 Y: n1 Y0 e' n" E$ O; t+ v这样子我们就可以实现一个X*10(频率差)的一个高通滤波器(低频段被删除了),之后我们通过傅里叶反变换实现还原原始信号。3 g+ O. |# }( r

+ z( l. D7 Z* U$ s这里需要注意的是,DSP库中没有给出IFFT的算法,因此我们选用最常见到的累加法求其IFFT的结果。. I% i& V& I+ n, h2 }* ~: E

( K. ^# {- o, l$ D% |0 D7 [
  1.     for (int i = 0; i < FFT_LENGTH; i++) {  
    ( _3 x4 t7 r1 q# A/ p' E9 @0 C/ @: j
  2.     FFT_OutputBuf = 0.0f;   ; R& l) H# N3 ~% v$ a1 W: @
  3.     for (int k = 0; k < FFT_LENGTH; k++) {  - p# X# r8 {, m! o5 W% A
  4.         // 累加复数乘法结果到原始信号  * P1 s8 ~. e6 _0 F
  5.         float32_t phase = -2.0f * 3.1415926 * i * k / FFT_LENGTH; // 计算相位  
    # k5 a/ _! z+ m. c( _
  6.         float32_t real_part = cosf(phase) * FFT_InputBuf[2*k] + sinf(phase) * FFT_InputBuf[k*2+1];  
    * G  L5 g" \8 r
  7.         //float32_t imag_part = -sinf(phase) * FFT_InputBuf[k*2+0] + cosf(phase) * FFT_InputBuf[k*2+1];虚部信号  
    % I! T* a  D4 S( z9 i  s% l+ F
  8.         FFT_OutputBuf += real_part; // 只取实部累加,因为原始信号是实数  
    6 K1 Z$ h- o8 b7 |+ ^) v- N0 ]9 w
  9.     }  
    0 j5 x! W- s; Z. F
  10.     o0 e/ A0 L1 ?1 x! j4 G
  11. }
复制代码

) h7 [! `. y/ c$ F9 ^这里不具体介绍原理,总之我们看看效果。
+ i& r7 [# B/ z7 s" \( x3 ]. T# A 微信图片_20240529165111.jpg
, I, o1 F; f( M9 c: n/ h, E( L$ Z3 N7 E8 H- I& T$ G/ h" T
将信号采集之后经过FFT变换之后再通过IFFT反变换为时域信号。$ \* K. K, _; X
# e5 G/ F  B1 b  R# K) E" E
这里我们采集了3KHZ的信号并进行了还原,可以看到并没有什么失真。( \- w/ o& k( y

3 N7 W0 E* ^/ j
微信图片_20240529165107.png
2 y+ c. h: j. _( F1 \

3 s5 |& U+ y. X! b& s三角波的还原,可以看到似乎叠加了一个什么信号,但是不是很明显。
: H& D) {0 k/ A
9 r' D/ e, }3 L8 ^
微信图片_20240529165103.png 4 G5 z& P: O" m1 f9 @6 s4 U

+ O6 q# }" v( F7 B! i$ Q调制信号的还原,可以看到信号还原度还是非常高的。
+ ]5 d# e2 i) Z' f+ u5 o- q+ U
4 Y/ l2 H* m  \1 S- E
微信图片_20240529165059.png $ V- n9 N* R7 j
) I  V6 S: A6 J3 _
两个正弦波,100HZ+500HZ的累加信号,可以看到其还原度也是非常高的。
; n) W+ X* s0 I7 v+ m  p1 w1 \
( y2 J! M) H8 o# t. c在这里我们应用一下我们之前的方法,将某个频段的信号去除。, b4 s9 t4 n8 F
+ b) ?7 H+ g6 z* M; `0 K) ~3 K
微信图片_20240529165056.png
1 Y4 _# r* c7 i$ r" J6 s2 y
0 a+ i+ e: ^) W- g0 w# D8 Q
可以看到,我们非常轻松的从500HZ的信号中提取到了100HZ的信号。
3 }# x! O: L3 R8 g$ I4 q
0 a( ^  S% m8 `& _
微信图片_20240529165053.png
: O9 ?% W- \% s. v$ s  F8 x! L8 d+ g1 |! M6 e
方波中提取其基波频率。
0 j6 f0 G$ t% ^' w( E/ A! y( d- b! U& S- b" \
微信图片_20240529165050.jpg / i- }+ L3 b6 a0 m$ @

) i5 u( T8 U$ g8 V+ m% M以及还有方波信号的 还原。4 s/ ]) i$ X' D" b4 D/ u) W+ O
: q: [) X# u( N  R1 X- K
并且这个方法 的滤波精度相当之高。
: k' i5 U+ Z* ]  {" `* o
- i, K# E  _& |( d2 ]& f" @
微信图片_20240529165043.jpg
  B2 }' Q$ J1 g9 W9 t  S' F' g% b1 w2 D2 P# r  K6 O  o
从一个900HZ叠加1000HZ的信号中将1000HZ的分量去掉。1 C0 A7 B/ G( @

- w8 L. `) E+ ~- ]1 M7 ?: X' ~& v) A4 L7 G* W: y# I
转载自:电路小白
5 L0 B8 ?5 ]6 i% c2 X& ]; c如有侵权请联系删除4 Z# _0 a# q5 R& F
: k( V6 E. ?! F: C, V' M
收藏 评论0 发布时间:2024-5-29 16:51

举报

0个回答

所属标签

相似分享

官网相关资源

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