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

【经验分享】STM32H7的DSP的FFT测试

[复制链接]
STMCU小助手 发布时间:2021-12-26 16:43
前面是关于怎样运行fpu的,以及相关的环境配置0 B' H+ p/ k/ ]; B$ M& b/ [5 r% P

4 T3 q1 d% x1 i  P! `4 c4 g6 M3 rFFT的测试0 o0 z* _7 z2 }  f' B2 G
先看一段关于官方的FFT测试例程
! k7 t# \8 @& X! `) }0 M
里面添加了相关注释; G- @/ c" o5 A& R; L: `
0 U, ~- [5 ^  G6 M" U" o$ t/ ^
  1. #include "arm_math.h"
    2 p, U3 P! a( `# x  N$ x
  2. #include "arm_const_structs.h"9 e- A+ _5 _; }/ Q' \9 }4 e6 Z
  3. $ u% ?) ?2 O- _' y9 M* o
  4. #define TEST_LENGTH_SAMPLES 2048
    ' Z" |% b5 g1 Y

  5. ) g. ~9 R# r; |! X; V- C% }, T
  6. /* -------------------------------------------------------------------8 i0 l7 F& S8 q$ }7 @
  7. * External Input and Output buffer Declarations for FFT Bin Example
    % g! }  {$ z% q$ k
  8. * ------------------------------------------------------------------- */; J# J# b7 g5 b. J. T' X
  9. extern float32_t testInput_f32_10khz[TEST_LENGTH_SAMPLES];
    0 E! \% K$ j: x1 H( G# X
  10. static float32_t testOutput[TEST_LENGTH_SAMPLES/2];# m, Z% t* ~' O1 s6 j6 R

  11. ! n( c2 I; t- z1 o" k
  12. /* ------------------------------------------------------------------0 a# d  T1 ^1 H$ T' m' ?
  13. * Global variables for FFT Bin Example
    ' m- B& Q& x  t: N  ^2 c  o5 H* B
  14. * ------------------------------------------------------------------- */
    8 c' k( s, M4 d1 ^
  15. uint32_t fftSize = 1024;) u8 U4 \1 _# F
  16. uint32_t ifftFlag = 0;
    & N% V; O  I" _, X  O
  17. uint32_t doBitReverse = 1;
    7 R" P6 X& j1 B
  18. 8 x- L. F$ w& x0 v; ^
  19. /* Reference index at which max energy of bin ocuurs */
    ; x2 A  u# p$ L+ J5 d3 i/ m, ^
  20. uint32_t refIndex = 213, testIndex = 0;/ E- _. i5 Y! N: ^) W
  21. 2 z" J4 P1 I+ f4 N; R
  22. /* ----------------------------------------------------------------------
    9 A$ M( X* M1 u: y0 g: l
  23. * Max magnitude FFT Bin test
    # K% Z1 h4 i0 V% b- i
  24. * ------------------------------------------------------------------- */, ^2 @- W- O! _/ n' F" g

  25. # c3 s$ H  o: \4 o# b
  26. int32_t main(void)
    % s3 j6 e4 x, O$ l, v+ e3 V
  27. {7 n" `& \" m1 |3 f% |  s

  28. 1 H/ ]! M; J5 P- a1 |" m- Z
  29.   arm_status status;( [( `) y3 L6 D$ K/ R. S
  30.   float32_t maxValue;# X" q7 z2 v! E% S
  31. 3 F* s+ U" \( L+ z7 A" ~
  32.   status = ARM_MATH_SUCCESS;& u7 q& o3 g4 K! `1 a# `
  33. ; {) R- z9 O+ M! A5 i; z
  34. //注意这个模块的参数的相关用法,下面这个将是我们后面进行调用的函数模块
    + l; N. n/ [' C6 }4 h: g! y
  35.   /* Process the data through the CFFT/CIFFT module */
    : o! a6 z4 C" V1 v! {
  36.   arm_cfft_f32(&arm_cfft_sR_f32_len1024, testInput_f32_10khz, ifftFlag, doBitReverse);9 d! w& m" O* G; S. [
  37.         //可以看到要想使用此函数,将调用4个参数
    / A0 M6 c2 w. y) y; a% F. d
  38.         //参数1:指向浮点CFFT结构的一个实例。两种:arm_cfft_sR_f32_len1024、arm_cfft_sR_q31_len1024;; g1 U2 p: R$ K
  39.         //参数2:数据缓冲区的起始地址,偶数位为实数位,奇数位为复数: Q# X* m; J% P( q( ]% A" ?
  40.         //参数3:是否逆FFT标志位;1-是
    3 l) a2 Q! i- W& W+ e
  41.         //参数4:是否位反转输出标志位;1-是+ `! ^2 ~0 D" Z$ d! v8 f
  42.         //注意:此函数将覆盖源数据,并将其修改为对应操作后的数据
    " k- O6 {% }0 V
  43. 5 K2 b3 b' C* G$ _/ q# A( }
  44. - e( k' R2 s# o2 G- i% ^- D
  45. //计算频域的幅度,由于对称性,只取前一半
    8 C5 J: v: l! u- `; ?" @
  46.   /* Process the data through the Complex Magnitude Module for" C: U. T3 V3 h# E+ p" \8 H, Z
  47.   calculating the magnitude at each bin */# \1 S+ S; _$ v+ {# U- T
  48.   arm_cmplx_mag_f32(testInput_f32_10khz, testOutput, fftSize);0 J) }( A# \6 ^4 U( ~

  49. $ d" v$ S9 z. b" S
  50. //计算频域的最大值
    8 v/ g* ?8 v# k
  51.   /* Calculates maxValue and returns corresponding BIN value */
    % F2 f* }& d, ?8 D; {$ G
  52.   arm_max_f32(testOutput, fftSize, &maxValue, &testIndex);3 y% t: K: U' _7 b
  53. # ?6 @- G+ [) W2 h* K
  54.   if (testIndex !=  refIndex)& y) V* C# @' o8 V
  55.   {% `1 [% X' Z3 q& G  D4 L# s
  56.     status = ARM_MATH_TEST_FAILURE;
    1 ?/ p: O  p9 f# P: }* [
  57.   }* t; z/ L6 r8 Y5 R

  58. ) E; p8 x. \: ?5 Q" L2 \
  59.   /* ----------------------------------------------------------------------
    2 x+ ?5 X4 P/ M! z) \- n
  60.   ** Loop here if the signals fail the PASS check.
    . n* y1 ?0 v  I; U5 P4 c
  61.   ** This denotes a test failure
    * M! n8 m( \0 M2 N0 M
  62.   ** ------------------------------------------------------------------- */- U, y; |% X& J' @+ j+ W; j
  63. + V; }; V& e  G& Y
  64.   if ( status != ARM_MATH_SUCCESS)# ]8 G) e/ ^9 S7 C* I
  65.   {
    , y* Y, O6 v! ]
  66.     while (1);. i* Q" F1 m, {5 E+ k
  67.   }, I1 q( Z+ _( y
  68. & l& O7 a& V: h7 Z- _
  69.   while (1);                             /* main function does not return */
    . b5 L7 r0 x2 D
  70. }
复制代码

! i8 x. Z; Q% z  [2 V" ~实际使用后的测试
7 X# k. H8 j1 J5 e6 u实际使用的时候,我们并不是使用对应的源代码c文件,而是使用对应的lib文件。. {3 A. W; X9 L+ T
当我移植到工程中后,等下发布效果,不要在意上面如何能够运行,弄完后自己再实现。
+ U5 Z/ `/ R. }3 \) k
, @, r0 I& U6 T% }0 Ypython处理源数据得到频谱
% v& m5 e) n: h6 @4 B! _: a' a8 c源数据有2048个数据,但实际是由实部和虚部组成的,所以实际只有1024个数据点
2 D# r0 I" B; @9 Q2 ^* y& o. |$ L2 d
20210119142023633.png

1 G; e* i- C  D) G& j- X9 z
8 u9 M. Z' v5 B6 d2 _3 vpython会得到一部分负频率的成分,但是一般我们只讨论正频率部分
. ]  Y4 Z: a) r9 M$ t4 t& K  H% b$ H, d4 b2 g  G- g
stm32处理源数据得到频谱& M( |- M7 D) ^! S# J3 ^: q: e: p1 K$ |
这是stm32通过串口上传至电脑,然后用excel绘制的图像
" X( q9 M" U- M  f5 p$ X) e6 Z3 i0 W7 o' f) L' u3 X, u' T2 c" ?
20210119145755419.png

/ v: [5 A$ L; R2 I. A
& F% c6 W: H( c1 _; s两个结果一致9 v3 L; Z1 l/ F: T# ]3 Q

  }8 j( o4 D# u8 b* VFFT如何使用

8 b9 O3 ~4 u$ u! i1 \" @  d源数据------》调用相关函数-----》频域+ s* k2 N2 ~: j3 H! M" F# a/ u
频域中的各个点对应着相应的频率,幅值对应着当期成分的含量占比大小6 n& @) j2 l9 Y: r) y
5 g  \3 b/ k* h2 ?" t
cubemx的工程建立
* n, P2 k- C7 P& t& o" y/ h+ h1 N. l和普通的工程一样,不过建立之前需要注意勾选,复制所有文件到当前工程中;如果后面发现没有我们要的文件,可能是这一步的问题
% x; J+ a( ^5 M  D
7 t6 w5 A# W* L
20210119151535753.png
* [; M" `! x7 s# I9 q- p
& ]- D: i5 j/ c& g" j
添加相应的库文件/ ~3 N) w: k: ?2 V
先来查看工程文件夹中的一些文件
1 K* {6 Z1 z! g1 \8 k
20210119152533686.png
7 ]  P4 p4 X- E! u+ K
( J) R1 f( [# _5 W; r
这里面的文件目录是:
9 M9 ~0 \2 e" A- Q3 g5 x工程文件夹\Drivers\CMSIS\Lib\ARM
* r3 T# [* q! m' m3 e里面就是我们所需的库文件
5 y; j0 }' q* e1 D8 l
/ [7 m1 ]* _2 h  w下面添加到我们的工程中:
. u! S! h; }  k  B1 `  u6 c% i3 c% h. A( o3 o5 x
20210119153038371.png

, ]2 R, y8 a, d8 _% h1 e! G7 l8 Q2 \* {* _! _$ ^4 g
然后设置添加文件的类型:: j* w- Q* w7 r# L4 y7 P6 @1 X

: `3 E- }# D& |1 Q2 P
20210119153208652.png
$ ?: Z4 [8 a. j1 C1 j2 u; K

) D% Q% r7 Q3 f$ o! {+ Z7 m选中小端模式的库,然后点击add,如果选错了,后面将不能编译,然后点击关闭窗口. U" z/ U) [& K9 m* X
" R0 a- u- Z& ^, O8 C7 z
20210119153345635.png
3 h, P4 b  _7 ^  |' p! I) z! k: R" K
* l/ [5 d1 F  ]- A1 M
20210119153500594.png
6 |3 E4 \( c  c' F8 S
  L6 k' I6 ~% d- H8 ^
Keil工程的设置
( z" L! I( X' v" \8 o" }
开启FPU并设置编译器:
$ N7 a4 z1 ?* A" t  m将下面的东西复制到后面的图片中) {' t/ p9 X  k0 r8 {
# I& N; I% l% ]
  1. ,__FPU_PRESENT=1,__FPU_USED=1,ARM_MATH_CM7,__CC_ARM
复制代码
1 T1 I% i+ u2 A
然后添加一些文件- V0 y& y# z& z4 `
! O' A, T6 T" F2 ]5 N: {) j
2021011916003141.png
  s  \. W! \# y$ f+ i

2 z7 f9 [$ S3 \. O) C- ~5 z在这里输入' I2 E. s) w, \+ d9 N! {( X
…/Drivers/CMSIS/DSP/Include& t! g% G" a2 j& z8 L

6 M! I  Z4 r0 C
20210119160141855.png
; e  n6 p5 n: R0 \- W
' A# m6 K! W4 `2 n* B# H5 }
结果像这样
- H! d5 [# F& {6 A5 P' D
20210119160247877.png

0 V1 F( U* O0 c7 W2 Z& o6 Q2 B. L& Y$ [" L$ I. o' I7 y. a
然后点击ok$ e5 v9 r, M" d
7 A( X: @! v5 o
还要设置一个东东
# n' Y4 ~6 D: w0 P8 o( ^
3 f5 J' D3 a# A. b" i! c0 @1 Q
20210119154104108.png

$ o- i% T4 Z  b1 Y7 Y7 Z- I* t+ f( n; B
# |7 w/ {6 }- I# n  L
这里使用的是STM32H750,所以后面提到的ARM_MATH_CM7后缀是M7$ O9 r8 q; }2 q; L+ z
# M2 d: h# `) f2 L
现在就可以使用库里面的函数了
& ~" {5 m; J, j* d1 g/ V2 O- x7 N' x; p! h6 F
下面是测试( u2 V9 n- P- Z9 Q$ e5 r) i/ E2 P

7 V. m( K; h+ ?# B* N7 O. G进行FFT测试
" m4 k& v1 n  f( ]测试一  i4 e6 T! h0 t. c' \
添加测试文件
9 Y) i# P1 X- z% w
使用的是官方测试文件: u4 b; K) I4 V8 T3 Y7 Z) k' x

( n% L5 ~0 \# F6 u: B) o
20210119154843902.png

, N! D* s- G2 K# V7 I! J/ o
) ~1 t9 a+ P/ b$ b5 e这是例程所在目录
5 k+ `( e% i& f( B3 d
& N& ?8 r6 a& ^9 X2 i/ Y- F
20210119155008969.png
% j; Q9 X+ o6 X% n4 i- G; ]  `7 T

' T3 g6 E0 _5 M  l" Z
20210119155111683.png

, I2 m! x: z9 `/ h7 D5 s5 I* i  Q$ X  c+ {  C% p8 r' y1 B
2021011915514321.png
! Q4 {- O& D- {% M3 f) v
( M) ^# K' b3 {0 t' e4 {
然后打开我们的main.c进行编辑! W3 d# c6 B: \# N
注意:
# F2 N* n' Q* s; `4 N- k
- X  \: v' C' X* V我用的是uart4进行的串口通信6 o& r. _, ?; {! m, f
0 N8 B; O3 {# H1 D3 E8 N  }7 x
20210119155432852.png
$ A) X- T8 @; w" T
) H. U+ |9 ~7 G  C
1 c" h* p9 |# r6 t
  1. #include <stdio.h>
    7 Q' o0 X$ w3 v/ F# h0 a
  2. #include "arm_math.h") O& T4 e+ A  Q# }8 _  D; {
  3. #include "arm_const_structs.h"/ ]8 s) N3 x1 B1 R

  4. % x" G+ u- K! f5 j8 ?9 `
  5. #define TEST_LENGTH_SAMPLES 2048: M" A3 I7 s1 ^0 T$ _& k
  6. % \/ b: d6 ^: u
  7. extern float32_t testInput_f32_10khz[TEST_LENGTH_SAMPLES];//only have 1024
    1 S' j) K% W% c+ I! G( V- _
  8. static float32_t testOutput[TEST_LENGTH_SAMPLES/2];
    6 w. J9 U: r1 h- A: C+ ^
  9. uint32_t fftSize = 1024;' T  Y) Z0 i6 t" Y
  10. uint32_t ifftFlag = 0;+ T  I6 q; i$ V4 B( Q  @
  11. uint32_t doBitReverse = 1;
    # L) G4 E3 ?/ X: x2 g1 @# T9 k
  12. $ o8 Z3 |1 t- W
  13. /* Reference index at which max energy of bin ocuurs */
    # H3 Z( k% e7 X: P- T+ M& o
  14. uint32_t refIndex = 213, testIndex = 0;( @7 C0 B2 @$ x9 F1 O3 C2 s

  15. * g; j- m' E# D" R4 N# w
  16. ) x# `) A1 O3 N& u
  17. int fputc(int ch,FILE *f)) B( |* R  f' i+ o% ?: \4 u! n
  18. {
    ( r/ D, O0 T6 q0 c7 e& g/ [
  19.     uint8_t temp[1]={ch};
    6 {5 W) A; Z, M8 ~) C' f% i; E7 B
  20.     HAL_UART_Transmit(&huart4,temp,1,2);        //uart4   一定要修改为自己的串口!!!!!!!!!!!!1 G: ^" e: }& S4 a
  21. }
复制代码

4 |5 b; R% }  G/ I- d% u  X; e8 k然后3 ~; y  \: D* W( o  u/ B( L

3 w& D4 n- m* K# |$ ^. P; O! y* |
20210119155723560.png
! h$ z) H7 G8 U. J- w$ c4 _
  1. ( e( V6 K4 Z) h: b3 a
  2. arm_status status;
    : s* \( r3 Z. M  a, v  u1 E, }
  3.   float32_t maxValue;7 K, q, |! n" r) ?

  4. ( _, X# [6 J. L( ]4 H7 H
  5.   status = ARM_MATH_SUCCESS;
    * P# v! b/ \& d1 G

  6. . L6 Z3 m7 u5 X
  7.   /* Process the data through the CFFT/CIFFT module */
    0 X3 p2 [' y/ G! X. v- N% h) w. @
  8.   arm_cfft_f32(&arm_cfft_sR_f32_len1024, testInput_f32_10khz, ifftFlag, doBitReverse);* r( q4 d) a0 X
  9. ; D$ f% v& Q" g" X$ F( U5 T
  10.   /* Process the data through the Complex Magnitude Module for) r* I0 Z3 X8 M! E2 I$ |
  11.   calculating the magnitude at each bin */% b8 X9 j# g/ }5 e% w. _- a+ G
  12.   arm_cmplx_mag_f32(testInput_f32_10khz, testOutput, fftSize);
    1 \6 K0 j/ w7 e" B. _1 ?  l( u

  13. 3 g9 w8 v: F; g1 e1 @6 d
  14.   /* Calculates maxValue and returns corresponding BIN value */
    ) S7 N5 Q4 x# |! k* Q( S$ M
  15.   arm_max_f32(testOutput, fftSize, &maxValue, &testIndex);
    9 G2 [: k! s$ g+ W( `0 M* ?+ c, [3 D
  16. 3 ~" A2 W" X( k
  17.   if (testIndex !=  refIndex)% O& T: f$ P- d2 z% G0 O
  18.   {
    " `2 }5 ~5 C+ E7 n
  19.     status = ARM_MATH_TEST_FAILURE;- F2 Z6 d" T, G' e( z
  20.   }
    4 K8 C$ v5 \& ]( V9 @! l
  21. , q) L6 x, L  n# h+ X, R
  22.   /* ----------------------------------------------------------------------
    3 F) a5 F) ?% A' ^7 R
  23.   ** Loop here if the signals fail the PASS check.2 Y, o' G. c8 C4 \
  24.   ** This denotes a test failure4 ]# r3 l! {; W$ K
  25.   ** ------------------------------------------------------------------- */8 x& i3 `4 m1 m; t3 X1 J2 k: v

  26. # y) g2 q0 L$ Z- O8 N* k) I
  27.   if ( status != ARM_MATH_SUCCESS)
    + |+ v( V" M( ]+ R
  28.   {7 F3 J$ E$ ]( H/ d+ V$ v1 C/ z1 p
  29.     while (1);9 R- A$ N3 {7 H& E# c
  30.   }( h4 l  A( V8 Y8 g! H. y
  31. 2 }  ~4 b! x' h- P) q
  32.   while (1)) {, Y+ D: K% t- h, x5 ^5 n* C" {+ s
  33.         {8 P. |- D; J& B
  34.         //printf("hello\n"); 4 q. B  J7 @8 R  u; g
  35.         HAL_Delay(5000);
    & O6 R) K# U1 h7 z$ g$ d- d" E
  36.         for(int i =0;i<1024;i++)7 Y+ {8 y' ?7 a% o1 I! p
  37.         {printf("%f\n",testOutput<i>);
    8 _& \5 L9 a6 ]5 O
  38.         </i>HAL_Delay(10);
    % N' r2 @6 I2 N( U7 I
  39.         }
    - A8 e+ k( z1 U) o& I% G' c
  40.         while(1);! H  v  z1 X2 u- w& R, N. E
  41.         }
复制代码
. Y" O" u0 J6 u
这里完了就可以编译了; J$ n. a7 \; m' l% `
; f4 N! ^3 r. b1 _, i$ Z9 Y
结果探究' F, q( k4 E- o! K* L8 o
打开串口助手,等待5s后会发送
$ d2 H$ i. r0 q) G' v
0 s; I0 g. w  r' O2 h5 `
20210119161237405.png

: C" g: Z+ S$ u1 @; o, j
4 M$ o% R( r+ s. p  y然后提取之后就是我们要的数据了,可以保存后用excel来进行绘制,就是我们上面的图像了
, k. U0 U) C  }$ J4 E7 b* E& d7 B& v6 }; ~) C6 j
/ e1 v; n( h* h1 ?
20210119153944812.png
收藏 评论0 发布时间:2021-12-26 16:43

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版