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

【经验分享】STM32F7 DSP库 FFT过程记录

[复制链接]
STMCU小助手 发布时间:2021-12-10 10:28
之前做课设的时候接触过FFT,看了一些资料,没整明白,现在做项目又用到FFT了,花了点时间整明白了。但此处的明白并非把FFT的原理啥的整明白了,只是明白在STM32上怎么用了。开发环境如下
4 R/ o6 I& e  ^0 tSTM32F767IGT6$ ~5 y: G# e* d$ Z# W
Keil5.21
$ {3 N" k1 f6 K$ ^Cube MX4.24& b3 J- b; G4 J5 W# C1 Y' N7 a! i# d
arm_cortexM7lfdp_math.lib* Q( e4 `* Q, {
正点原子阿波罗开发板$ t. I) s' ~( n4 Q

( h4 O6 k" s( t, q准备DSP库! @4 O! p* ?5 M( s
打开下载的固件库,文件名为STM32Cube_FW_F7_V1.9.0,
* M# B( T- b. h# P: e2 `
9 G$ K+ S5 `! c5 |/ w* U
20180311111030987.png

7 ^, v. N0 x# l" j. `+ \' @* g. r4 \+ f# K- Y! ]
Drivers文件夹下,CMISIS文件夹中包含上图所示文件夹,DSP_Lib和Lib是DSP库相关文件,其中DSP_Lib又包含两个文件夹,Examples和Source。
' b' t& c& a7 }- V* J$ tExamples 中的文件如下(这些是 ARM 官方提供的 DSP 实例):
' I- D' t% b# X" I7 P$ r4 k9 [: n5 }1 |5 D2 r3 `" A
20180311111810371.png

. z* u4 x- x! }& M- j1 A/ d
- O/ H( D/ _8 D" h. U2 ASource 中的文件如下(这些是 DSP库的源文件):# [6 I; a1 z, s# u

2 h- w* J' q! ?; G. A. T
20180311111958592.png
% r6 F2 T  j+ B; m1 E7 ^3 P

+ d$ k3 Y# T% ~7 |0 w+ m$ [; }源文件不需要添加到工程中,真正需要添加到工程中的是官方提供的DSP库,文件格式为.lib。库文件位于Lib文件夹中,有ARM和GCC两种开发环境的库,我们选择ARM。如图所示。6 r* m6 Q& w( E9 [7 f9 Q; d9 O
- u6 Y) V: J& m9 M2 h6 `
20180311112424199.png

+ J( z8 B" L, ?: ]" f$ n
0 L# q. D$ g/ i3 E7 @库文件有好多种,关于每种库文件的说明参见官方说明。 CMSIS DSP Software Library。该网站上有详细说明。如下图所示。! p6 v/ {& O# o9 p4 k, q
( N6 H( N; I. E9 c  b, J& Y
2018031111274971.png
+ I  ~9 q$ g$ a) c8 J1 Q

( L# [: Q0 U, n# S7 }确定了用哪个库后,添加到工程中。我的工程是用CubeMX建的,因此添加DSP库的时候在软件中操作,勾选后自动添加,如图。( J0 A& n, U/ `* n
& h6 Z( u  K  c) R
20180311113253946.png
2 Q+ A9 \) {+ a1 }9 _% Y0 I$ K
. J- A3 ?! F& j8 o# Y' E, d
下图为DSP库已添加到工程中。
8 K7 x2 e$ H" j( S/ ?# M7 C1 c
) O/ y, T0 x) A5 {  B
20180311113319114.png

+ j% n: |' C( \' ]  a1 x6 Y! m+ {& g, W
库添加到工程中,在需要用到库函数的文件中引用头文件,#include “arm_math.h”,即可调用所需函数。; e8 ~! }: [) q( R: r( ?
3 @6 W7 W+ c1 |
20180311113402949.png

- F  j) @. U7 e* t2 [8 W* H$ }2 W) G5 c- p$ P1 C* j& }/ Q
函数说明5 A1 H; n0 q+ i, g- c4 b( q
我用到的是实数FFT,即rfft。相关函数参见官方说明。
  H5 ^/ e9 A. f6 t6 `6 Z函数名中f32代表32位浮点数,q31代表32位定点数,q15代表16位定点数,q7代表8位定点数。
9 j. _. K' e$ l6 qarm_rfft_fast_f32是FFT实现的主要函数,函数原型如下。
) |  c1 d+ p8 z1 g5 P5 }3 \+ f) Z. D0 H+ c' r, N5 l
2018031111470032.png
  W: `& {/ _9 C7 D  \! B% Y) @' k
# h4 T% d* ?3 O+ K  H; v1 F4 f
S是 arm_rfft_instance_f32 类型的结构体,p和pOut是输入和输出的缓冲区,ifftFlag是变换的标志位。$ q/ d. w6 O# Q2 E! s' N
另外还有一个实现rfft的函数 arm_rfft_instance_f32,函数原型如下。2 A; P5 D- M0 w" W

4 ]4 k% L. n' v2 T; M4 n
2018031111510511.png
' h! i( @2 J( r

