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

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

[复制链接]
STMCU小助手 发布时间:2021-12-10 10:28
之前做课设的时候接触过FFT,看了一些资料,没整明白,现在做项目又用到FFT了,花了点时间整明白了。但此处的明白并非把FFT的原理啥的整明白了,只是明白在STM32上怎么用了。开发环境如下; L) s% X! M& t7 P# B
STM32F767IGT6
; j$ w  d" c$ R) {5 |Keil5.21
$ W& x1 _- z2 A! T- ~" GCube MX4.24) n- V5 c, B; u- {* f% ?4 A* p
arm_cortexM7lfdp_math.lib
; i) a4 D8 T. O2 O% Y0 ]正点原子阿波罗开发板# N, {3 Q9 z- e) w* P5 D
$ C2 _( X  l( v+ H
准备DSP库( u7 |' ?- P3 f* H
打开下载的固件库,文件名为STM32Cube_FW_F7_V1.9.0,& R1 V$ B* r5 s; T$ O% Q

; F/ x9 n8 X* x
20180311111030987.png

6 @6 k) H5 v( {0 s1 _
! @6 \, p2 s: q7 W- d$ H- XDrivers文件夹下,CMISIS文件夹中包含上图所示文件夹,DSP_Lib和Lib是DSP库相关文件,其中DSP_Lib又包含两个文件夹,Examples和Source。% R' Y( E/ H7 D6 \& R" C* V
Examples 中的文件如下(这些是 ARM 官方提供的 DSP 实例):
: X& i5 z9 }- _& k; E$ h4 z, t- `: D) l
20180311111810371.png

8 Y; i" |( r  u  V3 A7 M; k2 L' |4 P6 N& A) X3 C
Source 中的文件如下(这些是 DSP库的源文件):
: ]  g8 M, u4 B8 n, q1 j* k" N5 K( u' W, d! _1 B
20180311111958592.png

/ u/ i: \5 @; [( n9 w
& Y4 b/ V- l: v( m& Z, r) H& r源文件不需要添加到工程中,真正需要添加到工程中的是官方提供的DSP库,文件格式为.lib。库文件位于Lib文件夹中,有ARM和GCC两种开发环境的库,我们选择ARM。如图所示。) R" u( ^3 _% W% ^- ~" C3 e
/ H/ X4 j* [! I% A$ y5 |# i+ S) G7 f5 S
20180311112424199.png
  \9 ^& B  W& H9 @/ y5 Z5 ]" Q
" p5 X2 e9 h. o8 Y' u/ b0 |$ r+ n4 q
库文件有好多种,关于每种库文件的说明参见官方说明。 CMSIS DSP Software Library。该网站上有详细说明。如下图所示。. w& f- `1 N: @/ P" b+ E
. n, i, X( y- H
2018031111274971.png

6 D* u' k+ M! ?# w; Q; W5 x) q1 ?$ q( G2 U  q  X, W; e* S
确定了用哪个库后,添加到工程中。我的工程是用CubeMX建的,因此添加DSP库的时候在软件中操作,勾选后自动添加,如图。
  B, l, l8 _1 ^: w6 e/ S' X) l0 Z! L, b
20180311113253946.png

7 a& j, p3 [# m- B$ ?( p
0 }% H# ^/ P4 {, _下图为DSP库已添加到工程中。' h' t- M% U0 e3 C

, P# Z$ t4 z$ w0 q' j6 g& Z0 X
20180311113319114.png

$ U5 u4 _6 t, X$ G$ \8 r: [$ a& q  e. y: o# w& f' Y6 {5 v6 @8 \
库添加到工程中,在需要用到库函数的文件中引用头文件,#include “arm_math.h”,即可调用所需函数。
9 g7 D: b( f$ c1 ]
6 f! ?( ?. D' q5 \/ B0 W9 b
20180311113402949.png

0 x  Z/ U( ^9 |. }! ?" V
( y1 `1 N$ A' h* O函数说明
" ^: l5 |8 N4 }+ _我用到的是实数FFT,即rfft。相关函数参见官方说明。
4 ]% X8 l$ m$ ?! H# Y函数名中f32代表32位浮点数,q31代表32位定点数,q15代表16位定点数,q7代表8位定点数。
0 X7 B4 o2 f4 u6 ~& qarm_rfft_fast_f32是FFT实现的主要函数,函数原型如下。
5 M* r) o3 X6 U1 B- G+ r. p5 [
2 W. @9 F2 c- L6 P: V; U
2018031111470032.png

+ D/ {" v( D) J5 L. r
$ u: S* K2 M) i1 y2 yS是 arm_rfft_instance_f32 类型的结构体,p和pOut是输入和输出的缓冲区,ifftFlag是变换的标志位。
, V3 p: E; a! e9 B2 u8 D+ l另外还有一个实现rfft的函数 arm_rfft_instance_f32,函数原型如下。
7 `8 B8 Z' D. m
0 S6 ]" p6 y9 I$ K
2018031111510511.png
, Z2 E2 Z; i# D! \
7 r. e: K. B2 k/ E" C
官方不推荐使用此函数。“Do not use this function. It has been superceded by arm_rfft_fast_f32 and will be removed in the future. ”
8 d! j' M9 p, B除了FFT函数之外,还要用到一个函数对arm_rfft_fast_f32中的参数S进行初始化,该函数为 arm_rfft_fast_init_f32,用于 初始化结构体S中的参数 ,函数原型如下。  R: P' \6 c6 V, w( ~. p1 v

2 u0 P1 k+ `% s4 A% s
20180311115611796.png
/ _- v( H3 J9 ], U2 L5 p

( [+ E: ?' S7 d: g$ K' i9 }3 e4 C另外一个重要的函数是arm_cmplx_mag_f32,计算频率的幅值。函数原型如下。
. U- f0 C) h) A$ U( g; H2 v
7 n( X7 z; x+ \) y
20180311115858812.png
+ L7 S/ i/ _, ?+ ]/ E: {( n; O
2 C9 ~* o0 i$ }' ^0 f" E
代码示例
+ Q% F2 ^4 Z7 d4 c0 ]  B  }4 G
  1. include "DSP.h"8 A2 h: b0 c% B0 G' z' }* h: a4 c  v
  2. include "arm_math.h"
    0 i( [$ D- e) p) N; d
  3. define NPT  1024  //1024点FFT
    " {6 L. L7 u/ y" b5 i& U7 D  x
  4. define Fs 5120  //采样频率 5120Hz 频率分辨率 5Hz. I* d8 x2 Z) r, b1 h
  5. define PI2 6.28318530717959
    - {( w$ \6 I% E& Y5 f% z
  6. float32_t  testInput_f32[NPT];$ W- V& L8 U, s
  7. float32_t  testOutput_f32[NPT];6 A) U2 j+ @; D# I3 l, b
  8. float32_t  testOutput[NPT];- z& E, W: Z2 n$ F

  9. 5 d2 w* l3 i4 G% c$ G
  10. /* 2 U2 w7 }: T. n3 h1 J! w
  11. ********************************************************************************************************* 1 j' Z1 u2 ?7 @2 \- D" x) y, d( @6 N' m
  12. *  函 数 名: arm_rfft_fast_f32_app
      h: z5 T  J! y  `
  13. *  功能说明: 调用函数arm_rfft_fast_f32计算1024点实数序列的幅频响应并跟使用函数arm_cfft_f32计算结果做对比 8 p9 l! I; S0 q* y$ a, _
  14. *  形    参:无   n- L+ z) t) F( h
  15. *  返 回 值: 无
    / h! V; Y5 B8 Q
  16. *********************************************************************************************************
    1 F+ J) l' f7 M
  17. */
    ' W4 \; m% L% @7 [% A/ H- q. ?
  18. void arm_rfft_fast_f32_app(void) $ \2 S' J4 k$ M  X( X- Z1 \
  19. { 2 g5 H/ ?5 q. |( D  _0 J
  20.   uint16_t i;
    3 R* S; L. P4 Z7 W+ v
  21.   arm_rfft_fast_instance_f32 S;
    ( G) Y$ R  }& E, d/ ^  {3 C
  22. 1 ^  ^6 L; L8 G4 [+ h$ m: ~
  23.   /* 实数序列FFT长度 */ : E. _* F. Z$ ?: _2 }4 A& T; s
  24.   uint16_t fftSize = NPT;  - e4 E% A% v3 j. p
  25.   /* 正变换 */ 4 s7 C* S" L/ J5 [! G$ l( v: L+ ]
  26.     uint8_t ifftFlag = 0;  + B% I; A) Q' d; W# T" Y
  27. ( w4 o" l& I( K, U$ S) O
  28.   /* 初始化结构体S中的参数 */
    " W5 k, Y4 c8 G1 q' l0 X* U
  29.    arm_rfft_fast_init_f32(&S, fftSize);
    ( ?3 K/ D5 U2 W# d! c% [

  30. " l% p- P7 a, s7 u$ `5 w
  31.     /* 按照实部,虚部,实部,虚部..... 的顺序存储数据 */
    3 l' K! @& n9 v& x
  32.   for(i=0; i<1024; i++)
    4 c3 u& p  P2 o  G& H8 |; q
  33.   {
    # C% R$ k+ Z  z1 ~+ W! c3 e
  34.     /*3种频率 50Hz 2500Hz 2550Hz */
    ( ^; X. ]6 ], {
  35.     testInput_f32<i> = 1000*arm_sin_f32(PI2*i*50.0/Fs) +
    $ o2 y/ Z9 j4 ]* {) X* h9 K( s  s
  36.                </i>2000*arm_sin_f32(PI2*i*2500.0/Fs)  +
    2 J4 N% N7 [3 K; v$ A- Q4 ~$ q
  37.                3000*arm_sin_f32(PI2*i*2550.0/Fs);
      g2 t/ v: b" }& \7 M& q6 J
  38.   } 4 [, S: y& Z3 Y$ m5 n- \/ e
  39. 8 z1 H8 V$ Q# r* l1 B
  40.   /* 1024点实序列快速FFT */  
    0 R1 ?3 P# Y2 a
  41.   arm_rfft_fast_f32(&S, testInput_f32, testOutput_f32, ifftFlag);
    - P) y) ?  ?' c$ I+ B
  42.   q: o4 y1 {% Q1 f
  43.   /* 为了方便跟函数arm_cfft_f32计算的结果做对比,这里求解了1024组模值,实际函数arm_rfft_fast_f32 & y: d) i; }1 m, n( J
  44.      只求解出了512组   
    . F6 [9 r9 G7 U0 @
  45.   */  
    ( B! j1 v" L8 `2 ~
  46.    arm_cmplx_mag_f32(testOutput_f32, testOutput, fftSize);
    ; q4 ]' r& o4 A8 c* K
  47. / _% R" I# t9 ~" L% {5 X
  48.   /* 串口打印求解的模值 */
    5 O6 f  I& C( _( S" {8 W! Q: C% V
  49.   for(i=0; i<fftSize/2; i++) : D8 u. d0 ]7 p! m; W
  50.   {
    % q# b: \4 W* F
  51.     printf("%f\r\n", testOutput);
    ) [: r- x( `6 _- [! ~! a) x1 G
  52.   }
    ( {: M0 Z& }9 z7 z, T5 @
  53. }
复制代码
. w' u( M# P6 k
结果
" A% k4 }3 n  w3 v3 o+ _& k在单片机上运行,将串口助手接收到的数据保存到TXT文件,利用matlab进行分析。
3 R# u5 C* h) y7 K- P- s/ H, c! Q
0 F& g' t0 n# b# B
20180311120547219.png
; u6 M$ Y: {$ V

3 D* ~' Y, S; |6 k
20180311120659401.png
+ K! ^3 N9 }" ?8 l( H

1 D  `/ R3 E! f3 `$ q
20180311120749658.png
0 d% P" g! Y5 h

( K' }. p% p: [$ K6 S
) r  d5 v! k$ I+ I对数据plot画图,结果如下
) p- s& K& F% ~" {
: @) \7 Z$ I" I$ V. o
20180311120824877.png
9 |& }# S. Q. |; u0 \3 Y  [: K% n

. N  ?; U+ z8 f0 I可以看出,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);
, x; t& t+ t( F7 X8 T9 A7 x
: a3 `; F. `6 L4 P# R& F' _
  x$ L7 }, R3 `% E* Q- n" n" o

7 s! y' L# e% r5 Y6 n3 F' L$ k
收藏 评论0 发布时间:2021-12-10 10:28

举报

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