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

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

[复制链接]
攻城狮Melo 发布时间:2024-5-29 16:51
前面介绍过一期在STM32中进行傅里叶变换的教程,我们成功的对一段信号进行了傅里叶变换,获得其频率谱。+ h3 }0 O: ~6 r) J3 j( x
3B_8}BWR[]ZBFD2U~56EA@W.png 3 w0 Z2 y, J4 |4 |

. _; ^1 T$ d" L; _同样的,我们也同样介绍了双边频谱:FFT的结果是一个双边频谱,他不仅仅包含了实数的频谱也包含了负频率的频谱。
: c$ A: P. p% b" y4 a0 _6 e$ C0 V
! B) W! Z* Y: ?4 F8 R我们的采样长度为FFT_Lenth,同样的傅里叶变换的长度也是FFT_Lenth,而由于双边频谱的存在,我们的FFT结果数组长度是2*FFT_Lenth,并且通常直流信号会被统计两次。
* [) n3 w! b$ C2 ~! T1 H* S

6 ^8 \. w- [$ p$ w  _事实上对于我们的时域信号而言,我们采集到的数据仅仅只是实部信号(虚部信号之所以叫做虚部信号也正是因为在复平面上)。
) d* f  I+ T5 c# R* m
0 l2 Z% U; r' a
微信图片_20240529165125.png 6 `& ~# r3 p9 F

& L/ j3 a0 i6 T% h在大名鼎鼎的火柴人数学中也体现了这一点。0 {  k/ D" }# p0 b& z- g
" m+ L3 {  p/ {% v+ E% \
微信图片_20240529165122.png
1 b: R" b8 @' }* W; Q5 q% r- `& M1 E+ M
而真正的信号应该是一个在复平面上的合信号,但是对于我们而言虚数轴上并没有什么意义。! P8 m0 L: E; K5 F- q
5 _& M% \8 o  l2 l7 z
因此我们在计算FFT的时候也会主动的不向原始信号虚数轴上填充数据。' f7 j8 r, Q& ]2 ~# m" g+ E/ Q

