本篇内容将简要分析STM32自带的DSP库文件,其用汇编语言编写,代码执行效率明显优于C语言,ST公司封装好了了库文件,我们不必看懂其汇编代码,只要会调用接口函数即可。 1,代码分析 首先我们需要在一个已经建立好的工程文件里添加如下编译路径: 工程需要添加的文件如下图:
" F. I: L8 p, V7 x' f5 U2 n% m. K6 B 为了产生fft变换信号,我们可以自己产生个采样信号:使用三角函数生成采样点,供FFT计算,fx = 4000 * sin(PI2*i*50.0/Fs) + 4000 * sin(PI2*i*2500.0/Fs) + 4000*sin(PI2*i*2550.0/Fs)。
- T4 d8 n, N6 S! p5 H; V 模拟采样数据,采样数据中包含3种频率正弦波:50Hz,2500Hz,2550Hz, lBUFIN数组中,每个单元数据高字(高16位)中存储采样数据的实部,低字(低16位)存储采样数据的虚部(总是为0)。9 N' o/ `4 _# F& F2 [" x1 {
其中dsp_asm_init()函数的作用是产生采样信号,实际工程应用中我们使用的是ADC采样的处理值。dsp_asm_test()函数的作用是进行FFT变换,并计算各次谐波幅值。具体代码参见下面:
+ }% }- f" r6 H3 r' g- 1 /*
9 L1 u8 o$ L: U - 2 *********************************************************************************************************9 Z1 m, A: M- s7 y) E
- 3 * MICIRUM BOARD SUPPORT PACKAGE" B: f/ }" H5 S. }# X
- 4 *
0 v4 p2 y/ \, H3 A5 Z - 5 * (c) Copyright 2007; Micrium, Inc.; Weston, FL
. g( J& _$ f& q8 @) u7 s - 6 *" X% z" r4 L, L# F$ ]4 X
- 7 * All rights reserved. Protected by international copyright laws.
% x7 M7 ^4 P! _4 E, L, e - 8 * Knowledge of the source code may NOT be used to develop a similar product.
2 ]7 V& ?! ^$ u' R - 9 * Please help us continue to provide the Embedded community with the finest
( J, m& A" a8 b7 f, ?' w - 10 * software available. Your honesty is greatly appreciated.
" G. }9 O% j) q - 11 *********************************************************************************************************2 i% v; b! I; l/ o; w! T
- 12 */( L: d, ]* ?& f$ C
- 13
' x9 r. h' [3 N4 q - 14 /*
+ ^7 P7 a1 q5 m& L& i1 w( D - 15 *********************************************************************************************************0 R5 G. y, U% v3 {9 p. M2 k
- 16 *
, b h- p6 l7 [6 U. Q) h - 17 * BOARD SUPPORT PACKAGE. s9 ?! b1 P$ U' M: s
- 18 *0 A$ N# W& V4 b6 c
- 19 * ST Microelectronics STM32
6 U* U4 A/ O5 j8 u8 N5 b - 20 * with the
+ \5 O! X' x& Z2 ^; ~ - 21 * STM3210B-EVAL Evaluation Board# q' D! O4 Q/ M w$ E& K
- 22 *
: @ D5 s& r( F j - 23 * Filename : bsp.c9 K* b R& z8 t" N/ J
- 24 * Version : V1.004 U7 M" Y5 [' V- W; M
- 25 * Programmer(s) : Brian Nagel
- F. d) M( U8 H+ o# I. @ - 26 *********************************************************************************************************% a+ C- F: T. p9 \) M1 }
- 27 */# Q9 A( t: M8 |' Z, ~
- 28 9 @* r5 s* z6 ^7 }' d/ b8 U, P) I) _
- 29 /*
9 X9 z* J( U% B; n - 30 *********************************************************************************************************/ o; x3 v! Y9 d( O
- 31 * INCLUDE FILES
y% L d5 z; i- {9 d! C- `( I8 N - 32 *********************************************************************************************************
5 V5 b" O' G. t3 X: U5 n6 V - 33 */
; A; o& ]+ q& e9 x - 34 & f" m" y1 m3 n8 Y/ x
- 35 #define DSP_ASM$ s9 d- y r" N, ^& j5 Y1 V4 M) g
- 36 #include "stm32f10x.h"; b5 B- T8 D) [' d9 s% ]
- 37 #include "dsp_asm.h"
, E8 ^: o" f6 i# W# v - 38 #include "stm32_dsp.h"
0 q5 h4 c T2 f1 J+ O - 39 #include "table_fft.h"
* C/ c7 l# B% J A; Y - 40 #include <stdio.h>) I/ |6 C. @% m) G! }. W) ]) o
- 41 #include <math.h>& V8 K3 p" G4 {0 x- w) w
- 42
. M6 B# c6 v/ x5 ~* B - 43
% N" }/ S. O6 q3 [: G - 44 /*
6 ^! J! O+ R' }, @' w, j - 45 *********************************************************************************************************
: _. Q2 i" o0 P6 L1 E - 46 * LOCAL CONSTANTS
* b0 J% c. C9 o2 W6 ~ - 47 *********************************************************************************************************
' ?% f9 g+ s8 I; r! r7 X - 48 */3 a t a$ ]9 l% w
- 49 #define PI2 6.28318530717959
4 H, x) j! D1 c. ] z - 50 #define NPT_1024 1024
+ Y$ C# i; p: F/ a* X4 G' I/ K - 51 //#define NPT_256 256
' U8 E+ @0 W" t: r - 52 //#define NPT_1024 1024* o: [% B$ z S% m" T9 T/ g* Q5 z
- 53 ) [: C8 N7 f/ Q9 u, o
- 54 // N=64,Fs/N=50Hz,Max(Valid)=1600Hz
M4 m1 j# r$ d- v# W! C+ a - 55 #ifdef NPT_64
) b2 w5 {8 V3 q' T* [ - 56 #define NPT 64
% U7 |6 J# b1 `1 D/ E7 i4 d' D* W - 57 #define Fs 3200
/ b% p; n% G% V' a* K* u- w! ? - 58 #endif& g5 b) Z8 _6 I5 O% ~: l3 _
- 59
. b8 e6 F1 |% }/ f6 L( M* b" D - 60 // N=256,Fs/N=25Hz,Max(Valid)=3200Hz# S6 m1 K h8 t. L/ o6 n# B' r
- 61 #ifdef NPT_256
( A( `/ ~+ ~3 f- [- w - 62 #define NPT 256
) o6 j) x( y7 t7 ]3 G - 63 #define Fs 6400
7 N: M. B$ N3 B- I! O0 Z/ J+ W; h1 A - 64 #endif& a. |2 _7 e4 z1 a' e
- 65 ) v+ q+ S8 D- K1 b6 z0 t' k
- 66 // N=1024,Fs/N=5Hz,Max(Valid)=2560Hz. T M" U# c2 g2 X0 g
- 67 #ifdef NPT_1024
# i+ K8 t0 D) b% C; n5 h - 68 #define NPT 1024
* ~ z N# t6 G( I) H - 69 #define Fs 5120
9 J% ?4 J8 M9 N* R- l - 70 #endif
: B1 n' F/ f+ V: h+ }# k - 71 0 c2 A6 A0 E2 e% z
- 72 ) c; d. }! R: p: O* E# ~# r
- 73 /*" b; L- O/ h' a* L; j% e" t
- 74 *********************************************************************************************************. x) G0 ` N% T. e% ~; y
- 75 * LOCAL DATA TYPES
* r! H: e) c# X/ k4 m+ v& N0 q - 76 *********************************************************************************************************
' C- [- v* M4 D2 D# S2 g - 77 */
( K+ V8 ^, o: a$ U# i - 78 * V2 ] T( }8 X+ H, i; f, o
- 79
+ e7 l: k% z; u! v5 U - 80 /*
' K+ O' Q( a# `7 z$ X# [$ g - 81 *********************************************************************************************************
* e' E8 V5 e- c2 O - 82 * LOCAL TABLES
/ A# x# n* a5 m' l: P( x - 83 *********************************************************************************************************
: W+ l* B( g9 i/ m; f2 \( a - 84 */
1 s5 c3 w( c. H - 85
0 N3 {; c4 j/ i - 86 5 n; a0 A0 P$ t( ]) J
- 87 /*
9 v7 u b: G; O- { - 88 *********************************************************************************************************
' Q" F. X8 \ h: C$ v; [/ C - 89 * LOCAL GLOBAL VARIABLES5 \9 W# _& o6 M* r% v. N# N. H+ N% x
- 90 *********************************************************************************************************6 \4 X% u0 G5 h+ b/ g; X8 d
- 91 */& t9 [ ^# W5 r+ z* O6 @
- 92 long lBUFIN[NPT]; /* Complex input vector */
* r9 i7 Y @5 q2 O) Q) s& H - 93 long lBUFOUT[NPT]; /* Complex output vector */
( R) ^( X& ^) y. i7 W) y- Q - 94 long lBUFMAG[NPT];/* Magnitude vector */0 F* L$ p/ D, h. ]
- 95 /*% G+ P% d! K! }) ^% s
- 96 *********************************************************************************************************
7 E3 }1 L* U. n6 ~& i - 97 * LOCAL FUNCTION PROTOTYPES
' m3 J% i4 S/ P# X - 98 *********************************************************************************************************
) w9 r' A' }# f - 99 */+ Q4 p0 L: W8 d
- 100 void dsp_asm_powerMag(void);* i2 o8 c, x- G0 B$ S: c
- 101
. w7 `* z8 K) e) R3 K8 W - 102 /*
# V% O0 y& v( d - 103 *********************************************************************************************************+ d% m) x( F3 J* o# |8 H+ T }
- 104 * LOCAL CONFIGURATION ERRORS
% Q0 {, L7 }/ o" E9 R& ? - 105 *********************************************************************************************************
1 P) F! w3 k4 h4 @( k# I( l0 x5 b - 106 */
% H* p; |/ q- Q! Z4 d4 x - 107
1 ?; B. ?8 q5 s' J( m1 V& I S - 108
6 d( d/ I7 m2 O9 g5 v! j - 109 /*9 T+ `0 r- e4 u8 u5 ^8 e- ?$ `; u
- 110 ******************************************************************************************************************************2 z( B1 x% N$ w5 @1 {% r! z g( d
- 111 ******************************************************************************************************************************
* r6 O# P9 z0 A3 j - 112 ** Global Functions
: l( N' [, ^! N7 k; l6 J' ]' D, A1 G: Q - 113 ****************************************************************************************************************************** Y: g+ k) `8 |
- 114 ******************************************************************************************************************************
" j/ G$ I( `- } - 115 */
y2 \+ r1 k1 D+ |' R' k0 d$ U8 d - 116
( R5 o* P( C6 z. G2 T( E6 h: v - 117 void dsp_asm_init()" u2 ?1 l% `% m: I" V' n" R6 O
- 118 {! I. M' `$ H" v: o& N0 M" A; ]
- 119 u16 i=0;
6 ^7 V7 j) W( y; c4 @5 W - 120 float fx;+ M; G M! d! T' E9 A: O
- 121 for(i=0;i<NPT;i++)" Q/ ?/ d) N$ o, i( y
- 122 {! \* A0 z: f4 \ {& w
- 123 fx = 4000 * sin(PI2*i*50.0/Fs) + 4000 * sin(PI2*i*2500.0/Fs) + 4000*sin(PI2*i*2550.0/Fs);
8 C! n& R5 K- b9 Y e) ^/ W& V8 H1 ` - 124 lBUFIN[i] = ((long)fx)<<16;: D' L$ [6 a1 V5 n, P" h
- 125 }
3 Y9 a+ B5 q* k* b2 {9 b% X9 E - 126 }
' L; ]4 Z; A5 h# ?: L- M ` - 127 + j- n4 S9 t& V! B7 ?
- 128 void dsp_asm_test()
5 z5 ~/ U+ ~+ t$ u5 \. Z, S - 129 {
0 ?. d) y/ U* `1 n# G/ l% x; r. v - 130
6 V/ x3 Y1 t& e7 }; G0 p# z# p - 131 #ifdef NPT_64, a) h# w- N j# o: {5 c
- 132 cr4_fft_64_stm32(lBUFOUT, lBUFIN, NPT);" C3 x$ b% x# X# z
- 133 #endif4 D$ D) ?3 B6 |3 B# ^' Q5 q4 Q6 n( C
- 134
+ m5 R* B8 G) y0 {4 O - 135 #ifdef NPT_256
6 I: P6 K. d( G" t3 A6 u7 U - 136 cr4_fft_256_stm32(lBUFOUT, lBUFIN, NPT);
% t/ u' L. C& s% J - 137 #endif0 O3 @. ?2 G$ S/ k% R- P) Y
- 138 |+ L$ a2 j) E5 m
- 139 #ifdef NPT_1024
3 k, k6 a4 X2 ^ - 140 cr4_fft_1024_stm32(lBUFOUT, lBUFIN, NPT);
9 ^% b* t4 j' A' L - 141 #endif, ? f8 F3 H1 ]) A% J
- 142
3 S e2 S/ g& \' k/ M - 143 // 计算幅值' o* u8 r$ E8 w6 r! x
- 144 dsp_asm_powerMag();
5 \( }, r/ Q3 A' ~& q - 145
0 Y( L2 I, p A2 F* B: i3 L - 146 }' v, f; k& h8 G
- 147
) V( Z7 l+ a8 _! z$ ^! L7 r: p - 148 void dsp_asm_powerMag(void)
( u, V% ]9 ^( o- V - 149 {1 Z) l8 T2 r d' O7 O
- 150 s16 lX,lY;
) g2 b( b. b1 `# L+ Z0 L0 R - 151 u32 i;
2 T4 o% ?4 O5 {5 P; T' ~ i* |- x+ R - 152 for(i=0;i<NPT/2;i++)
4 l( U+ M) i V. m. d7 n4 v - 153 {6 Y" O$ X0 ?& }$ k. V3 @. ], H
- 154 lX = (lBUFOUT[i] << 16) >> 16;
- _) X% c, e! `$ | - 155 lY = (lBUFOUT[i] >> 16);
2 q% c) W) h+ U) C8 m1 D7 Q8 ^% r - 156 {
4 {9 O% i' M' U1 b - 157 float X = NPT * ((float)lX) /32768;7 `1 k) c. b j C0 O
- 158 float Y = NPT * ((float)lY) /32768;5 ?" I7 ?, ^: ^, F
- 159 float Mag = sqrt(X*X + Y*Y)/NPT;
[% a3 V2 ?% O5 y. T8 U8 k - 160 lBUFMAG[i] = (u32)(Mag * 65536);3 k, q) p' l5 G, i4 z. m% ^
- 161 }
) T' j$ U) d2 a( \5 p - 162 }
) E0 |$ n: @& R$ q; Y - 163 }
复制代码- 1 /*
& j) u/ X: Z# o. @ - 2 *********************************************************************************************************0 f, X' I$ Y( I* O- H
- 3 * MICIRUM BOARD SUPPORT PACKAGE
5 D# a5 ?8 L+ ]7 W& A, ` - 4 *
& W: d7 J" W( l. S2 S1 P9 ? - 5 * (c) Copyright 2007; Micrium, Inc.; Weston, FL
+ i3 f: z( ^% g - 6 *: M T, E! r1 `3 B# d, C M
- 7 * All rights reserved. Protected by international copyright laws.
. Q8 U7 G6 w( T) B - 8 * Knowledge of the source code may NOT be used to develop a similar product.
8 ?7 u p3 K7 c4 h - 9 * Please help us continue to provide the Embedded community with the finest
$ i3 c3 e! E) G - 10 * software available. Your honesty is greatly appreciated.) }$ A1 L i+ \0 L+ n2 `
- 11 *********************************************************************************************************. F; L7 {! Z3 {+ b. q5 I' y: Y
- 12 */
! I5 f5 A1 j% y" }" j8 I - 13 ! X \8 u- ]& N! p# m
- 14 /*% ~, J5 A( ]$ V$ Y* Z9 I# B
- 15 *********************************************************************************************************$ h7 b: G5 k$ |
- 16 *3 U% E/ S* N, d: D# D% F
- 17 * BOARD SUPPORT PACKAGE
0 z4 V" X x+ @2 ^" G& j - 18 *. G/ b' X6 U1 N! ^; P
- 19 * ST Microelectronics STM32
5 U. \9 a. z: N9 W0 W - 20 * with the
* t0 F( T1 S& |9 \' h9 B - 21 * STM3210B-EVAL Evaluation Board
' c8 D; {* A9 P2 B x$ _! M - 22 *
: d+ t. v6 `! A4 `( U% N - 23 * Filename : bsp.h/ I+ E' D( N4 ^# S+ R9 H
- 24 * Version : V1.00# I4 G5 x2 L5 N: Q5 D( x" t6 M. H
- 25 * Programmer(s) : Brian Nagel, y, Y) e. X' G# `0 H2 a8 h
- 26 *********************************************************************************************************) I0 y; I+ O' F0 A/ o
- 27 */
9 H( Q" m( d8 L& ]+ g, } - 28 3 P9 m( C; y! j4 ?( U
- 29 #ifndef __DSP_ASM_H__' ~ @& s9 O7 }$ F
- 30 #define __DSP_ASM_H__
) @1 ?/ S% k4 s& {& @ - 31 ) r- C+ L2 r) `" Z7 N
- 32 /** J" k: d( k! X# {8 U$ a
- 33 *********************************************************************************************************; H0 @; D8 L2 h
- 34 * EXTERNS
. e e# x/ E) ^' j7 ^1 G0 l - 35 *********************************************************************************************************
% F! l2 F- q- @$ r5 m0 } - 36 */6 t' T) P/ |2 b/ J, Z
- 37
" g, s- ^9 ~1 Z( V- ^( N - 38 #ifdef DSP_ASM
$ p. |; ]9 a- l B% c - 39 #define DSP_EXT8 F8 [) U; g+ F5 @: G3 e: x1 [0 x
- 40 #else' R% @- O, q8 R
- 41 #define DSP_EXT extern
- F" s3 r$ D6 y9 A0 ?# T - 42 #endif
% b0 P" u" o9 {& W1 Y- ]! Q - 43
2 ]: u3 p. _( h7 [+ m - 44 /*
1 o, I! s8 Q# K; P5 ] - 45 *********************************************************************************************************
5 {0 d0 U; r Y) a4 S9 O - 46 * INCLUDE FILES
' M4 k! O9 ]9 R9 K" u - 47 *********************************************************************************************************
' r' ~' P. l2 n6 H! y4 B - 48 */- J2 u3 d# A. o% }. {
- 49
) p* ?' `7 t/ R6 M9 F - 50 . r( b; u( R8 s k) o% I" h
- 51
: Y' ^5 J+ n! I# h9 N - 52 \$ ^! U7 e8 u p5 ]
- 53 /*
K* O, G- O, q4 c* G, {5 A - 54 *********************************************************************************************************: F. _# ?" l# g
- 55 * GLOBAL VARIABLES
" z9 m N; r, e% V - 56 *********************************************************************************************************, U+ k8 @0 w' o3 Y' I' s P
- 57 */
. b% b* n3 {: j d$ d* ?( H+ H - 58
" e N6 J9 T* w$ R) W+ i& H - 59
* _4 S) u# @1 T; w - 60 /*2 C6 j+ a( O- E% r; ^
- 61 *********************************************************************************************************: R6 I* n+ p: j! X( W& ]' z1 Y* m
- 62 * MACRO'S3 x' k. G& G; ?' c" i/ D# S2 ]
- 63 *********************************************************************************************************
8 |1 A2 S! y2 [6 A5 T - 64 */+ G0 u& a* `$ m$ C6 e) }
- 65 0 w% v2 _% Z# n9 E! N. s5 U' T+ d9 u
- 66
" A6 U, r1 Q* b V% j! I - 67 /*
) `( b, e) k! H! z2 `1 R3 F; L8 r - 68 *********************************************************************************************************. M2 d8 a, C8 B+ x" o' l
- 69 * FUNCTION PROTOTYPES! h* A- a: d( s( o
- 70 *********************************************************************************************************
2 }3 G# E2 w3 j, b1 u, W! z/ O - 71 */* r. v5 t& Z# T" m! l6 V4 h; r
- 72 % Y3 U; x8 i' z$ b! Y
- 73 void dsp_asm_test(void);
/ w+ n2 M3 U+ @ - 74 void dsp_asm_init(void);
6 z4 b2 A V& w6 n% i - 75 5 C# _4 Z/ k8 a- D: g- |' u
- 76 #endif /* End of module include. */
复制代码 @" g s5 B5 A$ w' d7 X
着重分析下dsp_asm_powerMag()函数的作用,其函数就是求幅值,首先定义的的一个16位的有符号的数据IX 和IY 这两个只是中间变量,然后定义的i,是32位的无符号型。语句的目的是Mag = sqrt(X*X + Y*Y)/NPT。但直接这么写不符合DSP的计算习惯也就是不符合浮点运算的习惯。因此语句在for函数i写道 lX = (lBUFOUT << 16) >> 16 就是取32位的i的低16位数据,lY = (lBUFOUT >> 16);是取高16位数据。下面的两句
, N. ?/ I: o f+ {$ l, ]5 P( L6 H float X = NPT * ((float)lX) /32768; % s& N+ z8 ?+ |) e2 Y; G
float Y = NPT * ((float)lY) /32768
+ u+ Q0 f0 D n) ]$ b' w' _ 目的就是把数据浮点化,至于为什么是除以32768 。可以这么说,浮点化就好像10进制里面的科学计数法。32768=2的15次。除以32768也就是去除了浮点数后面的那个基数,只剩下前面的。比如1991 改写成1.991*10的三次幂,再除以10的三次方,只剩下1.991,便于余下的运算。至于最后一句要乘以65536是因为我们定义的数据和我们需要求得的数据都是无符号32位的,之前已经把32位的数据拆开又分别浮点化了又开了个根号,所以再把它变回来 只需要乘以2的16次,也就是65536.比如说问你什么时候生日,你说是19911030,然而DSP是不习惯这么干的,他需要把它拆开为1991和1030。再写成1.991x10的3次方和1.030x10的3次方。然后才能进行其他的运算。
* ~8 ^ P1 K5 e6 a+ n# \7 f4 v 这里是ST公司采用了DSP专用芯片(主要是指TI)的写法,也就是说尽管DSP的芯片类型很多,数据变量的定义也各有差异,但原理是一样的,最终还是要采用DSP习惯的运算方式。至于为什么一定要采用浮点运算,因为机器是傻子,然而TI公司的工程师是天才。 main函数中我们只需在while(1)前加上dsp_asm_init(); dsp_asm_test();即可。
2 ]9 C% o; M* p+ l2,实验现象 注意FFT运算结果的对称性,也即256点的运算结果,只有前面128点的数据是有效可用的。 ① N=64,Fs/N=50Hz,Max(Valid)=1600Hz,64点FFt,采样率3200Hz,频率分辨率50Hz,测量最大有效频率1600Hz 64点FFT运算结果图(局部): 上图中,数组下标X对应的谐波频率为:N×Fs/64=N×3200/64=N*50Hz. lBUFMAG[1] 对应 50Hz谐波幅值。 上图中由于FFT分辨率50HZ,最大只能识别1600Hz谐波,导致结果中出现错误的数据。 ②N=256,Fs/N=25Hz,Max(Valid)=3200Hz,256点FFt,采样率6400Hz,频率分辨率25Hz,测量最大有效频率3200Hz
- k- v$ @6 n" ^, h0 S4 h4 }256点FFT运算结果图(局部): 上图中,数组下标X对应的谐波频率为:N×Fs/256=N×6400/256=N*25Hz. lBUFMAG[2] 对应 2×25 =50Hz谐波幅值 lBUFMAG[100] 对应 100×25=2500Hz谐波幅值 lBUFMAG[102] 对应 102×25=2550Hz谐波幅值 ③N=1024,Fs/N=5Hz,Max(Valid)=2560Hz,1024点FFt,采样率5120Hz,频率分辨率5Hz,测量最大有效频率2560Hz 1024点FFT运算结果图(局部): 上图中,数组下标X对应的谐波频率为:N×Fs/1024=N×5120/1024=N*5Hz. lBUFMAG[10] 对应 10×5 =50Hz谐波幅值 lBUFMAG[500] 对应 500×5=2500Hz谐波幅值 lBUFMAG[510] 对应 510×5=2550Hz谐波幅值 / U$ C4 R, D+ `% X7 l; W
总结:该工程中模拟信号源为:4000 * sin(PI2*i*50.0/Fs) + 4000 * sin(PI2*i*2500.0/Fs) + 4000*sin(PI2*i*2550.0/Fs)。 信号为1个50Hz、1个2500Hz、1个2550Hz的正弦波混合信号,幅值为均为4000。
- T* d6 Q3 g$ @" h$ U: ? |