本篇内容将简要分析STM32自带的DSP库文件,其用汇编语言编写,代码执行效率明显优于C语言,ST公司封装好了了库文件,我们不必看懂其汇编代码,只要会调用接口函数即可。 1,代码分析 首先我们需要在一个已经建立好的工程文件里添加如下编译路径: 工程需要添加的文件如下图:
% p" V& g4 \( x* r/ p( w 为了产生fft变换信号,我们可以自己产生个采样信号:使用三角函数生成采样点,供FFT计算,fx = 4000 * sin(PI2*i*50.0/Fs) + 4000 * sin(PI2*i*2500.0/Fs) + 4000*sin(PI2*i*2550.0/Fs)。
9 r, J' g) W% h. h- \" u" P( h: Y 模拟采样数据,采样数据中包含3种频率正弦波:50Hz,2500Hz,2550Hz, lBUFIN数组中,每个单元数据高字(高16位)中存储采样数据的实部,低字(低16位)存储采样数据的虚部(总是为0)。2 B* B( W: b: n8 @' o( m
其中dsp_asm_init()函数的作用是产生采样信号,实际工程应用中我们使用的是ADC采样的处理值。dsp_asm_test()函数的作用是进行FFT变换,并计算各次谐波幅值。具体代码参见下面:
; R$ [( ]! G$ ]- p: Y$ w- 1 /*( S8 _7 h4 c& {& l& C8 n
- 2 *********************************************************************************************************
5 ~: i+ i4 j* C2 S) }. B - 3 * MICIRUM BOARD SUPPORT PACKAGE
: I7 Z. |' W. x# E5 y+ l - 4 *& \" @$ S, I% G- J
- 5 * (c) Copyright 2007; Micrium, Inc.; Weston, FL, b+ N% h4 _; Q/ r) A
- 6 *
4 k( s9 A) Q# R2 P - 7 * All rights reserved. Protected by international copyright laws.
# C0 O t A7 _+ K1 E4 e/ h - 8 * Knowledge of the source code may NOT be used to develop a similar product.: _9 ~6 g$ f# B) v5 U
- 9 * Please help us continue to provide the Embedded community with the finest" d5 c+ P9 O/ X5 Y I/ H& E: c9 ?
- 10 * software available. Your honesty is greatly appreciated., z0 R# d( i) z: ~8 \+ l
- 11 *********************************************************************************************************; v7 n. `: S- a$ b/ |' x$ R
- 12 */
4 k# a% v6 a9 H0 y6 L' a - 13
: c6 D8 h+ E' G' j - 14 /*) h8 q* I4 p% v! l( x# N1 P
- 15 *********************************************************************************************************
1 [1 H4 g/ U, b* A7 w9 `2 O" b - 16 *8 ^) T9 N: Y/ q1 T% u7 H
- 17 * BOARD SUPPORT PACKAGE
/ c: x! o) X+ |! @ - 18 * y4 a& e* Z8 }# \0 ]. D. ]
- 19 * ST Microelectronics STM32* F/ ?% H. Z! |5 K9 p+ B0 [
- 20 * with the
! f; z7 ^5 y# s: u* L, p4 U* W - 21 * STM3210B-EVAL Evaluation Board( ~- N& F. e0 Y( F5 e2 N2 [
- 22 *5 P" q4 S8 h9 q7 O
- 23 * Filename : bsp.c* q+ b9 f% z) q* [( F" a
- 24 * Version : V1.00% R7 x1 h$ ?1 g2 F
- 25 * Programmer(s) : Brian Nagel, ~9 g+ |. K! i7 u2 U
- 26 *********************************************************************************************************# E% A$ A) z3 E6 m: D( C
- 27 */! U5 [% B5 ]& y3 i
- 28
- E0 y' T. k6 E% P - 29 /*
6 _4 K- {4 I0 _: b4 ]0 m& b3 ]: i - 30 *********************************************************************************************************5 C* P7 U: r. L
- 31 * INCLUDE FILES
4 J0 F* F7 |. c0 {2 g5 m - 32 *********************************************************************************************************
( [# g% O e8 _6 U- @+ D- C - 33 */9 ]# A: V. p/ w4 |) Q5 }! x
- 34
9 }0 _9 A( [& C) v8 p$ F( i# } M - 35 #define DSP_ASM
1 a$ t" T; i# g: V) B; I - 36 #include "stm32f10x.h": ^2 r$ f0 v8 _6 a3 [
- 37 #include "dsp_asm.h"/ |8 g& T" j j
- 38 #include "stm32_dsp.h"' O* H* ?& S/ ^
- 39 #include "table_fft.h"$ {9 {3 w- Q4 k4 M9 Q0 ]9 I* T2 o
- 40 #include <stdio.h>( X5 ]* a9 W7 x, H, ?
- 41 #include <math.h>
) Z1 Z' a. s! ^: S! `5 ` - 42
) F6 x/ Z* k: B# j0 P2 } - 43
$ a, o# L2 i0 a& u/ ^ - 44 /*
' U2 N* E/ H& e1 d& y5 f, { - 45 *********************************************************************************************************
# ^ f- j; I& V7 M# [ - 46 * LOCAL CONSTANTS
: a; j" E5 I+ D3 r, ^2 M7 t - 47 *********************************************************************************************************5 `, u- V8 ?( q$ c3 c, k& G+ {
- 48 */& `1 w8 m# I" C
- 49 #define PI2 6.28318530717959) d4 z$ G; D) f" ]: x3 P, e
- 50 #define NPT_1024 1024
. { w( ~( C4 F - 51 //#define NPT_256 256
) e- F$ s" m, v$ N! P/ _ - 52 //#define NPT_1024 1024
2 l9 v1 \6 M. A# m' ^' m5 V( f. A - 53 - [3 x, P; b3 c* |5 |1 @* X, L
- 54 // N=64,Fs/N=50Hz,Max(Valid)=1600Hz
& |& d8 d) P8 _& M, J7 @ - 55 #ifdef NPT_64
7 W3 L( \; t# ~" ` - 56 #define NPT 64
% J9 W1 j" p$ r! [9 m& G3 j- a( Z4 l - 57 #define Fs 3200
. c: x- A0 a. {. C# z/ v - 58 #endif: O, ~( J) M7 {3 l5 ~. ~
- 59
( M- x3 i- a( }: b; s - 60 // N=256,Fs/N=25Hz,Max(Valid)=3200Hz8 u: L6 H3 _+ c8 w' u
- 61 #ifdef NPT_256* W. V$ Y; r# f" @- ^4 A
- 62 #define NPT 256) i3 A# ~2 @. N& q$ j9 G( D
- 63 #define Fs 64001 G: i o6 a5 }3 z
- 64 #endif
* x0 }/ g# ?7 d - 65 7 I: A' j) l1 I
- 66 // N=1024,Fs/N=5Hz,Max(Valid)=2560Hz3 D3 N4 [: u, V
- 67 #ifdef NPT_1024
" Q, i1 Z& M! I, m1 g9 e8 ] - 68 #define NPT 1024; W1 |2 _- L( U# u8 p' c. w: @
- 69 #define Fs 5120' i. a* z4 ]% ?- ?) o, C3 K1 ~+ ]
- 70 #endif& C& c6 }" f2 m+ w
- 71
6 [6 P0 {- I# d - 72
9 _3 D, C) ^- K% h# Z* f1 O - 73 /*
* U& A; I) q5 M& L, c - 74 *********************************************************************************************************
O) e0 a. X3 u$ N - 75 * LOCAL DATA TYPES
+ _0 Z. x. e0 u: i; Z - 76 *********************************************************************************************************5 s( Z3 a$ q. Y k5 K# z
- 77 */
! r4 W7 ~5 w1 M X3 ^3 q* ^% v - 78 $ Y$ w* I$ M, F; n* x0 c7 x
- 79
% s2 L' R8 f0 Y& H6 a1 x) `8 H" o* J - 80 /*
3 O0 t, }2 E/ P: [* u' b% F6 H. Y+ E3 V - 81 *********************************************************************************************************: r9 ~, I% y1 |; j
- 82 * LOCAL TABLES- ]3 V3 k+ Z. I- i
- 83 *********************************************************************************************************
4 n7 e' U/ w% O) y6 w7 u0 f- o" G( } - 84 */
# C: H8 n+ b, [/ C7 c, u- ^ - 85
8 W5 k& T& a) a, z- ]6 Z2 E - 86 8 \; a( o2 j( t4 h) M( Y
- 87 /*
* p% f1 \2 [" r - 88 *********************************************************************************************************1 b7 n& M5 @1 ?" F6 o" y* E" \) j
- 89 * LOCAL GLOBAL VARIABLES
" k, v3 J1 d% X7 w# I3 z( O - 90 *********************************************************************************************************
' Y1 e% U/ p! L - 91 */& {& w! o9 L# U( G; ?: E
- 92 long lBUFIN[NPT]; /* Complex input vector */
7 L( C+ D4 E. i7 ^8 z7 I* M/ j0 c - 93 long lBUFOUT[NPT]; /* Complex output vector */3 V# k( b$ L0 I2 O: v1 f& D
- 94 long lBUFMAG[NPT];/* Magnitude vector */
% |! C6 D3 @& s3 O' @2 z8 r - 95 /*% J: I* r* \, S: x
- 96 *********************************************************************************************************
d5 h# }1 B6 X! X - 97 * LOCAL FUNCTION PROTOTYPES
' o6 y3 O" `2 E/ u! e - 98 *********************************************************************************************************1 r% f, E- w7 M; H. j$ \9 E# K, M
- 99 */! W. l* O4 @+ [
- 100 void dsp_asm_powerMag(void);
; J) S5 U4 ~- k% Z( ~1 c# ] - 101 ' z7 S2 z6 q2 I ?/ \% a+ j
- 102 /*
7 g& ~. K% ^9 W0 K! } - 103 *********************************************************************************************************
6 g( e* f" K! Y* h" d7 `) u( D - 104 * LOCAL CONFIGURATION ERRORS T+ A% A, Y+ _5 k& W7 Z
- 105 *********************************************************************************************************
6 S+ Z4 _2 w5 E3 I! l - 106 */* z- C5 `9 Q# g/ e
- 107
2 X1 j5 p! K( V7 f9 E' Y$ q8 _ - 108 6 q8 }! S7 D( w6 d; d0 \7 k
- 109 /*
+ w+ H: R; Q* D2 q - 110 ******************************************************************************************************************************# X( P' ]0 a7 O0 j7 w6 m; y: _
- 111 ******************************************************************************************************************************
! u z' e% S# y# K y - 112 ** Global Functions5 L0 N. V6 m* `7 K3 y7 P
- 113 ******************************************************************************************************************************+ F- x5 t4 k4 @# z
- 114 ******************************************************************************************************************************2 A# z: L) m0 ]5 j
- 115 */% x o: f& ]- x# k$ |! q# y+ J* K
- 116
8 Y6 M& G* B8 x - 117 void dsp_asm_init()2 T+ R7 b. T5 o3 k- }8 K
- 118 {
. i* ?7 s" z2 f5 o7 P' Y; S - 119 u16 i=0;
' {$ I" s H) S) t# T. i- c - 120 float fx;
! R. e; C1 v, W6 h/ I! z7 K - 121 for(i=0;i<NPT;i++)
. ?& `* q& w: d2 Q - 122 {
& x* T2 Q8 z+ S2 z$ w* T - 123 fx = 4000 * sin(PI2*i*50.0/Fs) + 4000 * sin(PI2*i*2500.0/Fs) + 4000*sin(PI2*i*2550.0/Fs);" r( v3 `$ z, N A8 d& F2 m
- 124 lBUFIN[i] = ((long)fx)<<16;* Z, \. h# R8 F
- 125 }* C6 ~/ l& K3 r6 v5 h1 T
- 126 }5 O8 e' ?, U% ?3 T
- 127
: {! D+ O/ F; `3 S - 128 void dsp_asm_test()
7 J8 [& q9 v" t" {/ v - 129 {; ]; v, Z/ u# u* x8 G' b1 P
- 130 6 Z$ M6 a, T0 b# N! k3 U: A+ A) ?
- 131 #ifdef NPT_64. t7 H% O' w) t, Y
- 132 cr4_fft_64_stm32(lBUFOUT, lBUFIN, NPT);
5 o- a# b) G8 E - 133 #endif s# g5 L# h+ P. F* j+ ~
- 134
- o% ]; s) k/ H - 135 #ifdef NPT_256
9 B! D1 p% Z4 t; Z' t) g) d3 t* k - 136 cr4_fft_256_stm32(lBUFOUT, lBUFIN, NPT);
9 U$ y" ~" D S/ w- t# ^ - 137 #endif
% Y* H! `* Q: G/ l5 S1 d+ a5 R - 138
5 _, S2 ^; N/ h2 I& ? - 139 #ifdef NPT_1024( ^0 [) j, Y6 m/ g( M
- 140 cr4_fft_1024_stm32(lBUFOUT, lBUFIN, NPT);
5 H; y7 Z8 `8 } - 141 #endif
# r* n* }( {5 v6 X - 142
0 D3 I! w) N$ L$ J - 143 // 计算幅值) \) }4 A' ?: j$ ^) u
- 144 dsp_asm_powerMag();3 G9 j0 o; d9 t; @6 J) f
- 145 ( O+ h3 J( ~' Y
- 146 }
- I a1 e0 n/ O. B - 147
. _! K& a5 O9 s - 148 void dsp_asm_powerMag(void)3 v% \: i6 ^0 d
- 149 {" i, M) b7 i- y
- 150 s16 lX,lY;
/ X5 E- i0 C9 \7 Z1 i - 151 u32 i;
& N' Q. R: P0 F% q - 152 for(i=0;i<NPT/2;i++)2 l+ ?' Q8 F+ M0 \/ s) J3 Q
- 153 {
/ }& d& o, p0 h) |+ r7 O* p- l - 154 lX = (lBUFOUT[i] << 16) >> 16;& t. {! V2 B6 H% t9 _ c. b) I
- 155 lY = (lBUFOUT[i] >> 16);% f* W1 G* S7 @- [3 F
- 156 {
) e1 a x/ f# b - 157 float X = NPT * ((float)lX) /32768;2 b |" @) S7 Q( _0 w4 Y+ x9 }
- 158 float Y = NPT * ((float)lY) /32768;; T& {) ^8 H' Z. W% R2 o
- 159 float Mag = sqrt(X*X + Y*Y)/NPT;- J8 [/ i* a ^( s1 k/ t% \
- 160 lBUFMAG[i] = (u32)(Mag * 65536);. z) ?: @6 t- D a3 ^
- 161 }2 V$ e) m4 c$ ]" ?5 X, K
- 162 }0 s% w, d3 H/ B
- 163 }
复制代码- 1 /*
9 W" @/ i8 e8 r$ o - 2 *********************************************************************************************************0 v- V4 z; h( H7 U. u9 _
- 3 * MICIRUM BOARD SUPPORT PACKAGE" f) ~+ x4 e* T
- 4 *9 u9 }% F. Y! f% C( I" L- s# J2 z% C
- 5 * (c) Copyright 2007; Micrium, Inc.; Weston, FL
! k. q- K$ z; r - 6 *
, ~; }0 k. f. S) i- a - 7 * All rights reserved. Protected by international copyright laws.: K( C3 I- T6 R7 g! y ]
- 8 * Knowledge of the source code may NOT be used to develop a similar product.
7 [8 z- o/ _' K) E2 I7 V( B - 9 * Please help us continue to provide the Embedded community with the finest1 D. L& y- a2 a( u/ N& q0 z6 |4 E
- 10 * software available. Your honesty is greatly appreciated.- @' P7 ]& s6 I' o4 |8 x* y3 j1 e
- 11 *********************************************************************************************************
4 K; a; k# ?9 Y8 S1 d - 12 */0 O0 `4 }2 G9 _0 N1 S# _/ ~" ^7 X" a
- 13 ( f: \/ x6 O' m; h3 L+ O
- 14 /*
' N2 w9 ^3 d% t; t( Z - 15 *********************************************************************************************************# M) y+ G- W: b& V. }
- 16 *% N6 q. b$ `2 s9 y
- 17 * BOARD SUPPORT PACKAGE
0 O, A4 y( M$ n5 x9 L# \( M6 N - 18 *
/ T8 n9 G' H( | B - 19 * ST Microelectronics STM32( l: ]% m5 t/ N2 R. G- p5 t5 w- X
- 20 * with the
0 K: B+ I& Z: C6 \+ I3 n - 21 * STM3210B-EVAL Evaluation Board7 O+ R9 T& c7 K
- 22 *
! R+ `8 M( T- T$ {/ W r - 23 * Filename : bsp.h# U. x l; I3 u! ] x8 S+ E7 y
- 24 * Version : V1.002 i; k1 [& R! q6 j# p
- 25 * Programmer(s) : Brian Nagel
8 y. u- ]8 {+ d( L - 26 *********************************************************************************************************
! H5 R) ~" J7 t* O" V- b6 Y - 27 */" k/ O3 u4 P; r. W$ t3 E
- 28 6 ^1 k4 \: s/ @$ Y% k
- 29 #ifndef __DSP_ASM_H__/ n9 y; b$ q2 e: ?6 Y( D S/ T1 q
- 30 #define __DSP_ASM_H__
9 H; |$ d* c Z! w - 31
$ m& M( u3 p. j5 Y - 32 /*
* h( ^( h2 w: @/ K - 33 *********************************************************************************************************- s% D3 l! q) x+ p
- 34 * EXTERNS& U0 s, y" h2 u3 m6 e6 l
- 35 *********************************************************************************************************1 ~- ^3 Y% p" k1 I# H
- 36 */
5 k% j: Z; z* e9 _& O! m; p) V7 K# u( b - 37
. Y: |4 N1 G- O& R% Z( Y - 38 #ifdef DSP_ASM
+ U- v# z( ^* i$ ]7 S* G( g4 c# `! e - 39 #define DSP_EXT) i8 B$ q3 y5 O: \6 }& _
- 40 #else1 x. Y4 b+ s; N3 p+ q
- 41 #define DSP_EXT extern
; N" n0 w- z8 {, x! }( ~4 f - 42 #endif
6 {8 H) G& G5 B' o( c - 43
1 ^6 ?% ?' a2 {% b9 Q/ v, b* H - 44 /*! I5 B2 v7 m: H7 R$ M, t# @4 _
- 45 *********************************************************************************************************7 z" v3 \' X& `( g# p
- 46 * INCLUDE FILES0 q7 S/ u- q- I: V
- 47 *********************************************************************************************************4 r( j+ O* l, Y, b3 \
- 48 */
2 W+ T" a' U$ d9 `2 z& v - 49
3 L& f% c: T' _) s" f( V4 Y, E x - 50 9 G( E l& d! W# e- h5 }: U: u5 Y
- 51 - w8 D k- G: u+ i5 ?5 G
- 52
& D. Y L _ c1 ^* ~ - 53 /*2 U5 W0 U0 f- M, J! g+ q) _0 q
- 54 *********************************************************************************************************
# t; u& \% L y3 G0 l- r, Q. d - 55 * GLOBAL VARIABLES
- ?- F& ?9 }! Q, M( Y; M - 56 *********************************************************************************************************0 z; a1 }$ N: F2 P/ X4 r. E5 Y
- 57 */
7 `. f2 P; P1 S - 58
( h8 p, e6 [9 Z& x. x2 g - 59 + `; j% ~9 R4 w9 g7 O4 }8 k
- 60 /*
5 @& v; S9 K/ J& b9 c+ m - 61 *********************************************************************************************************
7 V) O' o1 N9 w - 62 * MACRO'S, b, ^' o% y0 H# N
- 63 *********************************************************************************************************
, O Z0 i3 W1 h! Y: ~, i - 64 */# S6 [; o0 p7 M# x; o) \
- 65
" Y& v' I L- ]- u - 66 $ }" \ U. W; f4 X) H6 b8 B
- 67 /*
1 m3 K5 M. O1 E- d0 Z; v% @ - 68 *********************************************************************************************************) c3 L6 I: I9 ]! S
- 69 * FUNCTION PROTOTYPES
4 R) b5 z5 L; b7 D+ j& n2 k7 }: z - 70 *********************************************************************************************************+ q0 Z8 K& w7 B
- 71 */+ m# x. B8 D* C+ C6 O6 A
- 72
8 Q/ M& Q% d# {# x- h; ]; E* j' J - 73 void dsp_asm_test(void);
# F! T( C8 J8 j7 T - 74 void dsp_asm_init(void);/ n! l. n1 ~$ c. N% O0 `6 E: I7 l
- 75
2 M6 D# @& C! N' F/ K- C - 76 #endif /* End of module include. */
复制代码 3 _/ L8 l3 I! h* B2 e) T" m
着重分析下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位数据。下面的两句4 x/ C3 ]8 @8 [0 t) h" R# r( p
float X = NPT * ((float)lX) /32768;
) S* q4 V1 P6 W& u. y float Y = NPT * ((float)lY) /32768. |% C; t! i+ S, O
目的就是把数据浮点化,至于为什么是除以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次方。然后才能进行其他的运算。2 C9 @# M6 P, ], B/ m) @
这里是ST公司采用了DSP专用芯片(主要是指TI)的写法,也就是说尽管DSP的芯片类型很多,数据变量的定义也各有差异,但原理是一样的,最终还是要采用DSP习惯的运算方式。至于为什么一定要采用浮点运算,因为机器是傻子,然而TI公司的工程师是天才。 main函数中我们只需在while(1)前加上dsp_asm_init(); dsp_asm_test();即可。, k7 ]9 b/ F7 ^% {9 O" h
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# |+ n" c' ?, a* h2 D
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谐波幅值
+ d5 b3 w, T( _: Z' y7 F 总结:该工程中模拟信号源为: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。 R) ~0 R! ^. ]: _
|