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

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

[复制链接]
STMCU小助手 发布时间:2021-12-26 16:43
前面是关于怎样运行fpu的,以及相关的环境配置' @! F$ A- q/ P% O! z  u- |

* k- V' V+ R3 E2 {2 C) NFFT的测试
* d% T* [6 M5 R3 t+ w1 |* \先看一段关于官方的FFT测试例程
+ P0 \* [( u+ Y4 l
里面添加了相关注释: a8 T3 i$ k. O" D
6 f1 {; V$ j4 q7 s
  1. #include "arm_math.h"- [9 f# u2 j% o/ b2 v2 q
  2. #include "arm_const_structs.h"
    * H, P7 ]9 p  h0 w0 C( ^
  3. ; H' d7 Z$ F+ \8 x, C% S5 }1 X
  4. #define TEST_LENGTH_SAMPLES 20489 b" \7 D2 q0 K# E& V) y

  5. % H: i* {0 B! j% b; f& V: ]8 s
  6. /* -------------------------------------------------------------------' P( B) V0 C( `8 R" p1 \! e
  7. * External Input and Output buffer Declarations for FFT Bin Example2 L9 t" L9 i: Z9 g" T' H
  8. * ------------------------------------------------------------------- */
    ' f* T% z( _1 P1 z  e% P4 o& f% _/ H
  9. extern float32_t testInput_f32_10khz[TEST_LENGTH_SAMPLES];
    : g' i; P- q9 w# t
  10. static float32_t testOutput[TEST_LENGTH_SAMPLES/2];
    + G8 t$ ?$ R  n5 r, U5 g
  11. : Y- z: o: p& M6 p" l, I- C/ i
  12. /* ------------------------------------------------------------------4 w1 _1 ?+ d+ I. t7 z6 g* w
  13. * Global variables for FFT Bin Example
    5 J- E8 a0 o3 \0 b( H3 s+ {
  14. * ------------------------------------------------------------------- */
    8 K" E/ ~0 H/ {: H; C; v/ y6 R
  15. uint32_t fftSize = 1024;% m( P, @: T& N% |3 i2 D% ?
  16. uint32_t ifftFlag = 0;
      A# k* C+ H, ]  A
  17. uint32_t doBitReverse = 1;
    3 y3 _1 D. g& G: E7 F

  18. 4 y3 P7 C0 q, Q: W) D; D
  19. /* Reference index at which max energy of bin ocuurs */# W5 A& C. Y3 }5 s( H
  20. uint32_t refIndex = 213, testIndex = 0;; R; ~4 Y) t0 a% N6 R# v4 M9 [  W

  21. 7 m; ^/ b: s& F: C+ S+ C
  22. /* ----------------------------------------------------------------------+ |1 y! y. o4 @& u( C4 V; M: a
  23. * Max magnitude FFT Bin test2 n( Y3 \4 y$ j% H) ]
  24. * ------------------------------------------------------------------- */
    6 r' y( B/ i+ B& S; N$ {8 M
  25. . f0 u' y+ O' H) R8 Q) t9 d
  26. int32_t main(void)# l8 |, O* }& n  O' d3 c
  27. {
    $ M7 }# f. |; n7 X# S5 f4 u

  28. # \$ i3 X5 i% J
  29.   arm_status status;
    0 b- u" ~: U2 M. U
  30.   float32_t maxValue;2 i& O& y( a7 I. B" E0 e% Z6 O
  31. 7 i( W: }9 t! T1 |6 q
  32.   status = ARM_MATH_SUCCESS;
    : X# s: N7 b4 [7 }! y, s6 W" G

  33. . \$ Q0 l' ~' @& E6 b
  34. //注意这个模块的参数的相关用法,下面这个将是我们后面进行调用的函数模块6 [) ^- `0 c: }. _6 T2 s" |
  35.   /* Process the data through the CFFT/CIFFT module */
    ' _3 c5 m, l9 l/ H: S. s
  36.   arm_cfft_f32(&arm_cfft_sR_f32_len1024, testInput_f32_10khz, ifftFlag, doBitReverse);5 q& U- d0 U8 O6 G% ?$ e: k
  37.         //可以看到要想使用此函数,将调用4个参数2 r1 O$ `! J3 S2 d4 C6 R# N1 z
  38.         //参数1:指向浮点CFFT结构的一个实例。两种:arm_cfft_sR_f32_len1024、arm_cfft_sR_q31_len1024;
    % b: a1 U1 p- v. q6 B+ h7 e4 H. H! \
  39.         //参数2:数据缓冲区的起始地址,偶数位为实数位,奇数位为复数1 J9 U7 B( o, O
  40.         //参数3:是否逆FFT标志位;1-是) Z. V4 q9 x0 u" c
  41.         //参数4:是否位反转输出标志位;1-是
    " L3 d3 [# v4 p) [
  42.         //注意:此函数将覆盖源数据,并将其修改为对应操作后的数据
    ( M4 M/ g' n# A& z/ h' \( e
  43. ' q5 }4 g9 N' V' R  i% M' S

  44. ! G4 h3 c! ^/ a+ K2 ]9 n' X
  45. //计算频域的幅度,由于对称性,只取前一半
      |: T8 D& ~- X& T
  46.   /* Process the data through the Complex Magnitude Module for# E/ z9 K5 b0 `7 H: I5 E3 X% Z
  47.   calculating the magnitude at each bin */* B5 R: p* U2 M! Y* L2 ]
  48.   arm_cmplx_mag_f32(testInput_f32_10khz, testOutput, fftSize);
    6 [% c7 R- z* c# T

  49. 0 \% |. U' E4 J# O
  50. //计算频域的最大值$ ]5 ?7 D; a# m$ n3 k0 _; U
  51.   /* Calculates maxValue and returns corresponding BIN value */& L9 w) {3 Q$ n- F! R
  52.   arm_max_f32(testOutput, fftSize, &maxValue, &testIndex);
    ) `# d$ L5 P9 g& a, k3 z$ G

  53. . U: y3 k" S% W! B* l3 y- \
  54.   if (testIndex !=  refIndex)
    7 h: c8 Q, e5 ^
  55.   {4 E) \+ n4 h# H9 P& U( h/ Z( K
  56.     status = ARM_MATH_TEST_FAILURE;
    ; W1 [; s; ?( ~5 c
  57.   }3 H) @. U- f) ~3 I, ^; A5 W' m

  58. ) s- ]3 J& k+ U: E) G3 |" e- X- C
  59.   /* ----------------------------------------------------------------------  F/ X5 @5 e7 L3 T1 x, y" d
  60.   ** Loop here if the signals fail the PASS check.
    ' A: H! ?1 x5 H" \* ]$ T+ |
  61.   ** This denotes a test failure
    8 Z& t( Z; S" z+ j2 X7 U- m( }* L
  62.   ** ------------------------------------------------------------------- */; h3 z# \* ?6 |) _4 t) F: r) f

  63. : e, S, ?; P, u4 ?
  64.   if ( status != ARM_MATH_SUCCESS)) D# z! t% W; z8 H
  65.   {
    . _8 r' b3 X4 i* Z" W% g
  66.     while (1);  L3 T# k' D& N0 F6 x' F$ r* J
  67.   }
    6 i) v2 D' e* n' e' q+ [
  68. / S2 i3 E, v0 K" F  y8 z& t
  69.   while (1);                             /* main function does not return */3 Z7 u* s9 ~! q( Z2 P& L7 z
  70. }
复制代码
" ^5 T; Q# h% y4 u3 L' r$ k; l# ]( u
实际使用后的测试+ G1 g+ n2 F$ j" e' {8 l- E
实际使用的时候,我们并不是使用对应的源代码c文件,而是使用对应的lib文件。# ^$ o8 U( s) ^( ^; V& V4 Q
当我移植到工程中后,等下发布效果,不要在意上面如何能够运行,弄完后自己再实现。' s8 c: J; t$ i5 F+ ^) Q

' q+ F8 O/ I% v$ fpython处理源数据得到频谱, E3 X* V( H4 R) R8 X" q1 f5 a1 o
源数据有2048个数据,但实际是由实部和虚部组成的,所以实际只有1024个数据点
' `6 n* ^$ ~' z2 a0 |
8 ~+ A( \2 B' F) E
20210119142023633.png
0 l* @9 j  G4 z& H
  m3 I: ]. W( W# O% W5 G
python会得到一部分负频率的成分,但是一般我们只讨论正频率部分
  S- i! {# W" k1 H( Y/ s) f8 d2 i8 J  Y
stm32处理源数据得到频谱8 }7 G1 x: f! a+ x6 i4 s2 _
这是stm32通过串口上传至电脑,然后用excel绘制的图像
! q9 U9 B3 }$ p5 G
' X0 T1 d0 S% }! a  r
20210119145755419.png

6 [: I/ ~" S( I6 Q* U
' N* i4 }8 i  R6 I. ?两个结果一致
9 H; x, _# e/ t2 r/ _
' Y8 V7 N7 G# l9 ~* H; S6 ~& t4 Q( dFFT如何使用
7 N3 a- u+ p4 y
源数据------》调用相关函数-----》频域  }9 s3 D: a: l$ G7 L; `1 @
频域中的各个点对应着相应的频率,幅值对应着当期成分的含量占比大小* w7 w1 K' l- b
1 i7 U# c( L6 N' K9 A( O; f8 z* l
cubemx的工程建立
& u) M* i2 W4 F+ J和普通的工程一样,不过建立之前需要注意勾选,复制所有文件到当前工程中;如果后面发现没有我们要的文件,可能是这一步的问题- ?$ E; }: W; R1 u! K9 o" L
! M3 C$ z: w& m. I8 r% G" q" L
20210119151535753.png
$ u) R  R0 Z! Z6 m* F  q! O

+ r! ^  ?: o; h+ a$ J添加相应的库文件
9 }9 `' C( S" C* e先来查看工程文件夹中的一些文件; F& b/ t2 X2 i3 Q; b
20210119152533686.png

( t# p  S1 b$ ?4 U* l2 Z8 k+ F3 ?6 ?7 f8 C' A* i& P  U9 m
这里面的文件目录是:
! r' G: R( l  H工程文件夹\Drivers\CMSIS\Lib\ARM
9 c2 c3 z: }; k- O里面就是我们所需的库文件
* j1 D/ C! V0 t# J9 |1 y& V8 n8 m1 P% N1 }
下面添加到我们的工程中:1 [: Y% c# [# f

' {: D* Y* Z+ Q$ b) x
20210119153038371.png

. E8 s' E0 L. V8 D
0 E- y0 h  z$ Y& Y! M  v$ p/ I& D然后设置添加文件的类型:
4 @& R7 Z$ s7 a. Y2 ]( `
3 ^) l' `4 X3 n9 N% W3 i
20210119153208652.png

% r5 `7 @1 j/ D2 z" w; ?& G7 s5 Q' t, H  \) B. D
选中小端模式的库,然后点击add,如果选错了,后面将不能编译,然后点击关闭窗口* L4 ^  @; N8 z) `0 D- ~' n# ~, H
* n( s0 w  ~# K
20210119153345635.png
( c& o8 |9 C$ z: U; |! f

: b% q8 A$ B+ p$ J% a5 y
20210119153500594.png
. J+ H9 C0 X6 x0 _
( C4 l- L/ P; ]8 H
Keil工程的设置

( _' H( g/ o" [& L8 ]开启FPU并设置编译器:: F  P, Y/ z& C" ^, A+ i% b7 Y6 t4 ?
将下面的东西复制到后面的图片中: \; T1 }2 l' {2 r; h" l, s1 O7 k' h
2 E- o+ p' x' ?- ^* b9 ?
  1. ,__FPU_PRESENT=1,__FPU_USED=1,ARM_MATH_CM7,__CC_ARM
复制代码

4 C; {7 u2 \( C8 I然后添加一些文件
3 s8 @% l2 L2 N  v! c! r! z
! ]4 {6 Y) F! P
2021011916003141.png
1 f3 X4 ~0 f/ D0 k1 g2 E$ o6 z3 P

5 T& C" G; V4 E4 ?在这里输入. Y# C$ I3 z' i# O9 g* k
…/Drivers/CMSIS/DSP/Include
! c* M( C) x8 ?8 [
1 [' l/ S$ n: V& ^9 g1 u
20210119160141855.png
# X+ _8 W- ]3 {  t% u) b6 @' P* y
$ U( k9 p# u$ o" z/ P
结果像这样& G% p9 T- l6 |) @" O
20210119160247877.png
5 `( e! v8 J2 K$ G+ ~
# Q# x! R2 ^7 V+ I: s
然后点击ok  _# U) d- N# f$ Q
  N* Y2 M0 ]1 z, ^$ e9 g5 }6 _
还要设置一个东东% o- M" k7 _+ r: U) k

- K" `8 J3 f" p( J+ d: V: r$ F
20210119154104108.png
! Q+ e% [/ u5 b$ l( o

* \; [) o9 @* U( w  ?/ Z+ a+ J' K! R9 g9 F. k( C; j
这里使用的是STM32H750,所以后面提到的ARM_MATH_CM7后缀是M74 ^! O/ c7 d+ h& }
0 F4 F$ P/ y7 A  j
现在就可以使用库里面的函数了
: U% `  o+ g: o1 d5 S" z$ A" ~. g# z5 O
下面是测试7 M8 Y% A/ b/ N8 G/ d- B
+ |# M4 s; f- w, o$ P; g2 d
进行FFT测试
) C* \6 V% q6 l, w$ A测试一
. i. P4 I2 D. V# ]7 ]5 n添加测试文件
& r1 X( u" n0 k0 e1 K
使用的是官方测试文件
3 S1 e, J/ j7 P$ x8 D
. [* w: }3 m3 A% [3 V6 Q4 j
20210119154843902.png

) u9 C- u* F( }) }
9 j5 ?. a. S- A9 k- y! ?这是例程所在目录
: }. H  T7 P) `) |$ g: O3 w, N
# L" O9 L; S2 }
20210119155008969.png

: N% H' u. r9 ?& R/ A2 U2 A! l# o* Z* M4 U7 M8 W
20210119155111683.png

# P1 [* z8 R& p% B/ f
; _! ], I8 ]7 J! n
2021011915514321.png

- a% B. X  k( i2 K6 ]7 C8 K
! \/ r2 F/ C1 V: a然后打开我们的main.c进行编辑$ Z7 V  `. i% f
注意:
9 v& R1 [! E; m0 T# t
3 c7 \* v* c7 c/ C0 x/ ]  v我用的是uart4进行的串口通信
5 k9 |; O0 a( `. P
& S. W0 K* {% Y! T5 ~9 J& v' `
20210119155432852.png
) ~+ \6 o$ R9 W6 Z  M- o& o

" M: Z* L# r- S
, O& P' K5 G) b* W
  1. #include <stdio.h>
    7 U3 H6 C1 G9 \/ i& n
  2. #include "arm_math.h"7 r3 t  S) Y6 ?/ H: E
  3. #include "arm_const_structs.h"0 t; l* D$ |" U8 @' S
  4. 9 Y/ |% D8 u/ v5 }
  5. #define TEST_LENGTH_SAMPLES 2048) o! {0 X5 L4 E0 e6 h

  6. ' J+ H& l2 t/ N. q" _
  7. extern float32_t testInput_f32_10khz[TEST_LENGTH_SAMPLES];//only have 10244 c7 `! U6 y) h6 k9 h3 Y' _: l
  8. static float32_t testOutput[TEST_LENGTH_SAMPLES/2];
    , k7 G# A, R# ~( V
  9. uint32_t fftSize = 1024;3 B4 Q, T# S& ]0 C
  10. uint32_t ifftFlag = 0;1 ^: }+ J  s; w! U0 X* O
  11. uint32_t doBitReverse = 1;, c' ^- m. b6 w% l

  12. & H: N$ U- J1 I; ~
  13. /* Reference index at which max energy of bin ocuurs */
    / Y! w, E# f; d' h' \! C5 d
  14. uint32_t refIndex = 213, testIndex = 0;" ?* W- w' L' s0 J6 J6 r

  15. * O. Y5 p3 L5 t- b+ X* m4 D" S2 z

  16. 1 i3 S; x; u- }) S2 N
  17. int fputc(int ch,FILE *f)
    ' ~8 Q- b1 B6 d, F
  18. {. d2 J3 P! [$ E3 C+ j3 x9 b0 ^
  19.     uint8_t temp[1]={ch};0 ~; p* ]1 P; q* o" @2 k9 t- I! B
  20.     HAL_UART_Transmit(&huart4,temp,1,2);        //uart4   一定要修改为自己的串口!!!!!!!!!!!!1 @4 t4 f8 G) X8 D8 J5 Y
  21. }
复制代码

% h  }" e& S! e! t然后& p+ E+ |- y  Q  f

2 _( Q- [/ k! A5 q% Q& o
20210119155723560.png
/ O& f. y! ]! `; p7 D

  1. ) K) }0 l2 J" {- ~& r+ l
  2. arm_status status;( A5 W/ i/ U2 V) k
  3.   float32_t maxValue;) e0 T4 `6 D4 l: \1 K: q# f
  4. $ V1 r% a- u2 s* P& B6 H
  5.   status = ARM_MATH_SUCCESS;
    8 D5 V2 u8 V, }! v

  6. ! k. y2 L: `1 ~: f& K
  7.   /* Process the data through the CFFT/CIFFT module */# L: T* {2 U+ W$ P9 i
  8.   arm_cfft_f32(&arm_cfft_sR_f32_len1024, testInput_f32_10khz, ifftFlag, doBitReverse);" R. B/ o# t( X. v6 `" V6 S+ `
  9. ; a# _* O7 c' E. I
  10.   /* Process the data through the Complex Magnitude Module for
    1 f. o( {4 l: F- _/ i3 {4 G
  11.   calculating the magnitude at each bin */
    ) @# _) j, n' R' q  ]: W% ~
  12.   arm_cmplx_mag_f32(testInput_f32_10khz, testOutput, fftSize);
    ! R$ G) r4 X  W
  13. ; p& }( s/ `6 ^% o
  14.   /* Calculates maxValue and returns corresponding BIN value */
    ) H( W% E) T. i8 V; k- e. Y% s
  15.   arm_max_f32(testOutput, fftSize, &maxValue, &testIndex);5 D4 d2 i; D4 q* E7 S

  16. 2 L7 M0 ^+ {# P, b
  17.   if (testIndex !=  refIndex)
    5 \& W' G; Y8 U% X0 c" Q
  18.   {
    . @1 `8 I4 w- u; @# ?) u
  19.     status = ARM_MATH_TEST_FAILURE;- H# y) k4 b% d' @
  20.   }
    ; t' W  n' F) _! d
  21. : z8 g, [- _6 Z* a+ h+ @
  22.   /* ----------------------------------------------------------------------% ?' r* V$ K, N+ B" |! o
  23.   ** Loop here if the signals fail the PASS check.: |- e9 I) ]6 m* v( r- q. V# t; X
  24.   ** This denotes a test failure
    ( ?* c0 `) b7 a
  25.   ** ------------------------------------------------------------------- */. I; v% O9 y1 p! y
  26. " D3 J% L8 y$ \# L8 x% k6 d4 n
  27.   if ( status != ARM_MATH_SUCCESS)
    , J' w; a! s7 l% z4 t
  28.   {
    " i8 a) J- N& b9 ^5 E& I
  29.     while (1);
    , K- `* o. l, L  Z) M. d9 M) ~
  30.   }
    ! L9 w- |! T) j, y8 W9 @9 ?
  31.   X9 o, @# |( s6 N5 q/ N  N( P
  32.   while (1)' V2 W9 Y" ^& ^& X: b
  33.         {2 N. W2 p- K; m/ u/ [& c6 z
  34.         //printf("hello\n"); ! [  s$ H5 O& u3 ^
  35.         HAL_Delay(5000);/ q" H* ]& W: ?0 t7 w4 O
  36.         for(int i =0;i<1024;i++)
    1 p% a$ g% f: x
  37.         {printf("%f\n",testOutput<i>);( t8 W% U' F' O, G0 q8 H) n
  38.         </i>HAL_Delay(10);
    9 \* u$ T5 L; N3 ^
  39.         }4 {  |8 _' _0 `( D/ d7 _$ h6 S
  40.         while(1);
    ) J1 d* A1 U0 B2 d
  41.         }
复制代码
' V" y$ [4 m) X! _! k
这里完了就可以编译了  z- m) J* q8 ~; w1 w
2 ?+ O6 X& s! [% d# r" ^
结果探究
  n( I( C& q: i3 N6 j  _. @1 s. F打开串口助手,等待5s后会发送
, c! ^5 i$ R1 V+ N, Z
& E9 h& E* F/ Q) y! h1 J( _
20210119161237405.png
3 _% J, ?) \; S  `+ I! g
: ~' ~' h2 s" x* Y% r' o
然后提取之后就是我们要的数据了,可以保存后用excel来进行绘制,就是我们上面的图像了4 ]0 f0 g3 W: I: H5 P
) F; V4 P, u: c. I

* R  |/ f8 ?; ~& {
20210119153944812.png
赞 收藏 评论0 发布时间:2021-12-26 16:43

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版