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

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

[复制链接]
STMCU小助手 发布时间:2021-12-26 16:43
前面是关于怎样运行fpu的,以及相关的环境配置" w6 S  A( i( g: n! ^

) s  F6 c# o) [+ bFFT的测试) `% Y8 e1 M  I- `8 z
先看一段关于官方的FFT测试例程

. p% b, L1 i: ?- ~/ n里面添加了相关注释
. J9 @3 _* @$ o6 k7 S, G; ]6 G$ T! Y2 W) @  ]
  1. #include "arm_math.h"
    ) J6 X. K9 e, W! g4 t  d
  2. #include "arm_const_structs.h"3 T: S& W0 `, M$ k& E1 w8 H  _6 E

  3. - W. F! N5 T1 A( I( O1 m, s  _; y
  4. #define TEST_LENGTH_SAMPLES 2048
    $ X; C* s7 K  E+ D! c) q# B5 X
  5. : W/ ]6 G5 Q2 \) G% m! V
  6. /* -------------------------------------------------------------------- j0 U( B* R0 q4 p" |
  7. * External Input and Output buffer Declarations for FFT Bin Example
    / t3 [# a: S9 ?4 c$ r1 U: L
  8. * ------------------------------------------------------------------- */
    . k/ ?" j1 o1 y
  9. extern float32_t testInput_f32_10khz[TEST_LENGTH_SAMPLES];
    - W! u; g2 W( K; F: k5 n8 f& |
  10. static float32_t testOutput[TEST_LENGTH_SAMPLES/2];
    # f- o# a4 J2 P: x/ [, T- v" s% O

  11. 5 d1 A( b3 V/ Q* w. A
  12. /* ------------------------------------------------------------------, f/ x+ N0 G: ?7 U% X
  13. * Global variables for FFT Bin Example
    % ~9 q2 P; I4 W. n
  14. * ------------------------------------------------------------------- */* q- y) b. v$ [0 j2 T4 q8 W/ [
  15. uint32_t fftSize = 1024;
    . g* S- x# i' R& U# [
  16. uint32_t ifftFlag = 0;
    & F; }! Z% p; s3 H: H$ w. N  j6 E
  17. uint32_t doBitReverse = 1;" ^  a/ A; r: U& p  ?

  18. # d9 ^; t! u+ t/ h/ D
  19. /* Reference index at which max energy of bin ocuurs */
    $ }4 |' ^' e" m# y0 K6 M5 `2 B
  20. uint32_t refIndex = 213, testIndex = 0;" I& f; o0 u6 B

  21. # O2 O( @# j" C* M
  22. /* ----------------------------------------------------------------------* \( _& K- l' z/ _# C
  23. * Max magnitude FFT Bin test
    8 {$ A) E0 k# ], y2 e( w% h% q
  24. * ------------------------------------------------------------------- */
    ) X6 r" W; U( f0 B& e4 o$ k2 v

  25. 7 c4 x) |1 ~! I4 P( Q, ]
  26. int32_t main(void)
    ' ~/ C' M+ n& ?# i
  27. {2 Z$ c2 F+ `# [

  28. 6 c6 Q0 ]* k  v  Q% q! p
  29.   arm_status status;8 I/ k5 s6 p9 `# H) i
  30.   float32_t maxValue;! W( D6 F/ T- F7 v  r9 b) f
  31. ) M$ E- u0 I0 c/ t
  32.   status = ARM_MATH_SUCCESS;
    * ]1 B5 f6 S4 U, |4 f1 L8 l4 F7 v: @. ?

  33. 6 t8 X+ {: e3 F2 L6 Z* h; d
  34. //注意这个模块的参数的相关用法,下面这个将是我们后面进行调用的函数模块! b& b: u0 @3 U
  35.   /* Process the data through the CFFT/CIFFT module */& W" l) O9 I$ M+ O
  36.   arm_cfft_f32(&arm_cfft_sR_f32_len1024, testInput_f32_10khz, ifftFlag, doBitReverse);
    $ u3 g; `( q3 g3 x7 E; C4 |
  37.         //可以看到要想使用此函数,将调用4个参数- x5 k. {% Y% B( a
  38.         //参数1:指向浮点CFFT结构的一个实例。两种:arm_cfft_sR_f32_len1024、arm_cfft_sR_q31_len1024;* `4 _) r. N5 s$ W' D' u# z
  39.         //参数2:数据缓冲区的起始地址,偶数位为实数位,奇数位为复数( @3 M5 Y5 H& w1 C6 \4 A' m
  40.         //参数3:是否逆FFT标志位;1-是
    3 Q7 k; U) M  \7 y& h4 z3 |
  41.         //参数4:是否位反转输出标志位;1-是4 ]8 D' s* x' F1 ]) K
  42.         //注意:此函数将覆盖源数据,并将其修改为对应操作后的数据4 r5 M3 r, S& z/ V3 g

  43. - `* h: a- Y2 C' y4 M& f: f
  44. 4 T1 a. H) D5 J2 O
  45. //计算频域的幅度,由于对称性,只取前一半6 x. A, U4 E$ M, \+ L" L
  46.   /* Process the data through the Complex Magnitude Module for# e) \% G) t5 y$ n- N
  47.   calculating the magnitude at each bin */
    9 j4 K7 |) a$ p9 c2 ~' V
  48.   arm_cmplx_mag_f32(testInput_f32_10khz, testOutput, fftSize);! c( q% B8 ~' F# F
  49. ( x: p8 @' N; L
  50. //计算频域的最大值
    $ q9 q6 X9 a. t) B! W" a. c# \
  51.   /* Calculates maxValue and returns corresponding BIN value */6 i8 u+ J9 D. H! ]3 O# Q/ E
  52.   arm_max_f32(testOutput, fftSize, &maxValue, &testIndex);  j* n; c/ o2 }2 W# v9 q3 z
  53. / n9 X6 `" j. U, e( M! S
  54.   if (testIndex !=  refIndex)
    $ M  h$ K9 J0 f% G5 r
  55.   {
      l0 j+ _+ u2 n
  56.     status = ARM_MATH_TEST_FAILURE;
    4 A& B1 i6 n1 @% u8 g1 d3 [. }9 Z, \1 d
  57.   }
    + D& K5 o, ^& \/ E. d$ ~: k0 Z1 F

  58. 5 N* G$ n  G3 q0 i% S
  59.   /* ----------------------------------------------------------------------
      ^, M" ]! L3 m' {( I
  60.   ** Loop here if the signals fail the PASS check./ @) Y4 ^( ]0 V. |
  61.   ** This denotes a test failure4 A& A7 o% k7 U5 K
  62.   ** ------------------------------------------------------------------- */1 C- K) g: @$ t5 O; q

  63. 7 h2 ?) o! r5 J; d: b; `
  64.   if ( status != ARM_MATH_SUCCESS)
    " q! o) p1 T3 H0 ~
  65.   {
    & u6 r) l' h0 i' t
  66.     while (1);
      ?/ t) R3 F  e% N. `! s& h7 I3 z
  67.   }
    ' u; |1 p; z% `6 n# H
  68. / `# Y) d1 C5 M8 A4 \" }
  69.   while (1);                             /* main function does not return */
    3 P* b0 m: A* h- D
  70. }
复制代码
$ _2 o7 V2 w) G- W2 ?! D
实际使用后的测试
9 ?& G' K+ {* c7 F3 o2 A6 l% `; J实际使用的时候,我们并不是使用对应的源代码c文件,而是使用对应的lib文件。
) G4 t0 U6 N7 @+ V: y; ]当我移植到工程中后,等下发布效果,不要在意上面如何能够运行,弄完后自己再实现。7 ~  T5 O5 b- N5 q
$ k( h3 B& W% \. T& G$ ~1 [
python处理源数据得到频谱0 Z' ^2 N7 U% D4 t
源数据有2048个数据,但实际是由实部和虚部组成的,所以实际只有1024个数据点* ?7 H6 m. ]2 N+ z2 I" [+ B$ O
8 F8 |6 L! L- D! G6 T+ x
20210119142023633.png
# G" z+ a2 G  r' H' P6 v; ]$ v
; _5 [5 }/ n7 ^
python会得到一部分负频率的成分,但是一般我们只讨论正频率部分2 F  F" u( s$ r" W6 O" O, ~9 k% u

' ]2 V* q4 G. B8 C! L  k( ^stm32处理源数据得到频谱
; ?) @0 ]4 P7 o- b) ]" u$ F% w! P. W这是stm32通过串口上传至电脑,然后用excel绘制的图像
" h0 R  [9 V) {3 y) s) M
% n$ w$ b, m; d7 k. r6 f+ e1 F( V
20210119145755419.png
$ L; _( C# [; I2 g* h( a

8 h6 U; e1 G4 |# V两个结果一致
' }4 ?7 @4 T$ b5 H
; q3 w# i8 ~' ^! X( qFFT如何使用

. r/ s5 o8 a. E& }) o源数据------》调用相关函数-----》频域% c7 y8 j" ]% T( u$ z
频域中的各个点对应着相应的频率,幅值对应着当期成分的含量占比大小) _1 E6 q1 W, s4 d, b* q2 T

