本篇内容将简要分析STM32自带的DSP库文件,其用汇编语言编写,代码执行效率明显优于C语言,ST公司封装好了了库文件,我们不必看懂其汇编代码,只要会调用接口函数即可。 1,代码分析 首先我们需要在一个已经建立好的工程文件里添加如下编译路径: 工程需要添加的文件如下图: g4 b/ p/ J* Q: y3 L! x: X6 e( c
为了产生fft变换信号,我们可以自己产生个采样信号:使用三角函数生成采样点,供FFT计算,fx = 4000 * sin(PI2*i*50.0/Fs) + 4000 * sin(PI2*i*2500.0/Fs) + 4000*sin(PI2*i*2550.0/Fs)。
" A: y/ G" m8 a 模拟采样数据,采样数据中包含3种频率正弦波:50Hz,2500Hz,2550Hz, lBUFIN数组中,每个单元数据高字(高16位)中存储采样数据的实部,低字(低16位)存储采样数据的虚部(总是为0)。$ J& T0 K" ~ G" I7 h2 ?
其中dsp_asm_init()函数的作用是产生采样信号,实际工程应用中我们使用的是ADC采样的处理值。dsp_asm_test()函数的作用是进行FFT变换,并计算各次谐波幅值。具体代码参见下面:
7 ]% Q: p/ D: }' c9 @! _- 1 /*& f' B+ c7 i: u$ q
- 2 *********************************************************************************************************
9 T: @* U! } e - 3 * MICIRUM BOARD SUPPORT PACKAGE
1 N H* e/ K4 p+ X; w. R4 r - 4 *
' T* t1 _0 n3 E7 B - 5 * (c) Copyright 2007; Micrium, Inc.; Weston, FL
6 a3 {& e2 P7 p1 P* _5 q - 6 *1 D7 a C( w6 ^( a5 C; I
- 7 * All rights reserved. Protected by international copyright laws.: R5 h" X5 p- t5 G d
- 8 * Knowledge of the source code may NOT be used to develop a similar product.8 b& `9 U8 y. U
- 9 * Please help us continue to provide the Embedded community with the finest
* H- ^. F3 {3 m$ Y6 R - 10 * software available. Your honesty is greatly appreciated.
" M. `$ j( i1 }! ]3 |! L - 11 *********************************************************************************************************# Q+ L9 _3 Q& r4 W& H, G+ P, J/ M% p
- 12 */
! ~# i' V v$ c% h" ^( P3 {- |" E& H; n - 13
6 p- v- i! `. C, k) ^8 a - 14 /*
# h5 T3 Q0 i7 Y* q/ z4 H, f$ S3 @ - 15 *********************************************************************************************************, I+ _ c- e, i
- 16 *- c; J5 J* N& K' I, }5 ?
- 17 * BOARD SUPPORT PACKAGE
% x9 D( e0 x. ~( I - 18 *7 k8 c+ K3 c X6 x" d
- 19 * ST Microelectronics STM32$ o& L% }& k: `/ P, A% g$ W( K6 k3 a
- 20 * with the& g1 a4 s4 e0 E* u2 _
- 21 * STM3210B-EVAL Evaluation Board; m% L O2 j8 U( f1 W
- 22 *
0 Y* ?1 J8 R# [9 C. j- F5 P' p - 23 * Filename : bsp.c( J2 i3 U e+ L( h( d
- 24 * Version : V1.00
# _3 }0 S1 ^: c8 Y - 25 * Programmer(s) : Brian Nagel
+ R4 t+ i; |4 L - 26 *********************************************************************************************************: N; G9 R. o. N6 O) z
- 27 */
5 ?; G9 g3 G: p9 Q) m, T - 28 2 F2 y3 W; c3 U6 j2 W2 r2 @' l
- 29 /*
5 R3 K/ ?% o/ ~* E" m - 30 *********************************************************************************************************- @) ?3 v1 _6 ]8 k$ E( S; c g
- 31 * INCLUDE FILES
2 d; x+ f, V# s/ U9 |! Y$ W8 K4 x: E, m - 32 *********************************************************************************************************
7 Y( Q) E# v9 ?; @( M - 33 */
( D8 r) t! q' h: O - 34 + H) G( Z; l5 Z. m0 W
- 35 #define DSP_ASM
# a0 C5 `4 P4 [/ O O% }3 [ - 36 #include "stm32f10x.h"
# X; f0 k d( ?: c# Z9 @0 h1 E! Y - 37 #include "dsp_asm.h"
+ _" O7 e# |; z T - 38 #include "stm32_dsp.h"
K7 @6 Y1 ~* T0 W W+ m# O3 u# G/ }+ Z. L - 39 #include "table_fft.h"3 L0 p; x5 Z/ z. G+ L
- 40 #include <stdio.h>
" O- T- s& `7 \) p. \) b. { - 41 #include <math.h>2 e* S+ F2 _0 |4 A
- 42
8 e; U# A7 R, `' D4 t - 43
; a9 t% z. z& E" s - 44 /*9 t: W, Z6 @% i
- 45 *********************************************************************************************************9 a, A4 E( C+ p
- 46 * LOCAL CONSTANTS% y# y5 g9 O b7 t( t
- 47 *********************************************************************************************************$ ^9 D# ^: u& P. x X! b+ U
- 48 */! R( g& i d A) J% G# N
- 49 #define PI2 6.28318530717959( C/ ]2 H! n, Q0 w6 p
- 50 #define NPT_1024 1024
7 |1 E5 i) h& d, z* p7 L - 51 //#define NPT_256 256
1 a! i( _+ U0 C+ K5 N - 52 //#define NPT_1024 1024
" \" ^" l6 y. b" a! B0 [& ] - 53
9 X/ t/ ]3 F3 f0 p0 h; C# d - 54 // N=64,Fs/N=50Hz,Max(Valid)=1600Hz
) \- @: X! X( T1 Z# ?3 U - 55 #ifdef NPT_64
. v7 X3 |; R+ M- @* K - 56 #define NPT 64
: Q+ x6 }( T9 u6 j( C- z9 J5 E - 57 #define Fs 3200
O$ ~! H% L$ y7 J2 R/ j" D - 58 #endif0 o3 d5 g4 G* [8 n# U& z6 M% v
- 59
& [4 v0 [' ]: [ - 60 // N=256,Fs/N=25Hz,Max(Valid)=3200Hz& ~: Q5 _+ r" F" I5 B: b0 ?7 W
- 61 #ifdef NPT_256. {# q9 Y( i& P- D
- 62 #define NPT 256
9 r- ]9 r) C2 x8 v. H4 A1 }3 T( ] - 63 #define Fs 64007 x" P$ W2 l9 ~9 m- g) x( w& }, Y
- 64 #endif
5 G: C, g* D3 J! G' q1 o - 65
! v: B$ E2 D, D; k2 U/ K7 e7 d: R4 ^ - 66 // N=1024,Fs/N=5Hz,Max(Valid)=2560Hz
. P( d- W- Z* f - 67 #ifdef NPT_1024& D& o' }" A) `: {/ k' i" R7 C
- 68 #define NPT 1024
; ~! k' v9 O+ L k" O - 69 #define Fs 5120
9 T9 x: |- G$ O: p4 b* a - 70 #endif
% W' z; L7 m) v* h4 a+ c - 71
7 i' U# a, O* L% e2 \' i - 72 4 [4 Z) q ^* k" Y
- 73 /*
- C1 U3 E9 x. p/ V4 p$ P* n - 74 *********************************************************************************************************
+ w$ O: g( G! i1 U8 r- C3 E - 75 * LOCAL DATA TYPES
( e0 _2 V/ Q0 [' q) X) x - 76 *********************************************************************************************************
* h1 @+ i7 ?( { - 77 */
' ?& _- a9 q9 {2 I2 i/ i - 78
1 |* v+ F8 I5 x - 79
) @# L& T6 `, S: F/ ^ - 80 /*
- l/ Y2 B1 b2 }3 ~; O/ M - 81 *********************************************************************************************************
) V& X! G) a% ~3 m3 w* l# [! {8 C - 82 * LOCAL TABLES
% F2 @ I& Z5 f$ q - 83 *********************************************************************************************************4 Z* d. U# @1 N
- 84 */+ V, c4 y% C% ~% ?+ K8 s
- 85 % b( F0 ~/ |* {+ U& z
- 86 ! J) s7 \$ V9 Y3 c8 x
- 87 /*
9 m0 m- x" s: w. H2 N' f' @ - 88 *********************************************************************************************************
+ R" W5 a, ?& r8 t - 89 * LOCAL GLOBAL VARIABLES
9 w) F9 h+ H [8 n6 T0 r+ e - 90 *********************************************************************************************************
: I' _8 A; y: k* z4 V. X; F - 91 */
0 Q2 R. _' H9 B% B6 r( r - 92 long lBUFIN[NPT]; /* Complex input vector */
+ N, u6 B7 c5 h - 93 long lBUFOUT[NPT]; /* Complex output vector */ O0 h! g7 e- O U' }2 F0 \1 C
- 94 long lBUFMAG[NPT];/* Magnitude vector */
, Z. U; T/ s7 G; }- @ - 95 /*
, j' o% v. c/ B; Q - 96 *********************************************************************************************************/ Z% Y) o% a- u z
- 97 * LOCAL FUNCTION PROTOTYPES5 h& h0 q/ `# B/ @6 n3 K; B+ I6 `
- 98 *********************************************************************************************************6 s9 l1 o, [! w/ T. d5 X8 q
- 99 */' L1 ` H# C8 h4 n4 _+ r! t* Z
- 100 void dsp_asm_powerMag(void);
* X/ `/ h4 n, ^) [ b/ p" ^ - 101
- e! b( c# j. z% T0 F6 I" x4 E" ? - 102 /*
. G. _8 i7 E; d& B1 ~) y/ i; | - 103 ********************************************************************************************************** s9 E* c2 z; _3 F I4 }
- 104 * LOCAL CONFIGURATION ERRORS
9 [! {# H$ [* |- I3 T" u - 105 *********************************************************************************************************9 d2 h u3 p% [
- 106 */& ~# T7 ?0 s4 X' g8 ^2 g/ m4 ~
- 107
1 n3 k+ P. W/ A& v6 S - 108 3 m) F F! ]$ Z, N6 u9 d1 b7 e: d& k
- 109 /*
& q( ^$ H- Z) e# H8 r! I2 W- o2 P - 110 ******************************************************************************************************************************
, {. d! V; W7 S" s5 l - 111 ******************************************************************************************************************************
7 b/ R- e( N H2 h" k- r+ u - 112 ** Global Functions
1 P* L, c) N- {3 H - 113 ******************************************************************************************************************************; o1 V- a" {: b. R
- 114 ******************************************************************************************************************************
; d% h. f# @5 v! u* g - 115 */
9 N/ s' A* i0 E& b6 B/ j7 K - 116 . Y; [$ C$ Y# t, e+ _0 ?
- 117 void dsp_asm_init()
: r( l! G5 ~$ y - 118 {
" {' |4 ]3 B d$ ~7 v. b3 D - 119 u16 i=0; r6 F4 ^' Q+ t. ~4 O$ V7 i
- 120 float fx;1 R0 X4 l7 o! p2 u* f: }
- 121 for(i=0;i<NPT;i++)
; \ ]$ @6 l' U/ c - 122 {
8 w5 g+ g" g; v; @& n - 123 fx = 4000 * sin(PI2*i*50.0/Fs) + 4000 * sin(PI2*i*2500.0/Fs) + 4000*sin(PI2*i*2550.0/Fs);
. V/ s! l+ j ?$ P# V% E8 S# A3 @) \ - 124 lBUFIN[i] = ((long)fx)<<16;+ N2 m$ x$ F o* T) A
- 125 }6 v% j+ z- V) G! ^* s- x9 [3 F& S$ O6 d
- 126 }
4 a+ R4 U2 j% ^3 ] - 127
8 ]/ f1 r& L2 F$ z) Z; v3 o' C; r - 128 void dsp_asm_test()
, i) l6 M4 H! V) j2 N - 129 {
- V% f0 r7 A0 Y- |+ ~ - 130
3 p N; G* O5 f/ V - 131 #ifdef NPT_64
3 Z6 x2 ?" R# g0 s - 132 cr4_fft_64_stm32(lBUFOUT, lBUFIN, NPT);
$ H1 _! |: n8 V4 @5 @ - 133 #endif
7 Q. [, {$ Q8 L - 134 : F( O5 w/ j5 \
- 135 #ifdef NPT_256% e5 H- w1 B2 f2 Z) R
- 136 cr4_fft_256_stm32(lBUFOUT, lBUFIN, NPT);. H8 f- b. b' c/ Z+ \2 K
- 137 #endif7 a$ l3 b8 ?" d
- 138 G4 W* {3 `4 m# _* W
- 139 #ifdef NPT_10243 k" [3 v$ n: i( b6 v- M" ?
- 140 cr4_fft_1024_stm32(lBUFOUT, lBUFIN, NPT);
7 p; x2 S( F4 E8 E; R5 _ - 141 #endif
: o g5 t2 m+ ?6 _4 G& _1 B! { - 142
3 m9 s' p( @9 W4 v - 143 // 计算幅值8 M0 ^/ r1 i. \ ?/ L. P& y0 h2 f
- 144 dsp_asm_powerMag();
4 h% j6 G/ B- j8 ^ - 145
; d; F6 Z/ [1 |2 Y# `% \: D - 146 } M0 ~( i- O. y) L) s0 ]
- 147 & T# c3 w0 _/ U: G* }- Z% l/ e7 M
- 148 void dsp_asm_powerMag(void)
+ E2 O2 s. ]0 q) b, f - 149 {% _3 j$ u+ S! n( a s- G) ^( P
- 150 s16 lX,lY;/ ~! E; C: q: \; w2 k
- 151 u32 i;
) L& ]2 i0 _, I _- Y* o - 152 for(i=0;i<NPT/2;i++)
: w9 d/ r# |. ?; N9 J# ? - 153 {
) z& d+ v% |7 a - 154 lX = (lBUFOUT[i] << 16) >> 16;8 n/ ^5 a! S+ J! T
- 155 lY = (lBUFOUT[i] >> 16);6 ^7 `. }) J4 r' o" X. P
- 156 {
. }4 R) d) v& E! h) s5 J/ f. w - 157 float X = NPT * ((float)lX) /32768;( n* u+ [% B+ k0 Z5 V
- 158 float Y = NPT * ((float)lY) /32768;! M9 U( Z7 |" y" b
- 159 float Mag = sqrt(X*X + Y*Y)/NPT;& G6 P" O& w) J& l% ]6 c( U
- 160 lBUFMAG[i] = (u32)(Mag * 65536);3 d, r- f* J$ G
- 161 }" l$ c' E( `, W- {
- 162 }
! J. l3 z) _4 ^5 y2 F - 163 }
复制代码- 1 /*
( a- m" ~4 ?3 L& L$ | - 2 *********************************************************************************************************4 G8 P& j2 X0 d- D, ~
- 3 * MICIRUM BOARD SUPPORT PACKAGE0 e$ V( H9 p4 A: y' S+ O3 h
- 4 *% g7 N: U& n# ~% S; [; Z
- 5 * (c) Copyright 2007; Micrium, Inc.; Weston, FL
/ M; L! M3 a/ i7 Q; } - 6 *9 N) r& ]9 e5 Q, L4 ?% P
- 7 * All rights reserved. Protected by international copyright laws.( s$ q7 \8 d- G+ z L+ [! N+ v
- 8 * Knowledge of the source code may NOT be used to develop a similar product.
# n. z$ m( t2 Q; T& S" C! n% _ - 9 * Please help us continue to provide the Embedded community with the finest7 `7 s! T. \1 r2 K6 I
- 10 * software available. Your honesty is greatly appreciated.
) l5 m/ P: e; {$ u- B# T* [ - 11 *********************************************************************************************************5 l% `* W# O9 N2 x) V$ M
- 12 */
- v8 U2 [9 _* t% O - 13 9 s8 t/ r& f5 b; ^ C) {
- 14 /*$ h# _8 j, w7 A' ?+ \; H& l0 K
- 15 *********************************************************************************************************
* q- v0 ]4 }2 ?8 n- e: l - 16 *
% [- x/ I- n$ @& w1 [ ^+ t - 17 * BOARD SUPPORT PACKAGE& e, `3 D) M% }1 z
- 18 *, S2 U) D6 v2 s5 }: P7 O3 K3 f6 l
- 19 * ST Microelectronics STM32
; [4 i, |) O1 d k+ C9 O - 20 * with the6 t/ _: d+ d* r6 }; O
- 21 * STM3210B-EVAL Evaluation Board
: v5 s; O$ Y% g3 f; E, a - 22 *
, m2 n @# P/ Y& O( \& E - 23 * Filename : bsp.h
- Y5 J+ ]- g% a9 v) @8 {) J! j) B - 24 * Version : V1.000 n; B5 T0 v: }
- 25 * Programmer(s) : Brian Nagel
! m( j2 H; o6 j- E0 Y" e1 Z - 26 *********************************************************************************************************. M7 Q' w/ o/ v( {. b% Y1 @
- 27 */
% b7 C4 X! b& R+ K) y - 28
. X. \/ R |9 o; h2 z8 v# D; W/ A - 29 #ifndef __DSP_ASM_H__( ]7 Q$ G! O6 z4 `
- 30 #define __DSP_ASM_H__
, R7 ?% r6 P5 [! X$ c( W8 a - 31
; `- |/ `5 v1 ?$ b% {. b3 l, Y - 32 /*
- T' l) h7 I% D. j - 33 *********************************************************************************************************. V) F% m7 N' z4 ?; ?; X
- 34 * EXTERNS
( x- K* f: K5 Z& F# A - 35 *********************************************************************************************************
, \8 o( A" f* q - 36 */
$ ~/ m* v& P: L6 I& E: n - 37 ; ?* g5 g, D% U1 P$ ~
- 38 #ifdef DSP_ASM
. z g6 {( W) _2 [$ x - 39 #define DSP_EXT
/ e2 c7 M! `. @8 v- W' B2 M7 A - 40 #else
7 O; f' S4 W0 U* n/ O9 g - 41 #define DSP_EXT extern6 a1 k% o. p# m/ m/ O' \
- 42 #endif
. v% h1 @; b2 z5 { - 43
$ O+ j5 R K. P% y% p, B' j - 44 /*% m: ^; R" }/ {
- 45 *********************************************************************************************************; ]- N, u7 V: J% F
- 46 * INCLUDE FILES
8 I. B7 A( u, v2 | - 47 *********************************************************************************************************3 o7 Y) n4 y9 d9 B3 L9 |
- 48 */
( a* c6 ~( A) @' l; }! J a - 49
. ^- D' o" `6 ?/ U - 50 & {; C& T/ X! d% A8 @
- 51 0 v; R9 Z Q9 x7 ?$ V: D
- 52 . m: K! b% h0 _
- 53 /*
" S2 ]( U% `7 V& j' C& ?* F - 54 *********************************************************************************************************# v+ t7 [% W0 ~, u$ w
- 55 * GLOBAL VARIABLES* ]9 N# ?2 V8 X5 x' f9 h
- 56 *********************************************************************************************************
+ M) z7 s1 v0 | - 57 */% y* x# D- s2 O; x" d
- 58
o. O! [+ I& }7 p0 `( t# S - 59 : o8 w# P1 k' [% X: f4 w
- 60 /*% [# X+ \+ J3 n" ~
- 61 *********************************************************************************************************
# h+ i8 p j* _9 c: ^ - 62 * MACRO'S4 g) I/ F. t3 o* M2 i n7 G( u! a
- 63 *********************************************************************************************************2 {3 Q5 T7 F7 x2 ^/ M. D$ \
- 64 */
, \# R+ N( ~* x( w( X8 v - 65 2 R4 X) x m6 i& c$ g4 }$ H1 X
- 66
8 n @3 V+ K% X - 67 /*
6 {1 w0 ~) w& i! y3 _4 k9 m - 68 *********************************************************************************************************; |; @& e/ g9 b" S# i0 P8 f
- 69 * FUNCTION PROTOTYPES, w. |. X+ K* V3 E# t
- 70 *********************************************************************************************************
0 H: U; B+ n' k6 }1 S - 71 */
& `2 M8 }0 f r8 I) t( N - 72
' z/ I9 `, ` ~$ q - 73 void dsp_asm_test(void);5 Z( H+ C1 U5 _8 d# N
- 74 void dsp_asm_init(void);
' A. P2 F& D) q8 d: j - 75
. O5 r; k! k2 t/ s! N; p5 k7 T - 76 #endif /* End of module include. */
复制代码
3 ^( p7 q# q& {! d 着重分析下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位数据。下面的两句
2 ~# A6 y) n0 b7 X; V) } float X = NPT * ((float)lX) /32768; 0 |. T5 v. Y* Z" `3 ?8 Y/ C( z( K
float Y = NPT * ((float)lY) /32768; n1 i2 t/ K' F5 Q
目的就是把数据浮点化,至于为什么是除以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次方。然后才能进行其他的运算。) ^* [! ]. W2 O* |! v" l5 m
这里是ST公司采用了DSP专用芯片(主要是指TI)的写法,也就是说尽管DSP的芯片类型很多,数据变量的定义也各有差异,但原理是一样的,最终还是要采用DSP习惯的运算方式。至于为什么一定要采用浮点运算,因为机器是傻子,然而TI公司的工程师是天才。 main函数中我们只需在while(1)前加上dsp_asm_init(); dsp_asm_test();即可。; s" E* n, a7 ^4 n2 f' p7 U
2,实验现象 注意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
% {4 D) [& `+ l6 e6 x256点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谐波幅值
1 r4 ]& M( q9 U- j2 L" c5 ~. }( ^$ r 总结:该工程中模拟信号源为: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。
% l: c0 @! {6 G1 Y5 F9 \ |