+ [' S& Q8 A# S2 o
  1.     for(int i=0; i < FFT_LENGTH; i++)& I- L: P; ~# P1 M" U$ I( g2 Q
  2.     {2 L5 f' T; M! z- _9 P
  3.       FFT_InputBuf[2*i]=(ADC_1_Value_DMA )*3.3/4096; //实部
    ( l. `& C4 N/ Q* u9 {
  4.       FFT_InputBuf[2*i+1]=0;          //虚部
    5 g: C' G) ~7 U; z: B' s4 Q) r2 ~
  5.     }
复制代码
* q5 _- h1 d( q0 ~
但是,即便是我们主动的忽略了时域信号中的虚部,但是FFT的结果中依旧包含了负频率的双边频谱
4 M$ k& Z5 m+ O* W' V/ |+ x& T9 U9 b' r5 v
微信图片_20240529165119.png 2 T+ j. b& Q3 r: E& c
0 x* E5 s( u5 b3 c  J3 @( a
因此,当我们利用得到频谱的时候,通常情况下只考虑他的单边频谱,而负频率通常是不考虑的。
8 o/ X( ~$ ]1 p. Y, o
) C( C/ O8 c+ y+ o8 H, e
好了,说了那么多我们还是聊聊我们接下去要干什么,FFT在STM32中的应用有许多文章都在对其进行介绍,但是几乎没有文章有介绍IFFT也就是傅里叶反变换。
5 b* i2 _0 u8 d. x
& S( n- k5 x+ h- N也对,通常我们知道的时域信号,我们通过傅里叶变换之后将其转换为频域信号,但是很少有知道频域的情况下对其进行傅里叶反变换,因为首先是应用场合比较少,其次是好像没什么必要。! _- q& B4 i& {+ q- J

1 A1 `3 D& Q6 l但是如果我们可以实现傅里叶反变换,那能不能通过对其频率信息的修改,即修改频域的值,实现一种滤波效果。
. X1 t4 p& z! }- n# K' X& w! S$ F2 O7 K; Z) ?
假如我们的信号采样率为10KHZ即10240,而我们的FFT长度是1024,那么我们的输出数组结果所对应的频率差,即相邻两个数据对应的频率差为10240/1024 = 10HZ2 @1 A0 t$ K9 [2 [  U7 u' r6 a: `" _3 l

9 k# w8 _' c+ ~" o- n0 q- p
微信图片_20240529165115.png # ^3 R! p1 V- P7 ~8 a
0 J) ~2 d0 h" B
那么例如我们将FFT的结果中前2*X项赋值为0(因为输出的结果中包含了一个实部数据和一个虚部数据)并且FFT_Lenth~FFT_Lenth*2的值均为负频率。
& Z+ Z  k5 S  F# v6 v. I
" ^  n3 m* v" X这样子我们就可以实现一个X*10(频率差)的一个高通滤波器(低频段被删除了),之后我们通过傅里叶反变换实现还原原始信号。
8 G1 Y( S' C' f6 [5 s. m  f# A7 I, c) a5 A0 z2 [$ v9 n2 \8 `& t
这里需要注意的是,DSP库中没有给出IFFT的算法,因此我们选用最常见到的累加法求其IFFT的结果。
  g9 M5 L3 M6 m6 m2 i* s% Z$ s+ C9 K# H& M  H( K* B
  1.     for (int i = 0; i < FFT_LENGTH; i++) {  
    / d& L: [& P2 q8 F
  2.     FFT_OutputBuf = 0.0f;   4 d. k! f: ^" C6 v: r* ]. Z
  3.     for (int k = 0; k < FFT_LENGTH; k++) {  
    , y" F2 }8 Z9 `  Q% t; m$ ^) q3 v7 E
  4.         // 累加复数乘法结果到原始信号  - l8 e8 J( A* M8 ?6 Y, I
  5.         float32_t phase = -2.0f * 3.1415926 * i * k / FFT_LENGTH; // 计算相位  
    " ]0 j6 s# P1 P! D0 k
  6.         float32_t real_part = cosf(phase) * FFT_InputBuf[2*k] + sinf(phase) * FFT_InputBuf[k*2+1];  4 Y6 a) ]3 ?/ ~1 A5 B
  7.         //float32_t imag_part = -sinf(phase) * FFT_InputBuf[k*2+0] + cosf(phase) * FFT_InputBuf[k*2+1];虚部信号  % c! u* P4 z3 d+ l3 B
  8.         FFT_OutputBuf += real_part; // 只取实部累加,因为原始信号是实数  " }+ ~+ y8 h- R: ^0 p! k: X
  9.     }  
    : Q  D$ ^- O9 m' N9 Z6 @
  10.   0 \( w" u( y3 y) K5 _4 z" d7 |5 b- @) K
  11. }
复制代码
& Q) {: Y, U8 J; u( D
这里不具体介绍原理,总之我们看看效果。1 a6 r4 n; K0 Z! T( k& z9 I4 Z
微信图片_20240529165111.jpg % Q: m$ d: b1 v" S: j& v" H& k

5 F& y5 s# l, H8 c将信号采集之后经过FFT变换之后再通过IFFT反变换为时域信号。7 F+ Z! b1 [* f6 H' q3 e
& r. R/ X7 z  b% x9 p' P
这里我们采集了3KHZ的信号并进行了还原,可以看到并没有什么失真。
2 h  m1 T3 f! A4 q
  V( k8 k4 ]: P/ w% _$ s; e
微信图片_20240529165107.png
, ^% r/ N/ @5 A. ~* ^! @8 y% f

. E+ r! b$ \; r  B三角波的还原,可以看到似乎叠加了一个什么信号,但是不是很明显。( o% Z/ j4 \: k& I" l
. e; a$ p" s, T' T! s+ y& {
微信图片_20240529165103.png
1 n. C  e, b$ b( |3 _
6 k3 C; u7 m4 X/ U6 T' ^+ c
调制信号的还原,可以看到信号还原度还是非常高的。' `# O8 `3 \) c  _% g6 p( O& ~

) d2 S4 j$ E: N: C
微信图片_20240529165059.png # o! Q* t$ V  C3 w1 `6 ~- [
0 b, ?8 R$ c* |' a4 v9 V0 [  V
两个正弦波,100HZ+500HZ的累加信号,可以看到其还原度也是非常高的。0 [6 C0 m9 W, {, j9 G" v) M( J
& c6 P% c' ]$ `. g* e9 r) b
在这里我们应用一下我们之前的方法,将某个频段的信号去除。
2 M, u+ }" w/ ~% s& c8 _+ R9 p
, n0 g. I6 B* Z5 N* h$ |3 u
微信图片_20240529165056.png ! O% N" G1 m$ B5 t3 N

9 E7 o1 A, C3 m0 a4 ~& Y3 S. I可以看到,我们非常轻松的从500HZ的信号中提取到了100HZ的信号。
+ Y- p, a  o( k! X1 W  c3 `, a: V4 }0 l0 n" @: E
微信图片_20240529165053.png
1 k6 G, @2 x7 `
$ ~! K+ O; W5 W: a; l  `8 R  {+ q方波中提取其基波频率。6 V/ x( \/ {# p

- B" {( W3 Y8 l" l
微信图片_20240529165050.jpg
2 H) R0 P/ T, R# N, o& K9 P; u# _
以及还有方波信号的 还原。( U" {$ {" t( a. x
& g4 x0 j$ u  h1 _, l
并且这个方法 的滤波精度相当之高。
/ b7 U& |! V+ i9 K  x$ f$ l' v9 Z8 M4 P9 x6 ]
微信图片_20240529165043.jpg
: q9 G" v) n& n
5 c% x% D5 ]: \, S/ q从一个900HZ叠加1000HZ的信号中将1000HZ的分量去掉。4 C+ c8 y) i  C# f% n6 c' D" }# S% F
9 l  p& M' N) e4 J
1 d5 _9 h) t; x2 C
转载自:电路小白9 D2 k) m" t+ h
如有侵权请联系删除$ _# ]( _+ s: g8 y5 i- h" H
# {3 L4 H: s/ j5 U7 R" K) o
收藏 评论0 发布时间:2024-5-29 16:51

举报

0个回答

所属标签

相似分享

官网相关资源

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