. ]7 E  {9 J3 Scubemx的工程建立
1 R7 ~. l/ x) h1 }3 @$ b. V2 Z" n和普通的工程一样,不过建立之前需要注意勾选,复制所有文件到当前工程中;如果后面发现没有我们要的文件,可能是这一步的问题0 C# a6 [4 F) Q
* P7 {9 e. _3 N
20210119151535753.png

2 N8 T$ X1 D1 P7 b4 C
' u8 r6 p. s5 o: w添加相应的库文件
1 J5 Z! D1 Y, H( q- a+ c先来查看工程文件夹中的一些文件
; ^  `. W+ E6 Z6 |, B$ j8 Y$ e
20210119152533686.png

6 g, ^3 W0 B8 p: r+ x* i1 W/ k# X- F$ X5 U/ J% m& W
这里面的文件目录是:1 K9 P. ?; ], J. }# ?
工程文件夹\Drivers\CMSIS\Lib\ARM- I# Q( f. O2 c' C
里面就是我们所需的库文件* D  b8 G/ [1 z$ @. d
$ C1 K7 ]) u/ d
下面添加到我们的工程中:
. ?& r+ x3 p: A0 H1 M3 d/ {
; s/ E  T, ^) u; W5 W( M7 Z3 V/ i
20210119153038371.png
3 ]5 t: X4 o9 S  V; R
; j, P* @) ~4 r' @* S0 R
然后设置添加文件的类型:
( \9 R1 ]  `9 F
3 ]6 }9 S) W/ @& J
20210119153208652.png

