|
本篇内容将简要分析STM32自带的DSP库文件,其用汇编语言编写,代码执行效率明显优于C语言,ST公司封装好了了库文件,我们不必看懂其汇编代码,只要会调用接口函数即可。 1,代码分析 首先我们需要在一个已经建立好的工程文件里添加如下编译路径: 工程需要添加的文件如下图: 4 U: w: [* t) J0 B0 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)。! u& }" ]( X* C1 }. U
模拟采样数据,采样数据中包含3种频率正弦波:50Hz,2500Hz,2550Hz, lBUFIN数组中,每个单元数据高字(高16位)中存储采样数据的实部,低字(低16位)存储采样数据的虚部(总是为0)。
/ D* C! b C6 N0 A. [ 其中dsp_asm_init()函数的作用是产生采样信号,实际工程应用中我们使用的是ADC采样的处理值。dsp_asm_test()函数的作用是进行FFT变换,并计算各次谐波幅值。具体代码参见下面:
1 F; J- K6 j. e( m$ H3 b( |1 F- 1 /*7 _# U. e9 k" |( I4 P- F" r/ p! }; U
- 2 *********************************************************************************************************
! T; }1 J# w4 D) v# o6 E5 y" ~7 C - 3 * MICIRUM BOARD SUPPORT PACKAGE' X9 T' v2 [: k
- 4 *
/ d" b4 J6 }- I/ X0 n) Q - 5 * (c) Copyright 2007; Micrium, Inc.; Weston, FL1 k- `3 r% g1 T8 c
- 6 *7 ^& `) F0 q5 _9 S J
- 7 * All rights reserved. Protected by international copyright laws.
. l+ C/ {2 K7 b# H: W( t4 U9 K - 8 * Knowledge of the source code may NOT be used to develop a similar product., d# Z/ @7 w: l, ?/ T6 ]
- 9 * Please help us continue to provide the Embedded community with the finest+ Z, y! H/ ?1 i& n2 b+ h
- 10 * software available. Your honesty is greatly appreciated.
3 S m4 V5 x1 E! j- a - 11 *********************************************************************************************************: G2 ]$ H7 T* c6 M2 G
- 12 */) P: T B/ t# f
- 13 G# b4 O- g) f9 l6 m
- 14 /*8 ~; L. e& ?6 A/ x
- 15 *********************************************************************************************************$ L, R' s( m ~
- 16 *$ f5 Z7 W) g8 N( g* |" Z" s* K
- 17 * BOARD SUPPORT PACKAGE
4 v$ x8 i* t' Y- q - 18 *
9 y' l$ s& k% S. K - 19 * ST Microelectronics STM32* ~ S o- P5 h
- 20 * with the
$ \: p, C2 i7 i' ? k# \5 w - 21 * STM3210B-EVAL Evaluation Board
$ f6 k @' _* A- ?* c2 ^ e3 k - 22 *7 K- H) I5 c& l; ?
- 23 * Filename : bsp.c9 ~% e ~1 h8 A `2 k
- 24 * Version : V1.00
5 W2 [9 m5 M) U) b5 l, x9 t# D& c1 r0 z - 25 * Programmer(s) : Brian Nagel/ Q( A" A) g7 Q& n
- 26 *********************************************************************************************************
. V0 Z) E, B* y$ k7 H6 | - 27 */
2 D' ?: @8 y; \+ q8 `) Y - 28 1 C' z0 f" r m" k* ]) P9 G- J% O6 [
- 29 /*
|+ N. o; s3 v, Q3 s' l - 30 *********************************************************************************************************
4 ^& T& c+ m4 f; a- U. c - 31 * INCLUDE FILES) A7 ]7 l' B. i5 n% a# t
- 32 *********************************************************************************************************
/ ^3 o: f( s6 V' e - 33 */
q+ t e- R7 V5 \ - 34
- K$ {# M. m- t" ]% @ - 35 #define DSP_ASM' n$ i$ [; K% V7 i! f
- 36 #include "stm32f10x.h"; Z/ r- m: T' f! q/ O# L
- 37 #include "dsp_asm.h"
" I8 Z D; Z4 T: p1 F - 38 #include "stm32_dsp.h"
+ J: i; q& x/ t* A$ T0 k - 39 #include "table_fft.h"
2 f3 j ~2 F. D& J - 40 #include <stdio.h>1 U( V; B$ x; v) c9 U* S
- 41 #include <math.h> e6 V0 A) b7 A$ G; w
- 42
; ]5 S- C5 W; w& t - 43 " u k& S7 }! U8 s+ k2 J
- 44 /*; q# \) G! S+ w( u9 W
- 45 *********************************************************************************************************
* ^4 J+ l+ l4 L. P1 T$ j - 46 * LOCAL CONSTANTS8 E5 J( H; \; t; Z; l
- 47 *********************************************************************************************************
# D$ e5 k3 x4 z' b - 48 */: w$ V- G8 b* I2 @' z
- 49 #define PI2 6.28318530717959
5 O d* P4 L+ A# M - 50 #define NPT_1024 10244 z; Z. R: g3 R( o! Q4 A- j: h
- 51 //#define NPT_256 256
! `- | ]+ P. P - 52 //#define NPT_1024 1024/ ]- I1 {, x* R3 n! [& A! R
- 53 6 ] |' L; ?2 M( R, B2 c# @
- 54 // N=64,Fs/N=50Hz,Max(Valid)=1600Hz
' l1 h- V" G0 \2 O& l - 55 #ifdef NPT_64
7 b {$ r G3 t' V/ k. O3 i- L3 u - 56 #define NPT 64- n) v4 v0 i. w# ^% u# H
- 57 #define Fs 32008 J7 ]8 \1 ], l1 w) g3 f
- 58 #endif$ ?" f K9 P5 J8 a
- 59
' ]0 s A- ]1 ?+ v, O4 H" i+ y - 60 // N=256,Fs/N=25Hz,Max(Valid)=3200Hz
4 g5 K* W, C# n4 k+ E - 61 #ifdef NPT_256( l, N3 t; y K
- 62 #define NPT 256
! y5 _+ u; E Q( s7 R1 E - 63 #define Fs 6400
9 C$ e5 n( N% F# F+ n- y) [ - 64 #endif7 \% z7 r. e: ~' ]6 Y+ t
- 65
- s' _1 R! G9 o0 i3 P7 ^# j. o - 66 // N=1024,Fs/N=5Hz,Max(Valid)=2560Hz9 a" j9 m+ ~ f" Y
- 67 #ifdef NPT_1024; U: M" Q0 n# @% L9 K+ P% V
- 68 #define NPT 1024! { O- M" D" J- h+ \1 l
- 69 #define Fs 5120: O5 i9 E) U h& O, `% S
- 70 #endif
5 Q1 M- R2 ~ n) ^! q$ l" V - 71 2 f9 [. `: B3 j
- 72 * ^" l- M8 l/ [- k5 `/ @
- 73 /*
7 C& m0 {% T$ J9 m - 74 *********************************************************************************************************) W$ x W" G1 q* C* H1 p: l
- 75 * LOCAL DATA TYPES4 x7 f: {) m! `! {
- 76 *********************************************************************************************************
/ R c; N$ L5 O: _, \ - 77 */6 b; i- }3 m3 C7 |$ k! m
- 78 " Y0 |$ a& T6 Z& c7 {7 u, d' e
- 79 6 v( N( F; p( L4 g( c% B; h% a% F- c
- 80 /*
3 `7 e* d, A6 R' a2 @ - 81 *********************************************************************************************************
* l, b- W. ]1 s' | - 82 * LOCAL TABLES3 T" F; A9 r6 A
- 83 *********************************************************************************************************3 r0 q# j) [0 E, v+ D
- 84 */0 {) q3 m/ s- E) u0 v
- 85
) {. J9 r) c$ A4 G - 86 , t; I4 q) K5 `) w! u% B' z
- 87 /*; ?: E9 T( x3 |5 Q! }5 ^! t
- 88 *********************************************************************************************************
: A8 y: C" y! r' Y; ` - 89 * LOCAL GLOBAL VARIABLES
0 ?" b; D4 D" I& G, H# i - 90 *********************************************************************************************************: X* p/ y% ?/ z& E
- 91 */
3 g6 |+ k! j f - 92 long lBUFIN[NPT]; /* Complex input vector */
2 @8 g! C" l; a% T - 93 long lBUFOUT[NPT]; /* Complex output vector */, V; Y) o0 ]& m. N0 e% I# P+ w( m2 V
- 94 long lBUFMAG[NPT];/* Magnitude vector */" \- U7 `* Z& W" Z3 X2 y5 g2 \
- 95 /*
6 [/ y) u" \& J8 r5 o - 96 *********************************************************************************************************6 T: h( s7 `$ }" x: x+ ]; X
- 97 * LOCAL FUNCTION PROTOTYPES
; Q0 c- b/ D2 @! F6 ? - 98 *********************************************************************************************************4 _. o. r3 m. Q4 r
- 99 */& f* o1 j! a4 i/ a6 z* \# }) [
- 100 void dsp_asm_powerMag(void);
4 F* H; m6 \$ O/ b2 T6 } - 101
+ W& [1 R! A1 L$ a- A - 102 /*- k+ U9 p/ |* [ B7 h% M
- 103 *********************************************************************************************************
- L3 R9 b- ^/ \ C+ W9 f - 104 * LOCAL CONFIGURATION ERRORS
6 r3 D4 \( y1 z) t, i' d! z - 105 *********************************************************************************************************2 f% ?+ Z# ^, {9 g1 H8 Z; a
- 106 */
& K. `7 M0 Z m1 C5 M. K - 107 % r5 N5 x* y" A% p h! V% k! \
- 108
2 s3 a9 }! U* K4 \ - 109 /*2 }" |& {6 M" E* F. s* t
- 110 ******************************************************************************************************************************
. E% Y# p! L- c$ L4 {& h3 E - 111 ******************************************************************************************************************************
9 G2 I3 F# w, P: R' |: ^3 Q0 I - 112 ** Global Functions/ Q( g! H1 O! K
- 113 ******************************************************************************************************************************1 \, b3 V1 O2 ^* R/ q \2 f/ P
- 114 ******************************************************************************************************************************" z# z' H4 F& a1 H( w; y
- 115 */
) Q, S T9 N# { - 116 ; |! V: x& w ~/ s7 L- g' w
- 117 void dsp_asm_init()
6 X5 G1 B3 [/ {$ d - 118 {
|# U. t) T* \* k5 l - 119 u16 i=0;0 C9 b1 U5 i) Z: z9 C
- 120 float fx;5 x I3 S9 b, Y/ \# z G) G
- 121 for(i=0;i<NPT;i++)2 H( S. ]( a! P, l
- 122 {4 x2 O0 s6 [5 d- x5 }/ H
- 123 fx = 4000 * sin(PI2*i*50.0/Fs) + 4000 * sin(PI2*i*2500.0/Fs) + 4000*sin(PI2*i*2550.0/Fs);
3 t% a* S7 A7 Q4 D: E" B3 Q - 124 lBUFIN[i] = ((long)fx)<<16;
+ p" ]& T9 T( L* x7 @7 ~3 O" h - 125 }0 ^9 r' P: A8 D8 n+ L0 r- A
- 126 }% N5 g, S. `8 I" }
- 127 ; v' q! c' h- B- z! H' ~6 ^3 `' [
- 128 void dsp_asm_test() ; D+ z) B& o" |9 F0 O+ I, N
- 129 {
' v& q5 ]. o7 i- {3 G& f0 } - 130 9 j6 p; Z0 |1 O% S" V
- 131 #ifdef NPT_64# F. F: J7 o( [, ~
- 132 cr4_fft_64_stm32(lBUFOUT, lBUFIN, NPT);( H2 O9 v& @9 v% u
- 133 #endif8 y# x0 v/ a& s5 z
- 134 5 e7 d6 J' J' e- J* U7 g
- 135 #ifdef NPT_2568 s, R8 y6 |3 \) q4 n
- 136 cr4_fft_256_stm32(lBUFOUT, lBUFIN, NPT);
/ \# Q; p8 S" B* ]* J- Y9 e - 137 #endif
Z3 ]" c" y5 M6 N4 N% \# ], u - 138 4 V5 c( @3 C6 R
- 139 #ifdef NPT_1024
& \$ e7 }0 i3 z" o* v, n" \% x - 140 cr4_fft_1024_stm32(lBUFOUT, lBUFIN, NPT);; N3 X& e. p: H3 A- l- ]
- 141 #endif0 p8 D& p* i; W7 }* q% O
- 142
% l( K1 B2 ^9 s6 P - 143 // 计算幅值# s# n: {( P8 {$ V' R" d
- 144 dsp_asm_powerMag();1 Y5 ^! s, X1 Q. M6 P
- 145 7 K- D" q! s" V1 V
- 146 }; L2 d8 ?! \. e; Y5 R/ c5 ~+ T% _
- 147
4 T/ a' j) B, r" T$ L - 148 void dsp_asm_powerMag(void)* S- n3 R: U U9 ]. r) _
- 149 {# q8 Z" `- M1 T' L
- 150 s16 lX,lY;# @2 k( V) l% R3 J- \
- 151 u32 i;
! M1 N; F( N2 `6 y' F W - 152 for(i=0;i<NPT/2;i++)
7 K8 q/ x! A7 q' V: K4 x# E x# C - 153 {
, _# j! h& y# r - 154 lX = (lBUFOUT[i] << 16) >> 16;& d# N: m/ C2 y" Y) d' y
- 155 lY = (lBUFOUT[i] >> 16);
! ?0 k% C; X9 n) o8 T# H - 156 {
, u6 e3 U' ^8 V+ O - 157 float X = NPT * ((float)lX) /32768;
6 w5 a" b6 i/ W1 o - 158 float Y = NPT * ((float)lY) /32768;
5 u2 i9 v6 |; Z" Q - 159 float Mag = sqrt(X*X + Y*Y)/NPT;
% J' B, {6 p- \0 j% X- C* O7 ^ - 160 lBUFMAG[i] = (u32)(Mag * 65536);7 R: F! e! E6 `
- 161 }
: j8 \( ?5 p3 N! F; Z - 162 }
1 B% F+ R5 K* e) S" H - 163 }
复制代码- 1 /*+ m T0 ^9 ~' |
- 2 *********************************************************************************************************# p2 P1 D5 `' R, z( Y: D+ J; q! L( g
- 3 * MICIRUM BOARD SUPPORT PACKAGE! D$ s; F9 I: A7 @/ j6 o
- 4 *$ R! x1 M+ m0 [7 {* L8 G% b
- 5 * (c) Copyright 2007; Micrium, Inc.; Weston, FL3 H9 w" M2 T& c
- 6 *6 p) u0 j0 h& h' `7 T* d8 w$ [
- 7 * All rights reserved. Protected by international copyright laws.
8 m# m# C1 N+ k' M - 8 * Knowledge of the source code may NOT be used to develop a similar product.. b; |* J7 |* b% M+ b
- 9 * Please help us continue to provide the Embedded community with the finest% h- v/ H: E7 B, V4 c
- 10 * software available. Your honesty is greatly appreciated.% F2 c, ^ @/ [
- 11 *********************************************************************************************************
" v/ v$ I+ p# S# N - 12 */8 c0 Q9 ]/ ~9 F6 y4 U
- 13 " \9 i4 ^. }4 X$ D& A- E" u- D* c
- 14 /*
: E" P* k8 k/ j" I - 15 ********************************************************************************************************* h3 v3 b, G) F# \" i: Y9 c& c
- 16 *
6 Z" X' Q2 H" m- S+ d5 Q - 17 * BOARD SUPPORT PACKAGE
- y7 Q+ C6 L7 f1 D2 Z5 @+ x5 a J$ f - 18 *
# j4 T1 o( I* T' N# t+ b+ N+ L; | - 19 * ST Microelectronics STM32
9 r. K5 t- t6 b% g) G - 20 * with the
2 A1 r# `$ v, J8 O7 R - 21 * STM3210B-EVAL Evaluation Board$ T/ d: j0 @4 j+ O: E. C
- 22 *
5 E8 ~$ V* z( B7 N) R0 T7 ? - 23 * Filename : bsp.h& L$ G$ ~4 D/ e; G; c% W% P- J3 H4 X, U
- 24 * Version : V1.00, Z! |; c5 W8 V% w( t) p
- 25 * Programmer(s) : Brian Nagel
9 H- }; ?8 X6 n0 Y, J4 T- m - 26 *********************************************************************************************************
$ @9 d8 h7 v# j - 27 */
& X" \8 l/ l" P% v9 L - 28
% }+ O+ t/ D! x: M$ e& v - 29 #ifndef __DSP_ASM_H__1 Q# S6 j+ {0 s, f3 i4 e8 d/ Q) S
- 30 #define __DSP_ASM_H__
& F- v' N/ ^ n5 f7 V - 31 $ R) j" A7 M9 N, S$ i% _
- 32 /*
. }: _% r4 Z/ I$ h' r! A. h - 33 *********************************************************************************************************0 H" Z8 j9 v3 P7 {, ]
- 34 * EXTERNS" `/ } ^. i) ^+ \
- 35 *********************************************************************************************************
/ t+ o% M" n# Y2 { j - 36 */
/ U6 J& g" Q6 V, d# w! K+ ~4 C - 37
' _! N3 \& C; E4 @' c( l - 38 #ifdef DSP_ASM; [9 H3 r3 h' L& d, z
- 39 #define DSP_EXT0 i+ A( Z6 e7 }7 L
- 40 #else/ N+ B( B6 m0 d- R4 x9 G% |3 D6 B' {
- 41 #define DSP_EXT extern
- O( F* h# F7 W% t - 42 #endif
4 O6 [/ ]" u9 I- o - 43
: S K: J u. n/ L - 44 /** e* m/ R' D) W
- 45 *********************************************************************************************************
X1 @3 K ~: S3 Q - 46 * INCLUDE FILES1 ~1 j) l: z( _
- 47 *********************************************************************************************************
% x" ]# H8 v1 i8 b - 48 */' J1 j* k( M) ^0 Z7 z2 V
- 49
7 l9 A9 V: }1 ~" T - 50
+ R; V* V0 @* R* v, O4 Z) y - 51
+ M$ O5 a. u& x% w - 52
( @' q7 M# ~) P# n6 g6 U - 53 /*% j1 v) ?( r# i) Y' M! R
- 54 *********************************************************************************************************2 |8 s* V' p% [4 ^/ V3 X+ u1 w' P
- 55 * GLOBAL VARIABLES0 A' w+ W& V' U! l }0 R0 j
- 56 *********************************************************************************************************: N, E% S* H; \2 w# t
- 57 */$ T/ C/ Z" P2 c, l) y6 ]# \6 ~
- 58
8 f6 |' ~& m" n7 T2 s - 59 & }+ P& D3 z' ~: C- k
- 60 /*5 T P8 `8 |+ t. I3 G7 s$ V0 f
- 61 *********************************************************************************************************. p$ y+ h2 l v+ Q8 d e
- 62 * MACRO'S9 H. ~$ T( L5 }- ~+ l6 o* i/ K4 o
- 63 *********************************************************************************************************1 O1 ~, t$ \5 z. f& l' U# E$ \
- 64 */
- e% `- D9 C( Y5 j- N - 65 ' f7 b8 w- j2 |0 e+ N
- 66
! |% v$ E2 m9 S1 N3 L1 k - 67 /*1 R4 V q0 P: @2 l! u, X
- 68 *********************************************************************************************************
( |$ X+ E, t' F0 R( B0 v - 69 * FUNCTION PROTOTYPES
# x% h. N4 A2 W, w4 m; t9 n9 ]4 ^ - 70 *********************************************************************************************************
, @# q4 _8 C. X - 71 */
6 v! ` Y& v' @' w% V - 72 5 }" _/ F( }3 f- ^# ~
- 73 void dsp_asm_test(void);( w' `4 \7 K* g; X
- 74 void dsp_asm_init(void);- N& t* ?- s f
- 75
# \/ q7 `% K' g$ K/ J - 76 #endif /* End of module include. */
复制代码
6 x6 W& B7 U. q 着重分析下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位数据。下面的两句
# `) d$ N% f! M, m! u- u; {/ [ float X = NPT * ((float)lX) /32768;
9 y% u( r; }; G( q; O float Y = NPT * ((float)lY) /32768
& t$ B, x) J8 p! d 目的就是把数据浮点化,至于为什么是除以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次方。然后才能进行其他的运算。' Y6 `/ {4 c+ w( G& v% k G, \
这里是ST公司采用了DSP专用芯片(主要是指TI)的写法,也就是说尽管DSP的芯片类型很多,数据变量的定义也各有差异,但原理是一样的,最终还是要采用DSP习惯的运算方式。至于为什么一定要采用浮点运算,因为机器是傻子,然而TI公司的工程师是天才。 main函数中我们只需在while(1)前加上dsp_asm_init(); dsp_asm_test();即可。
9 }: z2 C1 @. g# L( s9 G9 N0 R4 {3 d2,实验现象 注意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$ B( u6 `2 W7 i$ ?! ~+ Z9 X
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谐波幅值 . N' z& ?* O h
总结:该工程中模拟信号源为: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。 c' c- U# v+ J4 N! ~/ B% x7 F/ l
|