|
本篇内容将简要分析STM32自带的DSP库文件,其用汇编语言编写,代码执行效率明显优于C语言,ST公司封装好了了库文件,我们不必看懂其汇编代码,只要会调用接口函数即可。 1,代码分析 首先我们需要在一个已经建立好的工程文件里添加如下编译路径: 工程需要添加的文件如下图: 5 z% V- D m! j2 W1 f! Q2 O
为了产生fft变换信号,我们可以自己产生个采样信号:使用三角函数生成采样点,供FFT计算,fx = 4000 * sin(PI2*i*50.0/Fs) + 4000 * sin(PI2*i*2500.0/Fs) + 4000*sin(PI2*i*2550.0/Fs)。
; l3 M0 e7 u, W# ^) I 模拟采样数据,采样数据中包含3种频率正弦波:50Hz,2500Hz,2550Hz, lBUFIN数组中,每个单元数据高字(高16位)中存储采样数据的实部,低字(低16位)存储采样数据的虚部(总是为0)。4 W. T! A( k4 Q# v, t& c# F
其中dsp_asm_init()函数的作用是产生采样信号,实际工程应用中我们使用的是ADC采样的处理值。dsp_asm_test()函数的作用是进行FFT变换,并计算各次谐波幅值。具体代码参见下面:2 v& X( t% u7 N, r9 v" a7 q/ j$ a& Q
- 1 /*
?7 K6 b% k4 r G, d7 j - 2 *********************************************************************************************************# f I' X4 M0 p# f+ W
- 3 * MICIRUM BOARD SUPPORT PACKAGE. E& n( z! `9 z# Z2 W: B
- 4 *
" h" k: ]3 L5 a( ?$ s& Q3 q - 5 * (c) Copyright 2007; Micrium, Inc.; Weston, FL
9 `, m8 R2 P& [% c, O+ l# ]; [ - 6 *
" `0 K$ \: X, s* K7 A: C, z1 q6 t, ~ - 7 * All rights reserved. Protected by international copyright laws.% {% F* {% \& T, n5 a5 H y
- 8 * Knowledge of the source code may NOT be used to develop a similar product.
* u$ F7 B. n# O/ o, a. F - 9 * Please help us continue to provide the Embedded community with the finest: S. v* L9 n% y _# J
- 10 * software available. Your honesty is greatly appreciated.
( J( g( |6 U& d - 11 *********************************************************************************************************
* E. o1 t0 v5 Q. c - 12 */
0 p3 j$ V( c" Z1 y3 H1 @- N - 13 , k2 R& v8 j. q
- 14 /*. Z1 F: e- y4 I/ M2 G& C' K8 A
- 15 *********************************************************************************************************
! u: S" e/ S2 |4 D - 16 *2 v4 ?- _" Y) V
- 17 * BOARD SUPPORT PACKAGE( p# ]2 m% w0 X& j! [ \( X
- 18 *
7 u# [5 U9 E- L: J! m. G0 S - 19 * ST Microelectronics STM32, y4 }% j Y) U7 l0 O+ j; T
- 20 * with the5 c* J9 a7 J- r2 m! T9 H0 c
- 21 * STM3210B-EVAL Evaluation Board
& o2 p& q8 E( H, P0 ? - 22 *2 I6 F* d( c% V& Q! a+ a5 w
- 23 * Filename : bsp.c% Y3 U1 }9 S# L! m# R! h
- 24 * Version : V1.001 N5 L1 L! Z; c9 P
- 25 * Programmer(s) : Brian Nagel$ R9 L2 q9 }, _# A( k
- 26 *********************************************************************************************************
- q$ Q- u3 z' P0 U/ J. B& M - 27 */6 n% o0 d' m1 I+ y
- 28
3 b; C/ q, W {5 q0 r) p+ r - 29 /*
5 W, ?$ ]: K0 t7 H/ ` E) j - 30 *********************************************************************************************************" R: W, U& g$ H: ^
- 31 * INCLUDE FILES3 g2 F# k* r1 Q% K4 ]
- 32 *********************************************************************************************************! D. z( F- s+ U# p% _
- 33 */
C3 G! }" _2 g - 34 $ t6 Y! ]0 L# C
- 35 #define DSP_ASM
1 J7 e8 i9 e& N4 G$ D5 M6 x9 q - 36 #include "stm32f10x.h"
+ C/ K0 u% h: L) W3 q! Z - 37 #include "dsp_asm.h"
5 H" I7 y, R5 O' H0 b - 38 #include "stm32_dsp.h"8 m5 X8 S- ]: Y3 [2 u( Y! s: X3 N% [6 S
- 39 #include "table_fft.h"% b$ ~) I) C* T9 d7 F: [$ Z0 r+ V
- 40 #include <stdio.h>
/ z) S. @% l1 w2 I - 41 #include <math.h>8 E0 F. t \1 A, C# ^! H
- 42
. ?1 {( ?! b" v - 43
6 p* I9 |0 ^7 K1 E [+ U* ?1 D0 B- L - 44 /*+ G% z$ X6 @% w! X( d, ]! L
- 45 *********************************************************************************************************
4 Y. \" x8 {) J7 ?7 d! ?/ i0 L - 46 * LOCAL CONSTANTS
J& g& D1 z5 i( _: h$ ] - 47 *********************************************************************************************************
9 D; z, _+ o, Y+ J: Z- }' q$ p( E - 48 */
+ A% H. `1 d6 w7 T5 Q5 D( E: F - 49 #define PI2 6.28318530717959
, Y# }5 N, ?: G% q - 50 #define NPT_1024 1024
9 b8 l: d/ O! c& _5 Q - 51 //#define NPT_256 256
% q. c: h7 ^* p' e1 }& J9 M: f - 52 //#define NPT_1024 1024
7 l6 Q6 Y6 X7 ^; q. w1 t2 i - 53 6 r6 R2 X- C) u# T& |! i; O* r, g
- 54 // N=64,Fs/N=50Hz,Max(Valid)=1600Hz, ~( M4 E- R0 ?" |5 a. B. I
- 55 #ifdef NPT_642 N( D, g, c% f# P3 Q; p& u
- 56 #define NPT 64
+ A ]+ G! r+ o4 h8 V6 l - 57 #define Fs 3200) n) J+ x2 `3 m4 s% j
- 58 #endif) e& j+ R7 @+ ^1 f
- 59 * ?& k f2 D3 q* A! A( n/ F4 b
- 60 // N=256,Fs/N=25Hz,Max(Valid)=3200Hz
3 M1 ]: S$ L) I& {. p$ C - 61 #ifdef NPT_256' \1 M5 w v6 V% n2 c- o
- 62 #define NPT 256
- M" z# x% V% q1 _2 | c! N - 63 #define Fs 6400+ k% W9 r2 r/ k! r$ J
- 64 #endif
8 [+ `; E# R9 J) o; E - 65 6 ?- @; O! T, ]/ e2 G
- 66 // N=1024,Fs/N=5Hz,Max(Valid)=2560Hz
- F0 b/ c, I3 `4 `: ? X$ S8 \ - 67 #ifdef NPT_1024( R& a# [* ~# G1 X1 j( W4 J3 p) ?
- 68 #define NPT 1024
3 @, L7 Q6 C2 {1 m' v - 69 #define Fs 5120
* c+ L$ Q" p" [0 G# ? - 70 #endif0 {2 D& M" P `" i4 g
- 71 & Q9 o. h9 r4 B8 o2 v
- 72 1 D5 U0 g6 _8 P# ~0 X7 x
- 73 /*
8 i A2 d" r' Z& L; M - 74 *********************************************************************************************************& b4 c7 i* ^+ W9 G6 ~+ M
- 75 * LOCAL DATA TYPES. Y& I( z. o% g7 [" w! i1 {
- 76 *********************************************************************************************************
: G" b1 n4 p3 E, } - 77 */3 w3 h5 _5 s$ _+ g
- 78
$ @4 }! W% x2 k2 ]! H% q: t - 79 , }2 i- l% _ X) O0 J- z) E' l
- 80 /*
, h! |- o2 o; {3 @2 u - 81 *********************************************************************************************************
9 j9 G0 s& {4 s7 w" H/ p8 Q) o f+ R - 82 * LOCAL TABLES" X2 o/ x9 N% b* A& a0 H( s
- 83 ********************************************************************************************************** a; O6 m( E/ x( \
- 84 */
" {9 Y/ o- c3 o - 85 5 m( z, W, e9 ~, i, B" k
- 86
! K% f! M+ ~' L6 i - 87 /*5 V/ l4 ]; C: p5 W; g
- 88 *********************************************************************************************************
) q6 Q! g, R. y& g- B" V4 \7 s0 K - 89 * LOCAL GLOBAL VARIABLES
$ }0 |/ N% y: q - 90 *********************************************************************************************************9 ~, _* u4 e% Z* {# }: y
- 91 */
4 k) I4 w& S/ c" d- Z7 p2 R3 q, o - 92 long lBUFIN[NPT]; /* Complex input vector */
% M- a$ P: V2 \4 G, b% ~ E. R - 93 long lBUFOUT[NPT]; /* Complex output vector */# n7 R' _4 J7 q' u
- 94 long lBUFMAG[NPT];/* Magnitude vector */# b4 O% n1 j2 j0 @$ [4 c( n
- 95 /*6 T, U7 c- [9 r' c
- 96 *********************************************************************************************************
9 {% J& p+ n6 u1 x - 97 * LOCAL FUNCTION PROTOTYPES" V" ?4 W" O N0 D
- 98 *********************************************************************************************************
7 y0 e9 s T | - 99 */
6 Z3 {5 P( \3 g' R; `9 d6 M8 B: o - 100 void dsp_asm_powerMag(void);
8 K% M; y7 v- O5 Y/ ] - 101
7 Z# t7 `. d0 ` - 102 /*
+ g; |5 b; e% t' q3 e3 @5 K( \& P - 103 *********************************************************************************************************: k, u% c, N: A" a/ p) v
- 104 * LOCAL CONFIGURATION ERRORS0 @% l' X' |+ |1 U6 \& h
- 105 *********************************************************************************************************( k5 Y# q! j% Y% l# K/ T5 I: D
- 106 *// l% ?, A1 Q" j0 ^& |4 p
- 107
5 n; }& r; ^& [3 j- h: T, F - 108 4 E4 W) C- |7 J* _* o
- 109 /*
m% f5 Y$ F( r/ j2 c - 110 ******************************************************************************************************************************
& v( U9 O/ l! P4 m4 _$ u. z3 z - 111 ******************************************************************************************************************************
+ J, H; i+ y$ @4 d - 112 ** Global Functions, `3 c5 O) o5 P
- 113 ******************************************************************************************************************************; g! m4 D8 p( f" k1 u5 K' g
- 114 ******************************************************************************************************************************* ~8 w' T/ Q& l' `
- 115 */2 p3 H, \; l* R R: f5 X+ x7 D4 r# U
- 116 ' M; X3 I( e5 P
- 117 void dsp_asm_init()3 W, r/ N2 S% d1 V, g
- 118 {( Y2 i% _* E' @, w P* F# i
- 119 u16 i=0;) a! Y* r$ f2 ]" u9 O
- 120 float fx;4 v: b$ X) R8 n, @+ R
- 121 for(i=0;i<NPT;i++)/ M" u- G/ w% `9 {) X' E' G
- 122 {& S3 U! U* g5 j6 c7 [" C
- 123 fx = 4000 * sin(PI2*i*50.0/Fs) + 4000 * sin(PI2*i*2500.0/Fs) + 4000*sin(PI2*i*2550.0/Fs);" G5 s/ y' X+ [" B
- 124 lBUFIN[i] = ((long)fx)<<16;7 |- q# w/ E% h+ c1 H
- 125 }. K8 N, S+ @; a2 K4 D Z2 N
- 126 }
( n; D% J3 P4 ~ - 127
4 R3 e5 a2 T7 k) d& o6 y0 f4 G - 128 void dsp_asm_test() ?/ G4 R) P- ]; f# j
- 129 {
, R( J" m, R. C6 M - 130
& j& t- J- \8 _% S" N - 131 #ifdef NPT_64+ l8 {$ F/ X% y
- 132 cr4_fft_64_stm32(lBUFOUT, lBUFIN, NPT);
, j6 G5 o3 n$ o6 ~& t- f - 133 #endif' L7 x. I9 [# {6 C
- 134 / o0 l; x+ r0 \/ t
- 135 #ifdef NPT_256
8 r7 E B8 Y) j8 w; B4 D - 136 cr4_fft_256_stm32(lBUFOUT, lBUFIN, NPT);8 P4 j) P* G7 y" a) z) v
- 137 #endif
9 {" p5 {% s; h2 Y: D* v$ ~ - 138
8 R- h2 L) `* ] Y8 N5 |9 G& G - 139 #ifdef NPT_1024
' s, P, U) [" s! H - 140 cr4_fft_1024_stm32(lBUFOUT, lBUFIN, NPT);
- M$ B$ a1 k, R' t( a: `# m: U - 141 #endif
8 s; c* T2 h4 E7 j4 D: B - 142 ) S* H) ~0 j3 Z" j7 k
- 143 // 计算幅值7 `- |; p# G) A% N$ F# J( y# s8 }
- 144 dsp_asm_powerMag();
$ n& k$ w" P, c' K2 L& K. v4 T - 145 2 Q3 T4 j! V# A0 l. L2 j
- 146 }7 ^! N/ m; Y+ O7 k' I
- 147
- q$ K0 D# ], x- _' t( O - 148 void dsp_asm_powerMag(void)
I$ |9 {4 k' Q6 y% Z9 ^4 H* o# D' g - 149 {. H: k: I7 r2 q" K
- 150 s16 lX,lY;
# s( q9 }& q( j/ c4 S - 151 u32 i;
' Q; B' s/ z0 f0 r9 W - 152 for(i=0;i<NPT/2;i++)
: N4 p7 o0 H g. u - 153 {
( F' ^, p- Z: W, X# N - 154 lX = (lBUFOUT[i] << 16) >> 16;+ f5 e- }, K" C) }( V& t
- 155 lY = (lBUFOUT[i] >> 16);2 x, ]3 x9 E' i
- 156 {' l H9 X3 _& T3 o
- 157 float X = NPT * ((float)lX) /32768;6 ~. h' V; M0 e4 ~0 d/ P( B
- 158 float Y = NPT * ((float)lY) /32768;# S( W2 l# U3 ~( m
- 159 float Mag = sqrt(X*X + Y*Y)/NPT;
2 C$ G) T; Y! l. T2 i4 U/ v - 160 lBUFMAG[i] = (u32)(Mag * 65536);, Y; q0 C8 J& [+ e. a
- 161 }
6 v8 @7 z$ b$ y1 ?+ v - 162 }
- F0 `1 N$ |* M- v( @ - 163 }
复制代码- 1 /*
$ s# \5 ]$ K8 S' s2 O! X. T - 2 *********************************************************************************************************' b% i v& ~$ S2 K0 B k( v
- 3 * MICIRUM BOARD SUPPORT PACKAGE
. n J) z( S4 U: r - 4 *! `: \ L4 {# `( T: y
- 5 * (c) Copyright 2007; Micrium, Inc.; Weston, FL
1 g. l; t U& @0 @& U: H2 O - 6 *
; u: I( i9 W8 {" v - 7 * All rights reserved. Protected by international copyright laws.
( P+ C2 u: B' h - 8 * Knowledge of the source code may NOT be used to develop a similar product.7 |4 w# Z% Z3 u7 _' G6 T
- 9 * Please help us continue to provide the Embedded community with the finest
' ?3 J' Y! r6 c/ | - 10 * software available. Your honesty is greatly appreciated.' B+ p( |* P; a- A& ^
- 11 *********************************************************************************************************
# x, T" ?! m; c% T) w0 \ - 12 */
1 f' E8 L$ j' _( k - 13 % h/ x1 F4 B4 O- v
- 14 /*, ?# A5 a. Z/ g" p, H
- 15 *********************************************************************************************************
$ G& G) D. w7 P - 16 *
@' R2 P9 K9 c8 r9 k$ g' v - 17 * BOARD SUPPORT PACKAGE
' s6 Y6 T$ b8 |3 c7 } - 18 * E( U3 B* k) J0 R
- 19 * ST Microelectronics STM32* T8 C1 g, a- { \. G4 ^' h8 h. f
- 20 * with the
* X/ R7 g, a M# w$ X, x3 K+ ^ - 21 * STM3210B-EVAL Evaluation Board
; n$ A& M' j1 ~3 B - 22 *
0 }5 v& o4 \/ B+ ~8 D T - 23 * Filename : bsp.h
R ~6 w8 P) U+ B - 24 * Version : V1.00( M- b& @/ v1 D K- E! ? t2 x6 X
- 25 * Programmer(s) : Brian Nagel. D: q6 Y5 _, ~# q7 k- A# o2 r9 X
- 26 *********************************************************************************************************
: o3 q5 E' p: w, m" A/ m' r1 o$ K - 27 */: t( m* e. p/ m f$ ]7 Z; K+ h4 z5 m
- 28
( g4 {: n3 Y9 F8 r$ _1 K, y - 29 #ifndef __DSP_ASM_H__7 W6 ^0 z! a1 ^) y/ ~& I4 H
- 30 #define __DSP_ASM_H__ C$ b, ~" b) o; k+ h
- 31
4 X0 U5 p& E( r/ j ` - 32 /*5 o( I; b. G# p# v
- 33 ********************************************************************************************************** [5 Z8 m: p6 R- h
- 34 * EXTERNS
/ l {$ }; B. \4 s% G+ e - 35 *********************************************************************************************************
2 @: M( `. B6 a$ i) B - 36 */5 G/ ]8 [4 o8 w; `
- 37
% v: h" t; }1 o" x! r! @ r4 r - 38 #ifdef DSP_ASM
: a" m8 T& i: w" h5 k - 39 #define DSP_EXT
, ^$ f6 M) v1 S3 C! p B - 40 #else
. v6 w6 f5 N5 @2 Q3 z# T% {3 q - 41 #define DSP_EXT extern6 i' z1 x J* ~* ?- f- Z/ b" \
- 42 #endif
, E7 O$ d _9 N - 43
* a) `6 y, X$ j: ^* w' q - 44 /*& t2 G6 F5 A* b. Z$ [9 F V, r
- 45 *********************************************************************************************************
- r$ _7 W, y9 i1 [ - 46 * INCLUDE FILES
{) i7 h% A |) @ - 47 *********************************************************************************************************2 E4 ], p9 W2 v
- 48 */
# V0 B9 v7 v4 X3 O - 49 $ e6 E1 g! O+ |5 s G% ]* S
- 50 0 Q6 [9 y8 y+ e$ d
- 51
9 P5 O/ m' }( ]2 X# j3 q - 52 & v7 |( k+ b# C$ B6 b5 ?
- 53 /*
+ P/ }6 O7 G5 u# l+ S - 54 *********************************************************************************************************
4 b9 n, F" b' y9 |# i - 55 * GLOBAL VARIABLES
2 [# b: X. A2 u - 56 *********************************************************************************************************, o N+ a. h) y% c9 r
- 57 */7 _6 ^3 X2 D9 h+ |7 y
- 58
9 r: e1 a! g1 Z - 59 ( m) |# f" \1 a8 Q
- 60 /*1 l6 Y2 d/ m! F' [* ?! o; X
- 61 *********************************************************************************************************2 f+ ]' q8 C2 z' F s# m
- 62 * MACRO'S
2 o2 \; L+ a8 j2 R1 l6 q2 x - 63 *********************************************************************************************************" T6 M* R4 c5 E) G- ], { A3 m
- 64 */
: W0 q$ _" K' L( j: ^% r4 t - 65
# v1 q* D; b% L, r - 66 * K5 J6 X: O. ]$ p+ v$ t$ B5 p
- 67 /*
6 n' k. t/ o% I- p6 M - 68 *********************************************************************************************************
& [" F2 |4 x, J1 b" ]- E' F% G - 69 * FUNCTION PROTOTYPES
, b# \ ^4 `9 ?" Y, |" h1 Q: v - 70 *********************************************************************************************************9 [ X; _2 ]- }- p
- 71 */ \/ W" {" {; o; X" U: z
- 72 ) _6 {0 @8 q' f$ H$ t% F
- 73 void dsp_asm_test(void);
% [: `2 o' S: c# R) y; Z - 74 void dsp_asm_init(void);
* @9 \1 A5 F* ^* e% ? - 75 [: M0 J. t9 J5 ]/ \
- 76 #endif /* End of module include. */
复制代码 ; {# S. f2 D: ]& }0 R+ ?. }+ {# Y- K
着重分析下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位数据。下面的两句$ t' |, l S* C% j6 N
float X = NPT * ((float)lX) /32768; 6 u t0 G1 z" W, x+ K" L0 s S
float Y = NPT * ((float)lY) /327689 O0 {- y) E# U; |- [
目的就是把数据浮点化,至于为什么是除以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次方。然后才能进行其他的运算。6 d# x/ k3 e0 o1 t2 d" p. `$ e
这里是ST公司采用了DSP专用芯片(主要是指TI)的写法,也就是说尽管DSP的芯片类型很多,数据变量的定义也各有差异,但原理是一样的,最终还是要采用DSP习惯的运算方式。至于为什么一定要采用浮点运算,因为机器是傻子,然而TI公司的工程师是天才。 main函数中我们只需在while(1)前加上dsp_asm_init(); dsp_asm_test();即可。8 _8 W* S# A/ a3 v5 B7 K' m
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,测量最大有效频率3200Hz4 B2 D4 z% x/ u8 h4 o
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谐波幅值 7 G; l# f9 d! O. o; n( P
总结:该工程中模拟信号源为: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。 8 ~) O& r7 x& s3 [8 e# i
|