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