8 M1 C! O! m; |: e& j1 `6 @/ b
! W3 B* p/ B/ C" O' X3 \- V" N- P  O选中小端模式的库,然后点击add,如果选错了,后面将不能编译,然后点击关闭窗口6 F" T( E" i- A4 t+ Q% I( s3 d, H* p. J

1 u: T9 D0 Z( }% L1 X% C
20210119153345635.png

9 {, ]! s* q5 L3 f9 i" u
) g$ h# L! A* p& f
20210119153500594.png

5 v' B$ X4 U$ l4 r3 @0 I1 q7 U$ R& s* Z) J9 [
Keil工程的设置

- s" Q0 [+ y- ^' b* Q& Y) A开启FPU并设置编译器:
) s; Z( _- o& p  e将下面的东西复制到后面的图片中
+ }0 V' d+ ]2 {7 ?7 k' j8 R' M! V* j+ W4 r
  1. ,__FPU_PRESENT=1,__FPU_USED=1,ARM_MATH_CM7,__CC_ARM
复制代码

& Q% V8 `" Q' m' u6 R+ j# V" h然后添加一些文件% a: W3 l9 q$ G, k- I) p) q7 A

" q& t. H2 W* @* J
2021011916003141.png
$ |" w- c+ `0 a2 p9 `; w; }, d
) \2 I9 j) ?6 V9 `! t6 K/ }6 O" U! f
在这里输入
  l" Q9 Z$ @' x…/Drivers/CMSIS/DSP/Include* I" d2 _+ }7 `% L7 l

5 e: {  d1 I* t: C; ]* G9 S3 V
20210119160141855.png

9 V0 Q" V5 X& h
  O$ h# ~4 I$ _结果像这样) |1 B$ b& [3 ~
