最近在做一个采集卡的东西,需要采集电压电流,用STM32做主控芯片,考虑到还得驱动其他器件,所以就不能用中断的方式采集,于是有了下面的方法: TIM输出PWM触发ADC, 进行周期性采集,采集数据通过DMA传输至内存,保存64点后,产生一个中断表示采集完成,进行一次FFT变换,得到基波幅值。这样只在采集开始设置一下,然后采集结束后处理,处理过程中又可以进行下一次采集,效率很高。- /******************** (C) COPYRIGHT 2012 WildFire Team **************************
) \) e4 {1 O( ^$ r; Z' I. T - 2015.1.1# |5 g( |. U3 H) [3 O. B
- 1.TIM2 PWM触发ADC1采集,3200hz,采集完成后数据DMA存到内存,一次64点,采集64点完成产生DMA中断% R; a( {; z: M4 f+ A; c. o
- , @) H1 v- v# j1 R! U2 u
- 2.用ST公司自带库进行64点FFT运算,测试OK
0 d) X5 h( S. c- W0 [ - V* `& h, ~9 w9 p
1 B' O# k' m4 r: {5 l, J- **********************************************************************************/' r1 I* V1 w+ k! I3 p4 @
- #include "stm32f10x.h"+ U, s* l- _; t1 a8 ? w! F
- #include "led.h"
8 Y/ o9 {/ i/ {# o - #include "sys.h"
- ] J0 `0 X# j1 O0 W( B$ B - #include "SysTickDelay.h"" ]- _: W8 X5 h4 ~4 q3 x
- #include <math.h>5 P3 D1 Z9 h( X/ w# m
- #include <stdio.h>
0 @% Y& k; r5 N* {- J - #include "stm32_dsp.h"/ M4 m5 B! H) Z7 H( u ]0 }
- #include "table_fft.h"6 L. _, O( b8 t r5 c/ U
5 F" x' J* N/ Z' _
N9 f; a6 p! J2 d- //#define MI_ERR (-2)
3 \) M# S6 _% Y
4 S) \- A; ~6 i2 T8 u- #define PI2 6.283185307179594 d0 V2 p2 R5 J/ x
- #define NPT 64 /* NPT = No of FFT point*/8 {( }- f9 s* Z7 s& e3 ^/ k2 \8 ~
- #define Fs 3200
0 a) G L6 _7 W% w% v
4 p4 T" I6 ^4 \8 }- \4 ]0 Y
/ z& I2 E6 I+ j8 V$ D- #define ADC1_DR_Address ((u32)0x40012400+0x4c)
, \# |' B6 _! e/ e- `& x$ Z
1 |, w D1 z7 z# u! b# P0 ], g7 h- void led_init(void);
" D4 B2 \$ F+ Q, f - void Adc_GPIO_Init(void);/ B. F7 M# L8 B7 |2 p+ c: O
- void Adc_single_Init(void);8 E. X. V4 W g% y+ f$ f2 J& `! J
- void ADC1_DMA_Init(void);* z" s8 Q" n3 e* @0 l! A8 c' ?
- void TIM2_NVIC_Config_1s(void);
# B- ?) C) M# k+ g1 i# c - void TIM2_Config_1s(void);$ Q ?4 n4 p' X4 B& O$ m3 X! ?
- void TIM2_Configration(void);
# I2 z* d+ I6 I5 Z# r
) o; Z. T5 [: E. b: Q7 z! [- void dsp_asm_init(void);* }; O* U6 w9 E: T9 {: J0 L& C5 L) Q
- void dsp_test(void);
( I4 u; f/ ?. w: v1 J, r+ C - void dsp_asm_powerMag(void);! U8 f2 s4 P% ]) I& M
! K. Y+ A) [+ ^: L
# O4 t4 B0 y) |& s- 5 F$ b9 E7 X, F3 `+ G5 b/ Y
- long lBUFIN[NPT]; /* Complex input vector */
3 p2 _5 e( R- \/ V$ Q - long lBUFOUT[NPT]; /* Complex output vector */' f7 a+ |/ ^% d
- long lBUFMAG[NPT + NPT/2];/* Magnitude vector */. E, H* F, R' ?4 }: `' l6 S/ w
- long lBUFMAG_base;
3 V9 B- V' [9 [+ S) ]+ r - float average = 0.0;5 G0 z' J9 q: W: e% R0 U
- / y1 I% P& x# F2 x6 W( u+ R
- float voltage = 0.0;
* @" E0 a* Z7 X# ^( c `8 F1 d; P - extern uint16_t TableFFT[];% s k0 G' J3 M } f
' {, Q0 L. ]9 `( {; ~. F- 5 H. _& x% y v- v1 W' g) @! p
- __IO uint16_t ADCConvertedValue[64];
! t5 m, q5 d4 {" h d - ! A' Y- ~% O* b& C
- uint8_t DMA_FLAG = 0;
9 w3 z- A& C/ }% P - uint8_t led_flag = 0;( [6 m, w; p4 U3 c
- int main(void)0 c3 Z8 A1 J' Q! P( v9 V
- {
9 P: `; {8 `6 r$ h0 F1 W - led_init();//pc 3 4 5
; p; q# m, ?8 B }) K4 A -
4 I- J' R4 @4 \ - SysTick_Initaize();
( B" I: }5 Q6 }% h -
( m+ u" c1 O6 M& V, o( e5 M - Adc_GPIO_Init();//pc2
# E8 M6 i3 S; z3 \, _5 ^ - Adc_single_Init();
% K, \- y3 e7 t% r; G& { @ - ADC1_DMA_Init();
3 h) s. f2 l! q0 i, e' n# P: Y -
0 I+ D' P8 Q1 m. G0 `/ ?# o - TIM2_Configration();* Z, H' X- K, @$ A
, ~* A& E, r' A- 6 i, N; f C9 h6 b/ P2 e
- while(1)
$ Z$ S% Z/ a6 b3 S# p' ^' e - { , O9 [+ J2 h7 W( u
- led0 = 0;: H. h! l9 T9 I5 p- P$ w d- ^
- led0 = 1;
2 T f- M& f# p - while(1)6 O" N4 `1 u( ~( a3 X4 j3 F2 |! R
- {* @2 U' s; `; {
- while(DMA_FLAG == 0);' b* K" H4 E. f. i7 [
- dsp_asm_init();
, e9 I4 R7 N! S' R/ @ - dsp_test();+ D( i9 G6 y# i, G
- }
' |6 d5 W% V1 F L4 v, {/ g3 t/ l) q - 2 D6 K( T, C* Q* G
- }
9 H! R+ @& G; z% ]# G. J - }+ q; w3 L7 [* c$ C$ b7 J
6 g7 Q5 Q/ ~% o( v% |4 P. Q/ ~' e
5 n* a0 O, b5 d. Y. N. Y ?- " p: r" N% N+ b) Y, {/ p8 C
$ V+ B& F8 l# j9 m9 |- % o: J3 i) [0 p
: t: Q8 W0 Z; P1 D) G: m$ a: P5 v- $ V- p( z* u$ `$ S) J1 _
- 6 ]0 B" ^3 r. A" X r. S+ c
- * d* _/ `5 x1 {' [' q: s
& r! ^5 z: ]6 M) g0 y% k
' t$ }+ Z9 {' \& f2 q- void led_init(void), E! W! ?& E* P* }( r5 K
- {
- F# Q+ |. x, U- t - /*定义一个GPIO_InitTypeDef类型的结构体*/; L0 t* u u" ^5 M& V- U
- GPIO_InitTypeDef GPIO_InitStructure;
; g1 j4 h3 c z h% B1 ~ - 6 r9 T5 T* H7 v: i
- /*开启GPIOC的外设时钟*/- Q' N/ h! X7 N: a: z( Q$ X$ t
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE); 6 Z; \& t9 h$ N* |! X5 {- M
- . ]3 E: E6 {, O- e0 g5 b' l* z
- /*选择要控制的GPIOC引脚*/
) q/ J. ~( W4 r) d- u7 o - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5; * ]% D+ n- y( G0 j/ q. Y
- * o: |# A! f: C+ g1 b" x
- /*设置引脚模式为通用推挽输出*/4 e9 `) O7 B, X$ M
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; ( J" z+ m' s4 k" I3 ?( ^' k
- 8 V' U) N# S0 i# g, x& U$ x* l" ^
- /*设置引脚速率为50MHz */
! t1 i; |1 w3 X5 `# j" T% ?! H! }, P - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; & | g7 s' A4 _% {" H/ d
- ; W2 q6 K$ j) A( c# @9 n# r
- /*调用库函数,初始化GPIOC*/& v2 L7 x+ [/ H+ v+ s: t2 f9 n8 r
- GPIO_Init(GPIOC, &GPIO_InitStructure); & J; X! o0 ]. C4 f" z7 L
- . O1 k6 y/ v2 a
- /* 关闭所有led灯 */
" N2 j% Y+ o. a- a1 v& F4 z7 K - GPIO_SetBits(GPIOC, GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5);
/ K5 i4 }/ p" e# }" S# V) h - }
. Z% \1 G1 s1 F' H
, A" a8 F2 k) v; Q @! r* }- void Adc_GPIO_Init(void)' m6 X8 z6 u; n8 _" }1 L
- {- U' ?6 A/ p' l" [
- GPIO_InitTypeDef GPIO_InitStructure;
1 w' _# J K6 v. S+ I: I2 m# f - ( H; V* u% U( u9 t4 [$ `2 A
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE);
; W# T2 b" w/ m' C. S% O - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
2 v/ a. a% B0 P) d" h) }* K( \& h - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;+ Q' d% o9 G8 {! i# G, ?% B: K1 l
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
5 M; C% {- G1 R* P( k# A m( e1 J - GPIO_Init(GPIOC, &GPIO_InitStructure);
5 p7 m4 H- @6 Y O; M - }* r( Y" h D f8 ]7 G G# h/ P
- 2 q: r4 P( q# i) D Z% a
- void Adc_single_Init(void)
' D$ v8 A9 r `4 X - {
2 U" }- A0 w' B/ K( ` - ADC_InitTypeDef ADC_InitStructure;
9 _& k1 T. C! k- J - 2 b8 E# @2 t, _% I# A) w
- ADC_DeInit(ADC1);
! s5 Z! b! I" n$ c* B -
$ Q# r. G$ H# v& i' [! F - RCC_APB2PeriphClockCmd( RCC_APB2Periph_ADC1, ENABLE); + _( s9 k3 g7 K; c; l; C; D
- RCC_ADCCLKConfig(RCC_PCLK2_Div6);//设置ADC时钟(ADCCLK) 72MHZ/6 = 12MHZ9 F; P: p/ B7 c2 Z1 m* B* K2 h5 G
- + l" f! d j4 D0 e
- ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
6 G# I' M' L5 O - ADC_InitStructure.ADC_ScanConvMode = DISABLE;//单次模式(单通道)" g" N, d% D( m2 H: {+ p) d
- ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//连续模式3 H' y+ v7 J5 J; U' p. `( T' g
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2;//转换由TIM2 CC2 trig% }" p, R: C0 d4 S+ e
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//ADC数据右对齐
2 @" J" |+ {- L* |; ~4 f0 `# B" b - ADC_InitStructure.ADC_NbrOfChannel = 1;//规则转换的ADC的通道数目,取值范围为1-16# {% q# Y: U D) M j
- ADC_Init(ADC1,&ADC_InitStructure);//初始化配置
* |1 X$ E2 G; h1 k# R% c) E" a -
1 \1 R6 l/ M, O6 }. u& l' \. s - # ]. ] d9 J! f4 |8 f
-
. p4 ~. Z( R- \0 c8 n5 y5 } - ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_7Cycles5);1 G+ {5 [3 Q7 g" s* Z
-
- w$ A S$ @0 A2 W( {. `/ W - & h5 K2 u% D+ A
- ADC_DMACmd(ADC1, ENABLE);//enable DMA
4 B7 S! u+ z1 t N" L
$ e& w: o; D9 } _2 v: V+ l9 z# [& t- ADC_Cmd(ADC1,ENABLE);// enable adc4 ^! n4 Q ^5 d2 u B
- 0 U* ~7 Q d: V- I
- ADC_ResetCalibration(ADC1);8 _* g; L+ |' p! n% N4 p: Y3 a
- while( ADC_GetResetCalibrationStatus(ADC1));//获取ADC重置校准寄存器的状态 等待复位结束8 P- X0 \0 A: X, D0 P( i7 ~
- ADC_StartCalibration(ADC1);//开始指定ADC的校准状态$ A* l z! l3 H" m2 b; S
- while( ADC_GetCalibrationStatus(ADC1) );
, C: d) F [" e8 d5 `+ r+ Q% P -
5 j+ B6 F$ J9 K, b; u - ADC_ExternalTrigConvCmd(ADC1,ENABLE);
@, q3 M; Q% _2 P' U. I' z - : m4 L2 e/ `: u
- - D# X! k$ A) T
- 8 B% ~$ s4 H8 P+ M; K
- }
7 E4 L* L3 [( W - 2 T& W+ H6 K3 y* {
- void ADC1_DMA_Init(void)
3 f+ M3 b5 ^ T: l - {! ]( K* {: ^- _3 N
- DMA_InitTypeDef DMA_InitStructure;
% f/ C+ c1 T; C) e - NVIC_InitTypeDef NVIC_InitStructure;
' H: T+ p" S9 w - % `) q; l9 I8 ?) |
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
$ e3 G( `9 _% k3 R# |) _
1 T/ L: B6 n* J- O$ A- //ADC1 DMA channel 1
5 u! [( R% v$ k' B* o - DMA_DeInit(DMA1_Channel1);
+ X% z1 V% `0 J- ^" [ - DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;7 Y7 Q/ G0 q6 x7 {7 {
- DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue;, p, k- ]4 x8 H1 O* J9 f8 a
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
% F1 W, y: v9 f' e5 T' B& r - DMA_InitStructure.DMA_BufferSize = 64;
) Z$ r. r2 O+ q1 E - DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
0 P5 m8 P3 J9 S - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;// 内存自增6 G3 q, [6 y" B5 c: V
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//16位0 `# A5 l9 I* z" l3 O1 R
- DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//16位
! Y+ l; P+ ]1 ]) k. h" V+ |! B' q - DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//DMA normal
C0 s9 Z- |& G6 [) ` - DMA_InitStructure.DMA_Priority = DMA_Priority_High;$ O! j9 C" |% a) r( f4 i( z% R) F5 u
- DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;* n9 M( C' A8 u$ n9 V
- DMA_Init(DMA1_Channel1, &DMA_InitStructure);. A1 P( s" F4 p. q9 V
-
- x8 `1 x7 V% s4 x4 ?. i0 A9 L$ k. X) d8 r - NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
- B9 Q8 b! a0 k' A o. r( f4 {$ X - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 主优先级为0# p1 s% G8 V1 x k" m7 x
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 次优先级为07 P, C7 b J3 e6 X% M
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;5 |7 O, E7 Z$ Y. B, u l; k
- NVIC_Init(&NVIC_InitStructure);
- G/ o, I$ D3 `) p) M, B6 r7 _ - . Y3 c$ G' J& K
- DMA_ITConfig(DMA1_Channel1,DMA_IT_TC, ENABLE);//使能或者失能指定的通道x中断(DMA1 通道1)
9 D$ F4 b5 F7 \ d; @( a
! \3 A1 f) Q, @( V' `4 n- " e/ h- e/ P4 y: c& d R: K
- /* Enable DMA1 channel1 */
2 o& P+ N; h/ ?/ \ - DMA_Cmd(DMA1_Channel1, ENABLE);
+ J5 o( y! L0 d. T - % f9 o0 F" k7 {/ ?& r2 l8 X5 U
- }8 X/ ~" o# z0 q
0 @- s4 ]' M# b" k4 ]( p6 m- void TIM2_NVIC_Config_1s(void)* d2 a6 v% B( K& u: Y! E$ I
- {2 u+ r* ]9 k0 d/ i2 v! ]# f; Q
- NVIC_InitTypeDef NVIC_InitStructure; 2 k* M% C& v/ U( N" i% R r, R: N4 b
- 5 {/ c, B! [. ^7 l) p: O6 S' }: h/ t
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
- S! n9 ]$ a/ P; v( H - NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
5 a% I) m+ m2 a; k3 i' e - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
w" ?* }7 y2 Y) ~% m- v: Z# l - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; / ~+ W4 J3 r0 h ?/ _
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;( Y/ Q3 P/ C2 \* P4 t
- NVIC_Init(&NVIC_InitStructure);
8 Q! M2 ?' G; F% g$ _& N - }
- T7 j. t" v: K. V - : C. _# [/ \3 X9 k9 h
- void TIM2_Config_1s(void)2 D5 |2 `: _- Z7 }, a
- {
0 `. M: l% g% L4 n d - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
# @6 `. C! w; P5 f - RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);4 @: E1 V d3 ~
- TIM_DeInit(TIM2);
1 a B. { G! k0 l( o) j - TIM_TimeBaseStructure.TIM_Period=10000; /* 自动重装载寄存器周期的值(计数值) */: m3 K1 j/ U! r
- /* 累计 TIM_Period个频率后产生一个更新或者中断 */# j$ h0 t$ |/ n
- TIM_TimeBaseStructure.TIM_Prescaler= (7200 - 1); /* 时钟预分频数 72M/72 */1 T6 ]# @; l" ?( M
- TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; /* 采样分频 */
( D: ?0 h' s5 E7 p( u - TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; /* 向上计数模式 */
9 k) b8 t( a' _ v k. @8 u - TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); @- H2 l R- [5 y5 o, ^+ e! q
- ) @6 H9 i. @3 |
- TIM_ClearFlag(TIM2, TIM_FLAG_Update); /* 清除溢出中断标志 */
7 x; \+ l, H/ C( c$ T- j - TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
1 U: |! _# T6 O& D) A6 V - TIM_Cmd(TIM2, ENABLE); /* 开启时钟 */2 O9 U, U+ e9 I& v+ t' Q2 l- h
- " n. Z' O8 R. _ N* R
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE); /*先关闭等待使用*/
- ~# Z. z1 { s - }* t3 I3 \9 p& Y, {
8 @8 y4 y% U/ w& k' s- void TIM2_Configration(void)
. P- v6 E7 F6 X" C - {
6 K" W" r7 t2 w6 e& [0 N - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
; Q$ O4 E* l# Z; Z w; N0 ]" J - TIM_OCInitTypeDef TIM_OCInitStructure;6 S6 y# b" f9 H2 n' T( a( E3 z
- //TIM_DeInit(TIM2);. L5 p/ y# I. _% a; G2 o0 h
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);
- i" B; J& \# p - 1 m; ?$ s, L/ X: | E3 c
- TIM_TimeBaseStructure.TIM_Period=100; /* 自动重装载寄存器周期的值(计数值) */
8 q0 f7 J& A e" E$ \ - /* 累计 TIM_Period个频率后产生一个更新或者中断 */$ |) W! R! U0 I9 c+ l9 g6 v
- TIM_TimeBaseStructure.TIM_Prescaler= (225 - 1); // 时钟预分频数 72000000/3200 = 22500 = 225 * 100
2 p0 w) W$ n% g* |+ A - TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; /* 采样分频 */# j) ~7 Y8 \1 x. [1 b, b& I/ ]) `
- TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; /* 向上计数模式 */
+ W. E9 ~; Q2 ^! @4 O; X/ X) F; {( N - TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
* H8 Y( Q9 x5 I" t5 C - TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
& z T+ \4 ?2 S( u1 D7 o% e ^ -
/ ~* X7 g6 A5 R: _4 d - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//PWM模式1
0 ~, I( [ F' ^& E" U6 n8 C- _ - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//使能
/ c# i2 @8 ~! {/ Z# m; X9 c4 E - ( c7 U4 j% k4 X! e
- TIM_OCInitStructure.TIM_Pulse = 50;//脉冲宽度,由这个设置占空比) ]" A, C1 G" r# o$ |# U
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;//LOW电平有效9 M4 k, h K; G4 y4 w6 p5 G& |
. D9 U1 b3 }- Y; ]- TIM_OC2Init(TIM2,&TIM_OCInitStructure);//初始化
( @% J6 U+ r. Z( J# `' p/ ] - . i3 x, q* S( D6 K* r
- TIM_Cmd(TIM2,ENABLE);
) [ Z9 ^& X- N( d7 x+ v - ; X, H3 p8 l/ f# Z' Z
- TIM_InternalClockConfig(TIM2);
9 @& E1 p: ?( z# v6 |. D - TIM_OC2PreloadConfig(TIM2,TIM_OCPreload_Enable);, ^; @2 Y7 u* E7 M5 k. |
- TIM_UpdateDisableConfig(TIM2,DISABLE);
, T0 B5 q- `1 @% v0 l -
( O3 D4 F" L% E/ j4 x5 d( o. N -
, e0 q1 U' f! g0 t - }
# T8 E# ^1 m) d0 V) k5 K - . j9 X' s" L9 m; c
- void dsp_asm_init(void)
( p% G* `: r* ^: ?6 _! {8 O; P - {
, s& [# p+ K9 W. \% [4 s6 x - uint16_t i = 0;
8 N$ c3 b* z3 O - //float fx;. R3 o- w$ ^6 K4 d- M# ? Z
- for( i = 0;i<NPT;i++ )$ T1 C. v+ r. O
- {
* @& M! q$ b' s - //fx = 4000 * sin(PI2*i*50.0/Fs ) + 4000*sin(PI2*i*2500.0/Fs) + 4000*sin(PI2*i*2550.0/Fs);
4 l% J. f/ q7 C3 R, H* b - average = average + ADCConvertedValue[i];
" s, X3 Y( r0 I. H6 f9 n. {8 B - }( B* T' W- V; } S( _( j- _# D
- average = average / NPT;
. l/ l: d0 J1 h. O/ c+ } - 9 _& y, j2 l1 p6 A
- for( i = 0;i<NPT;i++ )
4 i6 x+ s9 x% W. ?* v - {
& H- z( A( a! \1 i) l% \2 G0 w1 a - lBUFIN[i] = ((int16_t)(ADCConvertedValue[i] - average)) << 16;
1 z8 V2 ^9 s; v6 \& _$ p4 ] - }3 U- ^! X3 G4 Y c$ [) W9 \8 B
- 2 ^; G' D) R& W
- }9 n# L' g5 a' U$ V0 a1 r
- 6 {9 e$ t: D- I4 t% f* ?
- void dsp_test(void)% O6 [* E6 q' R
- {
/ x' `& N2 A. ^3 a6 Y - cr4_fft_64_stm32(lBUFOUT, lBUFIN, NPT);
" P4 c# W& ^1 W - dsp_asm_powerMag();
2 r* W! A; L0 ^& ^& o1 F9 h - }
/ L7 I$ Z q: t# E9 q - l* p6 q9 [. r& x- r) {
, m' E2 l5 A( _# W& E: f- // int main(void) S/ T- z+ b1 N
- // {
6 d/ c, F3 n7 l) q - // dsp_asm_init();7 n/ h+ N+ [" Y/ Q
- // dsp_test();
+ E% K2 j7 u$ N, c- B, b - // dsp_test();
5 J+ ~5 `) B$ s5 Z: C, K - // } Y' G, B6 q T& Y1 N+ x
- 7 A6 z% S3 I$ U A
+ |3 p/ i0 V q+ P- . n, p9 h- V' X5 W; |8 N: \3 L3 w
- void dsp_asm_powerMag(void)# Z; o5 P: N& s- n- Z' y8 b
- {0 G; @* b$ V4 j! l* R. m+ w
- int16_t lX,lY;0 _7 V" u+ V8 x: X
- uint32_t i;6 p4 V) `7 L; W* y6 U) _) s
- float X =0.0;) i' s# H- q* P7 l- {! e/ p* {
- float Y =0.0;: v; l7 c: s. y9 I( F' O& k9 d
- float Mag = 0.0;$ P8 N1 |9 J; I7 v& h- A& u
- for(i=0;i<NPT/2;i++)% x% |3 X* N5 a8 n- t/ g) h
- {
r( ? U3 M, l: e( z - lX = ( lBUFOUT[i] << 16 ) >> 16;4 _) V2 ]2 |% x0 I h
- lY = ( lBUFOUT[i] >> 16 );4 L# m- V! ?( |, u g) { I( I: p8 }
- {3 e; R8 R# {8 |$ f5 Z9 u5 c
- X = NPT * ((float)lX) / 32768;/ [! Z) v! k D* k8 d- z6 A
- Y = NPT * ((float)lY) / 32768;
% `2 s6 t7 }; G. R - Mag = sqrt ( X*X + Y*Y)/NPT;9 p$ ]) D9 |- F, T. A/ c3 Z
- lBUFMAG[i] = (uint32_t)(Mag*65536);
+ N& l9 V! p; R& j# i8 n - }
6 d7 X. h5 M+ H9 i; v% t% M6 @ - }
8 R3 l8 a7 R- l# S. ^" o8 A - voltage = (float)(lBUFMAG[1]) / 4096.0 * 3.3;5 g+ ^% {+ i) k; m; l
-
0 ~+ u/ z" ]: a p - // lX = ( lBUFOUT[1] << 16 ) >> 16;
" t7 z" J6 J8 M - // lY = ( lBUFOUT[1] >> 16 );
0 V3 W% b6 _! F z - // X = NPT * ((float)lX) / 32768;
1 P* M- _" j3 @9 ?- Q - // Y = NPT * ((float)lY) / 32768;+ Z) z' `$ d5 g- ]# o3 C7 K
- // Mag = sqrt ( X*X + Y*Y)/NPT;% q1 F8 H) G8 [7 l
- // lBUFMAG_base = (uint32_t)(Mag*65536); # |& ~2 v& O: M7 `) K2 a0 l
- ; |5 p# C! J: b4 I; u# X
- }) i0 Y' s8 G" Z" H( E* ^- p
复制代码
. h% \" M( V+ ^0 y$ M% Q
! n* h+ W+ s* j+ i! {" J I9 o4 T) w6 o- E0 y4 d
4 O8 w+ k8 f' x: \0 j6 |9 ?, F. K6 b# O/ {/ d
|
是这个意思,即通过TIM2的通道2的比较事件来触发ADC。
是不是 STM32 内部已经与TIM2的CC2 连接起来,触发ADC转换。
6 y5 r* J6 w8 l2 [: W
是这样的吗?
谢谢,不知道效果怎么样!?
谢谢,好好学习