: T& u9 h7 b" l, C5 b- O' Q! M官方不推荐使用此函数。“Do not use this function. It has been superceded by arm_rfft_fast_f32 and will be removed in the future. ”
) B' T* d1 M: i  ^! H- A( N除了FFT函数之外,还要用到一个函数对arm_rfft_fast_f32中的参数S进行初始化,该函数为 arm_rfft_fast_init_f32,用于 初始化结构体S中的参数 ,函数原型如下。( ], ]2 q4 f: ]" G' T

: T3 d" ~: e& x5 y8 w7 Y
20180311115611796.png

. @* r2 v5 w7 f  T
9 w6 Z' e/ A2 T/ U另外一个重要的函数是arm_cmplx_mag_f32,计算频率的幅值。函数原型如下。
% G' i' Z8 c9 ~' ?
6 p2 c6 P& {4 E( _4 F* O7 O, {; A) d
20180311115858812.png
. Z" r+ r: F$ V
* h0 Q# Q1 t1 ], m( t" ?, Y  t
代码示例
% X+ o2 e1 E' O1 ~0 Y
  1. include "DSP.h"
    , O! }+ C/ A9 m6 g8 q4 C2 B
  2. include "arm_math.h"1 h6 ~1 g9 Q- A
  3. define NPT  1024  //1024点FFT
    % F5 W) F4 @3 r2 N' P4 E5 g
  4. define Fs 5120  //采样频率 5120Hz 频率分辨率 5Hz$ _* p) s7 k( X
  5. define PI2 6.28318530717959- J( z9 A5 u% s0 s  B  V
  6. float32_t  testInput_f32[NPT];
    & S( j9 ~8 O! I6 T
  7. float32_t  testOutput_f32[NPT];
    7 \5 L5 Q' u% P5 O9 c
  8. float32_t  testOutput[NPT];$ Z# L  w" Z3 `. [; J0 }
  9. 0 P) |6 N7 m* d+ o9 R6 M- c
  10. /* % ?* c4 s0 T! ^; r( i, |
  11. *********************************************************************************************************
    3 U! W/ P! p9 Y4 ?( S/ V
  12. *  函 数 名: arm_rfft_fast_f32_app & N, }0 L3 M( F+ f7 T9 V
  13. *  功能说明: 调用函数arm_rfft_fast_f32计算1024点实数序列的幅频响应并跟使用函数arm_cfft_f32计算结果做对比 4 ^8 L0 K3 I9 m% i# L- F
  14. *  形    参:无 ) x" a2 o' A# ^! M
  15. *  返 回 值: 无 ; ?/ c2 d' K8 e# M! T- }
  16. ********************************************************************************************************* * U# @; H1 ^0 }0 F- P& H
  17. */
    4 Q* o% {  U+ I& N) e! X1 J
  18. void arm_rfft_fast_f32_app(void)
    ' I% u1 a  P1 A4 ^* K; l
  19. {
    3 n- N; Q+ t2 W0 {
  20.   uint16_t i;
    3 K( a& [3 j( @4 s+ J! L
  21.   arm_rfft_fast_instance_f32 S;
    + P, k( q, R7 w" S4 w+ Z
  22. ' T' U* R# ?! E! g- K7 P2 \
  23.   /* 实数序列FFT长度 */ 9 h5 r* ~3 {2 r' l0 R
  24.   uint16_t fftSize = NPT;  : I& ?2 j' C6 U
  25.   /* 正变换 */ $ \( v9 J  X- W- w
  26.     uint8_t ifftFlag = 0;  " c3 U" c2 h5 g  C9 ~  T9 q0 M
  27. 0 ?4 @2 R8 m5 V) _
  28.   /* 初始化结构体S中的参数 */ 4 Z5 Z3 k! W% {5 j
  29.    arm_rfft_fast_init_f32(&S, fftSize);
    9 P% W& K5 ^( T8 f8 y* S; N- w) M

  30. 2 w# l. E1 \. M
  31.     /* 按照实部,虚部,实部,虚部..... 的顺序存储数据 */
    . }/ V; A/ `% G9 j# i  x
  32.   for(i=0; i<1024; i++) + @' y0 V  z/ w/ ^) F. C
  33.   { " o6 U; j. E8 j" n2 P3 j
  34.     /*3种频率 50Hz 2500Hz 2550Hz */ " E  ], U: D1 u& g" w) a! D$ E
  35.     testInput_f32<i> = 1000*arm_sin_f32(PI2*i*50.0/Fs) + ( \+ V8 L% b9 W2 o
  36.                </i>2000*arm_sin_f32(PI2*i*2500.0/Fs)  +
    ; \9 G* X/ z6 O
  37.                3000*arm_sin_f32(PI2*i*2550.0/Fs);
    ' J, _# B' ~' T* h
  38.   } , z2 B! e& h1 J4 _6 Y

  39. $ l5 w" L9 t' B) t. I* {+ I0 f
  40.   /* 1024点实序列快速FFT */  
    + k8 H: y; w  R3 I$ ?  o& Y; e
  41.   arm_rfft_fast_f32(&S, testInput_f32, testOutput_f32, ifftFlag); 3 ~1 a+ M; C1 X, ]
  42. . I# P2 e' |) T6 a
  43.   /* 为了方便跟函数arm_cfft_f32计算的结果做对比,这里求解了1024组模值,实际函数arm_rfft_fast_f32 0 N0 S: w8 Z% U6 \  g3 t
  44.      只求解出了512组   / K8 P) z1 R+ w; O% \5 l
  45.   */  
    3 x! ^" [* O  ]
  46.    arm_cmplx_mag_f32(testOutput_f32, testOutput, fftSize);
    , E  f! [$ J& u0 F" Z& |/ M( }

  47.   F: X1 O4 m" A" O* ~& a6 x
  48.   /* 串口打印求解的模值 */ : @# z( P, \, N$ y
  49.   for(i=0; i<fftSize/2; i++)
    ( }1 x) A  j! M. @* y; \
  50.   {
    " Q' g3 \( {1 `9 Z7 @  t
  51.     printf("%f\r\n", testOutput); 1 W" g% l# L  h4 Y; @% w0 Y
  52.   } 9 K  o7 e9 D7 z( Y7 a/ j" U+ ]0 E. r: y
  53. }
复制代码
$ W; G, q& L1 v' C' a
结果
* o& V8 I* w' ?( X$ U在单片机上运行,将串口助手接收到的数据保存到TXT文件,利用matlab进行分析。, X( Z; o5 l7 Y1 c

* N% A9 {0 s% p' j8 ]1 u
20180311120547219.png
# q3 ^  u8 A+ w* e/ Z3 R; ~+ O7 B
: t2 _/ a/ R  C4 R5 y/ f) G
20180311120659401.png

0 z9 I0 K9 f7 M: i- {) g, N: f- Z1 V/ M6 y
20180311120749658.png

/ v2 G# o$ K+ f: z
9 b& Z3 o1 E6 {5 j9 K( {! t
$ h- `) w+ f8 J; X" _7 ]1 F3 S' {5 n对数据plot画图,结果如下
& o8 M* n. G4 w$ Z7 I' ?2 G0 t4 Y& O7 D# T3 u$ H& n) C# [; j
20180311120824877.png
- D8 Q- P% d' w! w# P
8 C5 n8 h7 v1 M" J8 u
可以看出,FFT之后分析出包含信号的频率为50Hz,2500Hz,2550Hz,与生成信号 testInput_f32 = 1000*arm_sin_f32(PI2*i*50.0/Fs) + 2000*arm_sin_f32(PI2*i*2500.0/Fs) + 3000*arm_sin_f32(PI2*i*2550.0/Fs);1 C6 w. x2 F2 C4 ~. p

. @* W% I3 W  W2 h' ~9 p2 O1 H9 Q% S; }. |. N

1 U; V3 @: O4 ?7 a, u  D: ~) c
收藏 评论0 发布时间:2021-12-10 10:28

举报

0个回答

所属标签

相似技术帖

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