20210119160247877.png
9 N9 D' ^( u' F# b+ S1 {* g) o. ~
( @5 G( T* b3 m% g4 _# t
然后点击ok
1 G7 L5 n, M' f9 K
8 l9 J5 P$ {: P# ?还要设置一个东东
9 t* p. c, U/ W( Y3 u! E( K
+ m/ ^/ F9 [- w4 w, J$ B6 Q
20210119154104108.png

4 o  r* [; ~+ c9 A! U- ~; M
+ _" ]0 u( F9 D" U* ], T( U3 _7 u3 E* K, F6 n, v( o9 y
这里使用的是STM32H750,所以后面提到的ARM_MATH_CM7后缀是M7
) C! B& @2 i; Z' g5 n; w
% {. d* J( u) t: l) ]现在就可以使用库里面的函数了1 Y# h* [& L1 |: ], v9 [0 A! g
& [& U- d8 F& ~# }
下面是测试$ w  y  A$ U/ @2 P, p. u& [& c) P
3 k& K, i5 J* z5 I1 j9 D8 f, e
进行FFT测试$ l, X7 h% f6 y6 E( |
测试一
$ e# }7 c5 v) }, F" W7 n% S9 N5 G- _添加测试文件
$ D/ l. g4 H' ]' m2 O$ h/ y- d
使用的是官方测试文件
5 l9 S; \( `8 |: d2 k, I
  M' |. R: m* f6 Z6 @9 {, |
20210119154843902.png
$ |2 i! @4 P" K$ D  k) D* ~* B
4 Z5 ~2 z% t. I- \9 q1 o9 N( U
这是例程所在目录  \2 v& ]* W, T+ g/ G9 e  [3 }

" Q1 L0 n4 d9 A( j9 _0 y. K+ w
20210119155008969.png

9 z( \0 Z8 H- |. \& \3 z+ {2 E
- n/ g. z' w! s. n  f. @
20210119155111683.png
2 W; `% e# a. O& i  \

: V2 l9 ]+ S+ `" C% {5 e: ~
2021011915514321.png

& e9 `! ~5 O* D1 Q4 E& z1 u8 B( {0 E
然后打开我们的main.c进行编辑
7 y+ H3 p6 J( B, [- A% N注意:
' u4 x. p) C* N  t( w
# }2 U& T4 x6 m! M9 s. [6 d+ b我用的是uart4进行的串口通信3 A1 y+ L7 \' k  b! E
3 b( u+ C+ r1 ?) Y
20210119155432852.png

% ~1 R0 J3 m' V  @
2 ?/ ^2 d! c6 Z5 z- ?
- P9 V3 y5 h8 {* }5 x( q% S
  1. #include <stdio.h>
    1 ?% f7 l+ i$ H4 Z0 f$ s
  2. #include "arm_math.h"0 J1 |- W0 o- G1 E% M, y
  3. #include "arm_const_structs.h"$ j/ _1 o$ V# A# l
  4. - [0 l- M, _9 _8 J5 g
  5. #define TEST_LENGTH_SAMPLES 2048
    2 S, V, c, {+ B: e3 ~+ h* a
  6. 0 ^$ t- t- f5 u5 l% a, P
  7. extern float32_t testInput_f32_10khz[TEST_LENGTH_SAMPLES];//only have 1024% e# `' I; s4 p0 Y' u6 ?
  8. static float32_t testOutput[TEST_LENGTH_SAMPLES/2];0 g, F' l( L, }0 a3 a
  9. uint32_t fftSize = 1024;, J" A/ Y* ^$ V
  10. uint32_t ifftFlag = 0;
    % i# a" b" W. E# R
  11. uint32_t doBitReverse = 1;$ L! O& `! k! N  h3 q; H: D5 m) [
  12. 6 n' E3 b9 T2 G/ A" o
  13. /* Reference index at which max energy of bin ocuurs */
    & q- ^2 y, d7 q. _2 j+ h; p. [! f
  14. uint32_t refIndex = 213, testIndex = 0;
    & i/ k4 C: C/ N* F5 D- B/ t
  15. 1 F+ _6 Y8 g4 G2 j1 M2 [1 m0 K

  16. . g& l0 g* R8 j3 N1 V2 s1 R
  17. int fputc(int ch,FILE *f)
    ( ^4 ^  V# C. A' E
  18. {
    ( P: A4 `( R6 S8 u! r
  19.     uint8_t temp[1]={ch};
    9 s  X, s$ Y" ~+ O0 |
  20.     HAL_UART_Transmit(&huart4,temp,1,2);        //uart4   一定要修改为自己的串口!!!!!!!!!!!!
    * n& v8 c3 J( r- Y4 v9 c9 ^
  21. }
复制代码
2 K5 m8 J' b/ T
然后
$ _5 B/ @! G# G7 x$ [0 G: I6 I5 P9 w% X$ \4 B/ V+ F
20210119155723560.png

; v& p: r; y; U6 k0 h. G

  1. 9 ?- v1 U( `' T$ k
  2. arm_status status;! n! `! i% g# ~$ O" _
  3.   float32_t maxValue;' n/ D3 C# [  }8 W. M  P/ `

  4. 6 J6 I; a0 R$ K7 n1 ]
  5.   status = ARM_MATH_SUCCESS;
    9 h) J, k6 q( N  q. a% p( ~

  6. . Q2 s- L$ T: r
  7.   /* Process the data through the CFFT/CIFFT module */8 d$ `' K5 n! c, p! ]1 `6 ?
  8.   arm_cfft_f32(&arm_cfft_sR_f32_len1024, testInput_f32_10khz, ifftFlag, doBitReverse);
    * t! R2 p) D  Q# l6 A

  9. . X9 i8 Z6 P5 [3 W4 k+ K/ h
  10.   /* Process the data through the Complex Magnitude Module for
    ! p- t' A# g: V& d. l
  11.   calculating the magnitude at each bin */
    5 a* j" {' [& G; \
  12.   arm_cmplx_mag_f32(testInput_f32_10khz, testOutput, fftSize);
    2 m" o% K" ^" e" P

  13. $ W6 c/ G( H( A  |$ k0 s3 N
  14.   /* Calculates maxValue and returns corresponding BIN value */4 |! q( {9 [, I
  15.   arm_max_f32(testOutput, fftSize, &maxValue, &testIndex);& @% i, T9 I6 m3 a- V, g7 f$ A9 Y

  16. 6 v$ G( l, Z# t6 o- `! e
  17.   if (testIndex !=  refIndex)
    7 U4 B4 o2 q+ y) C
  18.   {8 b* k* ~+ n& C5 G$ k! ?
  19.     status = ARM_MATH_TEST_FAILURE;
    - b; m) J/ {' `3 o1 D
  20.   }- x, @5 s7 `7 V3 s' n

  21. 6 Z" O" U3 J1 R3 y' R
  22.   /* ----------------------------------------------------------------------, w9 f) P0 e5 X( B$ f5 M
  23.   ** Loop here if the signals fail the PASS check.; S; G  x8 h8 m5 F- c. n
  24.   ** This denotes a test failure! a/ \; N! d  W3 _( p) O
  25.   ** ------------------------------------------------------------------- */- v# Z' h6 C3 `( ]  {% ~' \, j

  26. 5 I1 v4 c5 q" ~8 b
  27.   if ( status != ARM_MATH_SUCCESS)
    ; f5 _' J6 z. n8 g1 T
  28.   {
    6 L; E0 [# }) t3 r/ V8 u* u
  29.     while (1);
    7 |5 p: [' h0 j0 D, [( c
  30.   }
    / k9 o* r" D; y8 f/ {7 w
  31. # B9 e7 V  i( D8 t" z
  32.   while (1)! [6 W- U/ C! c# W8 ?
  33.         {
    0 I7 q% S6 A# t5 K9 n! D1 Y9 S) }
  34.         //printf("hello\n"); " ~3 w) ?8 `' N3 j" K2 U
  35.         HAL_Delay(5000);
    : ]& V2 A- s& u! l% h
  36.         for(int i =0;i<1024;i++)
    ) I; l5 }: Z" v
  37.         {printf("%f\n",testOutput<i>);' o* O$ d- ?- m  G1 N6 E
  38.         </i>HAL_Delay(10);+ q$ s, Y$ ]  l3 ^. p% h1 s6 x, V
  39.         }
    ( A( p. D, E$ }, I& t! T6 P# ]+ d
  40.         while(1);$ P6 ?  p; N+ V, G2 M9 ?$ p0 [3 m
  41.         }
复制代码
3 P) d1 t# s& |' \1 n
这里完了就可以编译了
* O+ z7 L$ A! c* ^* |% H2 I4 T, ]/ N
5 ]" f* r% p4 k: X结果探究: v8 Y1 d0 |0 c; {& Q
打开串口助手,等待5s后会发送
! \/ Z# h# P/ C- u; }  D* P# S7 W. E, j2 F( u: \
20210119161237405.png

0 T; A) ]8 v1 B& E2 F* ^( n+ V, q
5 S4 S, G6 k9 h8 N3 Z& U. t: a0 s/ y: z5 p然后提取之后就是我们要的数据了,可以保存后用excel来进行绘制,就是我们上面的图像了
# O' P8 r# @: O9 z: F( n# I$ T2 V2 Q/ x: c1 R0 m/ e% H
; p& k7 h' O: J( n, v; K
20210119153944812.png
收藏 评论0 发布时间:2021-12-26 16:43

举报

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