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

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

[复制链接]
STMCU小助手 发布时间:2021-12-26 16:43
前面是关于怎样运行fpu的,以及相关的环境配置" |1 n- `3 I3 n( z4 C

( h- k" C, j; t3 Y2 G$ QFFT的测试
- N( Y+ z9 K! C7 l! s9 b先看一段关于官方的FFT测试例程
/ F6 J& K) [* c# C
里面添加了相关注释
- a0 R  x; k- n
" N% P7 [. R$ ?. b' z& t
  1. #include "arm_math.h"
    4 y. A3 E& f6 `  X) x
  2. #include "arm_const_structs.h"
    8 r/ Z0 Q2 t2 |( o7 Z: B4 F
  3. + N9 X9 p5 T# B8 L9 f' C
  4. #define TEST_LENGTH_SAMPLES 2048: @  e5 Y% }7 o  O
  5. ; t2 c7 J+ n; [9 ?( Z# l  }
  6. /* -------------------------------------------------------------------  V% `6 x  q  W% L0 Q; s
  7. * External Input and Output buffer Declarations for FFT Bin Example; F% v8 n4 z& Z
  8. * ------------------------------------------------------------------- */- O$ P7 X" ~9 v( C4 F) K! S! k
  9. extern float32_t testInput_f32_10khz[TEST_LENGTH_SAMPLES];- J8 R9 P1 ?  s7 Q+ n! D8 \
  10. static float32_t testOutput[TEST_LENGTH_SAMPLES/2];
    . S$ r) i( S& c. ]4 J

  11. : s/ Y: _+ W& }3 V4 h, a
  12. /* ------------------------------------------------------------------# D  d/ |) U+ w" M/ T% @
  13. * Global variables for FFT Bin Example, O7 \0 v/ A4 g" z- u: Q3 T
  14. * ------------------------------------------------------------------- *// }  s( y3 v2 K$ d. ~/ A
  15. uint32_t fftSize = 1024;: M0 I( \$ Z$ A$ V
  16. uint32_t ifftFlag = 0;# s9 d. h7 p- ]2 d
  17. uint32_t doBitReverse = 1;- N# ^: I+ L( t4 Z/ H

  18. , Y* g% n- _3 U) ^! }- v
  19. /* Reference index at which max energy of bin ocuurs */6 U$ \; y5 B" A* N( j
  20. uint32_t refIndex = 213, testIndex = 0;
    1 [' y9 i- ~* k$ X4 i9 U8 y3 K
  21. 8 n8 G3 I; i& R* d
  22. /* ----------------------------------------------------------------------
    2 L7 w- \& c9 o& P
  23. * Max magnitude FFT Bin test
    ! h( y6 q# n$ z! Z6 i
  24. * ------------------------------------------------------------------- */
    ) ?6 u9 Q7 C, F+ R. O

  25. 1 g, `! z+ h$ R; O
  26. int32_t main(void)
    + c! P* C( v4 f- y3 W8 X
  27. {2 X* o8 m4 z, O+ Y5 Q, ~

  28. & K+ w& X$ }; M* d2 o; G5 I
  29.   arm_status status;
    2 Z/ c+ B' b: Z( S! m4 M7 f1 k
  30.   float32_t maxValue;2 y! W. c/ E! h" ^9 p' J

  31. ! `. R" G9 r, B3 G. u& {. n5 \! P
  32.   status = ARM_MATH_SUCCESS;
    ' v0 [+ f$ q5 [4 A
  33. " ]# S0 B7 a$ [  H# P' l
  34. //注意这个模块的参数的相关用法,下面这个将是我们后面进行调用的函数模块
    * L: n$ g4 p9 _4 J# L3 U! y
  35.   /* Process the data through the CFFT/CIFFT module */6 n4 [; D8 L7 ?$ f
  36.   arm_cfft_f32(&arm_cfft_sR_f32_len1024, testInput_f32_10khz, ifftFlag, doBitReverse);
    + t% H7 H# Z: j5 g- B( ?+ I  r1 l
  37.         //可以看到要想使用此函数,将调用4个参数
      l0 d, [: z+ j$ @" a
  38.         //参数1:指向浮点CFFT结构的一个实例。两种:arm_cfft_sR_f32_len1024、arm_cfft_sR_q31_len1024;
    + l/ x2 p0 x+ d# h
  39.         //参数2:数据缓冲区的起始地址,偶数位为实数位,奇数位为复数
    3 y! U! D/ [5 _" w) u( c
  40.         //参数3:是否逆FFT标志位;1-是
    4 ?1 ]6 @: v- m4 y8 K
  41.         //参数4:是否位反转输出标志位;1-是
      Z+ p" [* C2 t
  42.         //注意:此函数将覆盖源数据,并将其修改为对应操作后的数据
    2 I$ L4 o4 N0 J: _- T
  43. . S: W4 C9 O, y

  44. 9 V" g- F3 d4 b+ [4 f* M" q6 q
  45. //计算频域的幅度,由于对称性,只取前一半
    ) F- D8 }3 E0 ~% w% {( |. ?
  46.   /* Process the data through the Complex Magnitude Module for
    / c1 d, l# T; i1 R- l+ N
  47.   calculating the magnitude at each bin */, ]3 j4 {  `) B
  48.   arm_cmplx_mag_f32(testInput_f32_10khz, testOutput, fftSize);1 @" w) I8 p: Y$ g/ ^2 S
  49. / I4 T7 N9 n8 }: h: {
  50. //计算频域的最大值
    " U! p& v, k$ t8 p% x
  51.   /* Calculates maxValue and returns corresponding BIN value */
    ) Y9 K6 e: E6 t# D- x) Z
  52.   arm_max_f32(testOutput, fftSize, &maxValue, &testIndex);" k$ ?) F7 ^' a0 j2 M( x
  53. ; F$ r9 M$ L7 y+ U
  54.   if (testIndex !=  refIndex)
    2 L5 \! P/ s+ T. o6 |) ?
  55.   {
    0 _; t* g) E( w
  56.     status = ARM_MATH_TEST_FAILURE;
    ; @- \* d2 K0 M$ R
  57.   }- o! p8 u: O, _- H. }
  58. ) p2 g7 _5 ^, H. K! Q* d2 p
  59.   /* ----------------------------------------------------------------------& q3 n  s3 ]9 ~0 v( ]* ^5 C
  60.   ** Loop here if the signals fail the PASS check.* [6 W, i: {# d2 n2 r
  61.   ** This denotes a test failure0 L' {3 Q1 z# v9 ]) C7 n
  62.   ** ------------------------------------------------------------------- */+ S' ?" G/ u# ~& g5 I5 d
  63. * ~( \1 S+ _6 Z) n
  64.   if ( status != ARM_MATH_SUCCESS)5 N1 x& S* Q/ u' A9 X2 v
  65.   {1 Z. E! A% V, W2 e
  66.     while (1);7 E0 ]" p: p5 o
  67.   }
    2 S( e5 }% Y7 _2 |
  68. " ^! t8 D3 W/ T0 N
  69.   while (1);                             /* main function does not return */
    0 c0 q8 u' |( m! H, ]
  70. }
复制代码

: E9 R! [1 H/ g/ Q- H实际使用后的测试9 R6 M# y, [, @. ^1 K! I9 b+ K1 }
实际使用的时候,我们并不是使用对应的源代码c文件,而是使用对应的lib文件。. ?8 p) l$ l+ Y
当我移植到工程中后,等下发布效果,不要在意上面如何能够运行,弄完后自己再实现。
$ M8 Y/ p4 Y3 z& O
) j8 v( k' p) i9 Rpython处理源数据得到频谱
1 ?: d! ~8 M( }9 d1 X源数据有2048个数据,但实际是由实部和虚部组成的,所以实际只有1024个数据点4 C" q; z! M6 i3 w+ `. o0 I
+ o- P! \0 _+ j/ R5 H3 t( S
20210119142023633.png

# U4 a7 ]. c+ [  P7 }* G' M, V$ K3 q' @8 h9 ]( F/ r
python会得到一部分负频率的成分,但是一般我们只讨论正频率部分: H' y, t+ C/ A

+ g1 M1 E4 ~, Z& Q2 N! n7 mstm32处理源数据得到频谱
, `0 J5 T. t+ {6 ?$ z这是stm32通过串口上传至电脑,然后用excel绘制的图像
: l" }+ B' r7 Y0 T+ Z( w
6 P  `$ }- q$ o4 l: |& D
20210119145755419.png
! W" H6 `2 F4 ]8 H2 b  m6 T

  g% c  k/ \8 V4 H7 h- |" q8 F两个结果一致0 o4 ^# x- a. S$ m$ @
# y1 Z3 ]# A4 g2 z* J
FFT如何使用
: \6 W7 o- M( o: C- S% q0 s4 q
源数据------》调用相关函数-----》频域* T! T' L, }, g: Y
频域中的各个点对应着相应的频率,幅值对应着当期成分的含量占比大小# A$ ?8 b, d- E# E& @+ ?& X3 l
5 r6 ~- D! V4 k8 l% q4 p
cubemx的工程建立
% l3 |- u$ o$ a: t: o和普通的工程一样,不过建立之前需要注意勾选,复制所有文件到当前工程中;如果后面发现没有我们要的文件,可能是这一步的问题
. ]8 a; w! C4 [; I% [2 D+ U" L" F7 l! x3 T$ K; |
20210119151535753.png

# }8 u* H5 @8 j2 h" R. ]& W
' q2 W) T* S5 M! m4 d1 r3 ~# R4 E添加相应的库文件
% d; Z) Y5 L+ V  r) e+ v2 ^先来查看工程文件夹中的一些文件4 l" z# B( C- ?3 m" C9 ^4 a# m- `, W
20210119152533686.png
. M. v3 [( K' I) k* j- D7 J
1 i* C& Y# j/ ~) g" Q+ D. h
这里面的文件目录是:
6 ]1 m8 a1 q- ^/ T' N4 R7 J工程文件夹\Drivers\CMSIS\Lib\ARM
$ u  e/ {0 G& o; p6 g1 o+ e里面就是我们所需的库文件
9 r& F2 i) ]+ Y+ F1 j' _) v
6 t" c% s7 ~/ C下面添加到我们的工程中:
+ f0 J  q, \  ^
( `9 q1 n4 p; D) {0 w( T  p
20210119153038371.png

  |/ s# q6 u' A" e9 v) |0 g2 E4 O6 Y3 I2 L2 d1 ]3 c9 M
然后设置添加文件的类型:
1 _+ `* u- h% K3 r
3 @' x8 l, N8 M/ j' D  B- A7 I
20210119153208652.png
, C: F9 r0 E* m9 Q2 I: S+ ]
4 `1 G* U$ D) S% x4 I
选中小端模式的库,然后点击add,如果选错了,后面将不能编译,然后点击关闭窗口. Q$ G- Z3 x4 z9 K( [

# f3 P- ?4 k# D" t( e% B! q( ^: f0 i
20210119153345635.png

  T( P. X8 a+ A0 e# [9 l: G6 @# B0 @9 D8 M, V, U
20210119153500594.png

  |/ j: r( R- f) N/ N5 C$ g
/ M) D+ J$ g8 X6 n8 s# dKeil工程的设置

5 u- D% Q9 y1 J# O' V开启FPU并设置编译器:! O' b5 a8 h1 k  e" G
将下面的东西复制到后面的图片中# p! N. s* G" G# S' L3 Q+ W

: y+ s  I4 [5 l; R2 d  L) K
  1. ,__FPU_PRESENT=1,__FPU_USED=1,ARM_MATH_CM7,__CC_ARM
复制代码

$ a0 a! |  a; i2 A然后添加一些文件
: i: {9 I5 W9 B. Z* i1 S  |
+ b! a) u6 E7 j+ }/ T4 Z0 W
2021011916003141.png
& D- R* K; p7 t6 {7 ^  [
6 k! |3 m- s" |: u% M) O* S
在这里输入
! Q/ K4 l3 u9 a2 J7 I…/Drivers/CMSIS/DSP/Include
+ `. @# x5 g" x
1 [* g% p: J$ R# t( S( q) B
20210119160141855.png
' G2 {+ {4 j% y0 s

- g! j: h' p' q2 d" K1 s" D" E7 ^结果像这样
; G# y; [" T- x( q% p
20210119160247877.png
1 [2 S) S) _' j+ g7 n
: L; O2 s: {* R+ o4 `- @: I
然后点击ok& z- |0 `& Y/ x- l! y3 `3 C: g) d
, s) [8 u" R0 A& W2 E
还要设置一个东东
+ _7 H, C0 h- I: c" s
3 Q2 S" Y  \. A& }& W8 d& o
20210119154104108.png
  I0 r" D3 r' i) u8 V  V- u3 B

) S6 E5 k& I  u( S" ^( }% z# c( B: T$ z8 \0 k
这里使用的是STM32H750,所以后面提到的ARM_MATH_CM7后缀是M7, S! p) j! v' W5 K! u# @) I# _
; }4 U) d1 D+ C- p$ v3 h. ?
现在就可以使用库里面的函数了6 O5 v( ^% e2 m+ O# G8 ~2 z, L
$ ]6 T/ ~' H4 C# s  v
下面是测试( p& m, t3 C4 Z1 Z; e9 I

& N: r0 h6 O9 H6 l" X; G  I进行FFT测试
0 L) ^& m: ~4 b# X) |测试一2 z) F. ^+ O0 T! P
添加测试文件

; X5 {: u$ {2 d: W使用的是官方测试文件# K! H1 V: C2 Z# t* l% p' e. S
& O* s; U/ Z( v* D* R# r
20210119154843902.png

, B0 i" M9 y# Z3 W. Q) p3 o3 ^0 g: [# I0 E$ v8 E
这是例程所在目录
1 }; M! V7 D: b9 A0 O5 d6 G2 e! M  l2 d, v' t% U, K* ]
20210119155008969.png

, M# {7 K, K0 O- j6 I( b2 F* c  y7 S5 A. T! N, u; ^
20210119155111683.png
# ^& j0 p* e2 z6 h$ |

& i* {& K6 n2 \. a5 j7 R8 ?: c
2021011915514321.png

" |  Q; g! l! c! B& a& e4 `7 v9 {: g
) e* N! x, D- K. J8 F. d2 B然后打开我们的main.c进行编辑
! J; m1 \9 {: e% _注意:$ i7 |% ^, j% T
( Y$ Z" i* Y8 M% O$ u
我用的是uart4进行的串口通信
3 B& @3 N4 Z& `5 g1 P
% s* n# D7 X! G2 k! [" \
20210119155432852.png

, o6 y$ z8 J* S5 ?) _) q- A2 b) z- h; z  @0 |" Y# e. w7 X

* }* B+ b& R3 i
  1. #include <stdio.h>
    0 W% X/ N6 _' y* ^5 s0 x8 F
  2. #include "arm_math.h"8 I- X9 S$ u8 l
  3. #include "arm_const_structs.h"% H: {- m, m) e2 D: c

  4. ! C) M- E. U6 B! l* w& l6 q
  5. #define TEST_LENGTH_SAMPLES 2048
    - U" y5 p& L( [# i

  6. ; C" t7 J- C  F  P
  7. extern float32_t testInput_f32_10khz[TEST_LENGTH_SAMPLES];//only have 1024
    5 }/ x! \( T. ?4 v
  8. static float32_t testOutput[TEST_LENGTH_SAMPLES/2];$ e2 ^! R: r5 ~1 d
  9. uint32_t fftSize = 1024;: G% [! U: q& M! o
  10. uint32_t ifftFlag = 0;
    : s! M3 m, ^; ?: `
  11. uint32_t doBitReverse = 1;
    3 r% h7 b& v2 H0 \& R) ?" ~
  12. 2 e# |5 k( q) T* Y
  13. /* Reference index at which max energy of bin ocuurs */
    ; q+ T" a# o2 d: A, Z
  14. uint32_t refIndex = 213, testIndex = 0;
    0 w# ]& n/ m' f
  15. ' \; ^3 k$ n& J
  16. % Y1 s* k! H: y4 B3 C8 d9 Y, z
  17. int fputc(int ch,FILE *f)
    % O5 I. V6 Y& W& H- p
  18. {
    % e1 ^; E! d9 \; }
  19.     uint8_t temp[1]={ch};& I: l4 c$ t* Q4 a4 Y
  20.     HAL_UART_Transmit(&huart4,temp,1,2);        //uart4   一定要修改为自己的串口!!!!!!!!!!!!$ S7 Y; m8 i- h9 {, r1 r
  21. }
复制代码

( Z+ d2 `% ]0 s7 z# A. w然后5 w. f. s; A3 H

0 u. J- N9 k! W$ f
20210119155723560.png

7 g* ^8 E4 }+ i; u8 _9 l! N  ^% Q
  1. & [, u# d$ e5 N# A& D  p
  2. arm_status status;  P7 p, h9 L) N0 o
  3.   float32_t maxValue;
    % ~7 @6 m9 v4 Q  N* o
  4. 2 ~. r0 d/ ?4 N" m/ k
  5.   status = ARM_MATH_SUCCESS;) p" Z( F2 u/ p* t8 y" `
  6. / u9 k2 `1 O) z) O5 y/ J, J' e
  7.   /* Process the data through the CFFT/CIFFT module */
    " D" t* C7 F+ g6 `' B& _6 M" B( C
  8.   arm_cfft_f32(&arm_cfft_sR_f32_len1024, testInput_f32_10khz, ifftFlag, doBitReverse);4 h$ F7 m8 ?4 W  N

  9. : J& @  I; A/ V4 c* \! }$ [; E- r6 C
  10.   /* Process the data through the Complex Magnitude Module for* b5 N2 T' N7 ]! m& J# @# F! z
  11.   calculating the magnitude at each bin */8 m$ a) c- K+ I  J5 I; L/ C
  12.   arm_cmplx_mag_f32(testInput_f32_10khz, testOutput, fftSize);
    % D; K: x# U* P& `4 y5 y. F

  13. & b# B% `- Q2 h* n& R$ k. D
  14.   /* Calculates maxValue and returns corresponding BIN value */6 x  ~# C0 q$ v: G4 I- f
  15.   arm_max_f32(testOutput, fftSize, &maxValue, &testIndex);" X; E. F/ o8 e' U9 H
  16. 7 h$ d5 O& p+ Q: z+ ~$ M
  17.   if (testIndex !=  refIndex)  D& h1 B/ v# H7 f9 x, U# z+ H
  18.   {; k( K+ A( c$ @. a( W  D
  19.     status = ARM_MATH_TEST_FAILURE;  U5 F0 |6 ~* Z! Z  V0 J
  20.   }9 ?+ H' g- Z: S+ j2 K0 A
  21. + k- W2 e  a. T& l  }" @
  22.   /* ----------------------------------------------------------------------
    2 r2 F1 w' {) v+ a- n9 P, h& z
  23.   ** Loop here if the signals fail the PASS check.1 P6 \- `$ Y- {$ p9 q2 Y) X- }
  24.   ** This denotes a test failure, X4 V0 i6 p8 l# ~8 a7 f6 i# {+ Z
  25.   ** ------------------------------------------------------------------- */
    4 X- \$ K. `7 e( U

  26. 5 K6 x+ v3 r+ H& n
  27.   if ( status != ARM_MATH_SUCCESS): u1 R- Z! Z& J2 h9 M5 F, J
  28.   {; x) n5 {9 z: w9 v
  29.     while (1);2 @" O( |9 L! F( I
  30.   }
    / h4 W7 `  A+ H. c2 u/ z, g1 @

  31. 6 Q' N- y! {3 Z% x
  32.   while (1)
    # O+ q+ Z+ Z2 [# q
  33.         {
    6 f9 P3 g2 l- A+ `
  34.         //printf("hello\n");
    0 o( ~( P' H; Y3 M, W6 S6 j$ Y
  35.         HAL_Delay(5000);
    ) ^) C( g# z5 x9 R" m/ q5 |
  36.         for(int i =0;i<1024;i++)" M- q" @2 i& h+ R* L/ H
  37.         {printf("%f\n",testOutput<i>);- a$ ]9 |* v! e! p
  38.         </i>HAL_Delay(10);
      b" m4 Z% ?6 E# l1 e7 ]: k
  39.         }7 u& z2 P- b$ c  H) \, {
  40.         while(1);. E6 t7 }6 [3 y5 Y& t
  41.         }
复制代码

# k# D' F" ?* X1 d! Y/ @- V8 y这里完了就可以编译了
  ]# c, {0 Z0 \% D( F
2 [- o* D: ?! _2 Q, |* R5 k结果探究
% s. q! Z' a, M# j4 {( u- v- I  ]/ d打开串口助手,等待5s后会发送
3 V8 G& }) Q! P. h! |1 ~
* P. T* m. G0 C  ^* g0 Z
20210119161237405.png

; u/ t! d. \! o6 w& ~0 C) v4 Z: V" G
然后提取之后就是我们要的数据了,可以保存后用excel来进行绘制,就是我们上面的图像了
! J6 l& z: p9 Y" ^$ O5 v# [" ~( \' W# Z, C
: `" m. |6 H. ]* q+ |9 U3 @( h
20210119153944812.png
收藏 评论0 发布时间:2021-12-26 16:43

举报

0个回答

所属标签

相似分享

官网相关资源

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