只做了一路,多路的话自己扩展
* _# p/ {/ i$ r2 ~# h4 l3 H. o- #include "adc.h"
/ G0 }3 ?' a3 H9 q4 w% s% l: r e - #include "delay.h" Y6 U2 j) N! ]7 i+ }
- //////////////////////////////////////////////////////////////////////////////////
) x/ N2 q) T$ N$ O r. F5 G - //本程序只供学习使用,未经作者许可,不得用于其它任何用途: e* q1 i% K2 i' K6 h6 P
- //ALIENTEK miniSTM32开发板# u- @9 i7 Z7 s. H, Y
- //ADC 代码
4 u4 M$ f2 ?8 Q - //正点原子@ALIENTEK& w3 O, O4 N! j6 a: c7 B7 A0 C
- //技术论坛:www.openedv.com
2 a" A7 F% b9 u8 ^( R3 y7 q - //修改日期:2012/9/7
3 o0 Z1 U+ P' W5 U# t! X- k - //版本:V1.0, _0 B% l N1 y* ?- ?# D
- //版权所有,盗版必究。" V5 g* S# i& k% z% C( v
- //Copyright(C) 广州市星翼电子科技有限公司 2009-2019
4 ~$ O+ }0 `% r - //All rights reserved
9 g+ h, F. a' ?2 K( M9 G - ////////////////////////////////////////////////////////////////////////////////// + }$ [) k2 G2 @4 C
- 5 D; U. F5 `" }) I) S; r" h
- __IO uint16_t ADC_ConvertedValue;
) \; D1 m9 z a3 }4 X) ~ - //初始化ADC
7 K3 n& z3 _" h- o - //这里我们仅以规则通道为例
# e0 s! L m0 F; I5 y, ? - //我们默认将开启通道0~3 / Z# g- _5 p4 m; [" X" Y2 x
- void Adc_Init(void)) l( {: Q& F2 ^- F( Q
- {
% X. V% u4 Q4 o4 G& {: j+ ~* {, a - ADC_InitTypeDef ADC_InitStructure; ) ~+ C6 t: ?: T0 m: M
- GPIO_InitTypeDef GPIO_InitStructure;
/ w" k* |3 x9 _' D) l/ F: v& p - /*--------------------------DMA部分---------------------------*/
; i& Z( J K. {3 ~- w" P9 i9 F - DMA_InitTypeDef DMA_InitStructure; + R, |6 Y. ^$ \* y7 D
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);// 打开DMA时钟# K, w( Q# X7 |- K( E. W0 Q
- DMA_DeInit(DMA1_Channel1);// 复位DMA控制器, X2 _+ q2 w+ g
- DMA_InitStructure.DMA_PeripheralBaseAddr = ( uint32_t ) ( & ( ADC1->DR ) ); // 配置 DMA 初始化结构体 // 外设基址为:ADC 数据寄存器地址
, D" E) I8 ^' N$ V, |8 \ - DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;// 存储器地址,实际上就是一个内部SRAM的变量7 p8 a2 Z) q u( ?* l5 U: m9 k
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;// 数据源来自外设% o R' \1 v( {- x1 y2 ^
- DMA_InitStructure.DMA_BufferSize = 1;// 缓冲区大小为1,缓冲区的大小应该等于存储器的大小
0 L3 ^( x. A! K - DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;// 外设寄存器只有一个,地址不用递增
& N7 {; r0 d: D! u7 R( A - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; // 存储器地址固定$ ` F& @ P. M$ F7 b
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;// 外设数据大小为半字,即两个字节
; R( z" y( J% ? N6 M( h - DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;// 存储器数据大小也为半字,跟外设数据大小相同& R, e! `3 n* \
- DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 循环传输模式/ I6 L0 b0 }: Y* f! i+ @ f/ |
- DMA_InitStructure.DMA_Priority = DMA_Priority_High;// DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响
& S; U1 g: u; ~ - DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;// 禁止存储器到存储器模式,因为是从外设到存储器2 _, F! C4 C9 d" S' `! O
- DMA_Init(DMA1_Channel1, &DMA_InitStructure);// 初始化DMA+ a* i5 x N5 Q
- DMA_Cmd(DMA1_Channel1 , ENABLE);// 使能 DMA 通道3 O5 \( U( M. G. z
- /*--------------------------DMA结束---------------------------*/; }2 Y4 D3 @3 E
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE ); //使能ADC1通道时钟
5 O; U! l2 @1 L" U9 G - RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M; } P+ d2 X7 ^& D
% K( I/ t1 X( r$ b* o1 Y( z-
# u) k; h5 N2 a5 r1 M" u# } - //PA1 作为模拟通道输入引脚 ) u% n& A0 u+ M, p" R
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
9 K1 o9 O7 x& @5 `5 j - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
5 Y! @) y, [9 y) U8 r( }6 j - GPIO_Init(GPIOA, &GPIO_InitStructure);
/ p: e/ |1 q5 g3 \& h
* [1 E- d( h" B- ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值4 }3 N( H0 l4 B+ Z$ O v
- $ F: Z9 [2 D H& K+ B7 o2 q: b
- ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式4 I* `8 z* Q a' J6 a) I7 t
- ADC_InitStructure.ADC_ScanConvMode =DISABLE ; //模数转换工作在单通道模式- L3 H( {$ O# e, {% s* }
- ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //模数转换工作在单次转换模式7 u/ D* g/ k c1 v1 s
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动" D; i# q8 s% _' e& D
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
: c( o. M: \+ \. r% a - ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目
% [% r2 D, N* K+ m9 ^ - ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器 - z' q8 Y4 z! u# d9 c4 C
- ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5 );
& ]8 h+ ~7 i1 i6 K, q' \ - ADC_DMACmd(ADC1, ENABLE); // 使能ADC DMA 请求
7 M* `5 v! t" K N- B4 _* i7 c -
8 I5 o4 ^5 \3 m# d# F - ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1& N0 P V' N2 K" }+ Z
- ADC_ResetCalibration(ADC1); //使能复位校准 : P n( N S$ s, [$ l; l' V8 r7 e3 n
- while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束; Q" a$ v: _3 ^
- ADC_StartCalibration(ADC1); //开启AD校准* x' @ i. N2 M9 o
- while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
[, }+ C9 \* V+ S+ ?5 w! @. r, O - ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能! o% G+ G& e0 _+ Z
- } / ~1 I3 u0 ^) G7 c
- //获得ADC值
, E. y1 s& w [% A4 T, J, k+ d - //ch:通道值 0~3
( H; H7 k1 W6 x3 T0 r# ~% E; C - u16 Get_Adc(u8 ch)
[- }( q) g+ c( ^6 L0 H- U - {
" N6 s0 E& B( h! [9 G4 @! t3 K+ ? - //设置指定ADC的规则组通道,一个序列,采样时间7 `4 C7 R+ u* O% G
- // ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
$ A' s7 N/ R, r& x$ {. c - //
4 Y) m. [0 f, l# i - // ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
. S X* b$ e( c1 A9 J9 I0 } - //
^. [8 h: R( Z! g1 G+ M3 `' A - // while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
) b" `& m$ `/ j" E
/ q. x9 ^2 U( D7 ~+ A; Z- return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果, m M/ T# g0 a% ~
- }: w4 k- y4 [7 `
- _& {( [( S4 r1 [6 o0 y3 t5 U5 K- u16 Get_Adc_Average(u8 ch,u8 times)
. }* ^& l9 E) p p - {
0 |$ b; {1 A" r+ k: N. v8 G - u32 temp_val=0;
6 T3 p, r# v& e - u8 t;& _5 ~8 I3 _8 [7 z4 e
- for(t=0;t<times;t++)
% ^) R! a$ P9 d. c) U$ g - {
% Z+ G4 q0 j9 `5 v& ` - // temp_val+=Get_Adc(ch);) O7 ?4 z+ N4 g, t: h
- temp_val+=ADC_ConvertedValue;
# \. f) s4 c) w6 Z - delay_ms(5);6 k% Y) f6 Y, D0 S$ C6 {/ }0 ^+ b
- }
; X0 d0 _4 j! _1 [) Q9 H0 e9 g2 S - return temp_val/times;# Y9 @4 y) a* \8 \% v
- }
4 l7 t1 `+ u; `) g, x2 j: B
: k# m+ f: H- A* E" y, s5 w
1 C. }; n3 N, N/ ^: G6 n4 w- - P( }' ?2 N, e* |" `! U5 E
: P0 z0 U1 p* O0 x, n0 C- 2 e) @+ j. h) L/ s% K; u
2 @, v$ B9 @0 u3 e, ?9 v- & W, K6 h5 h+ k6 Y' Z
3 F; j# G+ r! f+ [9 ?' M
, e3 l2 v$ x! \% g: h" u. X
; @3 ?0 o* z- n5 j1 ?% ~) @
$ {+ T$ E; l3 o' N$ i
+ y' P: e! ]$ F- + x. w5 S8 O$ ]3 W
- . X" b2 @1 H0 h& P
- % ^( C4 W% Z6 m, [. \% C
- * Q/ c" X5 _5 i$ ^
- 2 z5 V) o7 ]8 X7 W$ _
1 B$ y* A) ?# {8 _- E. ?- ; |* k; p y" E. I
) j5 B/ r' v# |; i: k
" p- j7 C R3 c8 e0 M, I! ~- * l) i% k: @6 W0 b( e E5 [$ R
7 l F" o* X0 w1 z% l
! I. q/ w' e6 {0 B$ H" C4 ~* n
. T: p& }; R$ @% Y+ U0 W
! k2 l- d" L! s- z% z* M0 c: V! T- & w! f Y {: [
- & Y$ U/ ]! d+ w- S, A, x
- + G4 t4 t' f, Y
* [2 M% s# s' S1 A9 d/ [
- ]) v$ K) J& p* _0 N5 h- ' o* ^1 y4 \: H5 s" `( u; v
- #ifndef __ADC_H
3 a. m0 @% ^. t1 l m - #define __ADC_H / d. q q# p( K) Y4 a
- #include "sys.h"
0 Z3 G6 r0 Z) d; T( l! J+ n - //本程序只供学习使用,未经作者许可,不得用于其它任何用途
) {$ i/ ]$ X1 \% E( W' f$ ^( M - //ALIENTEK战舰STM32开发板$ c! N8 i: s# c2 S. y2 q9 c
- //ADC 代码 T1 M% V5 L* [. v
- //正点原子@ALIENTEK
3 d& K5 M( v( B9 C* q/ d, O - //技术论坛:www.openedv.com( L3 ]/ ^6 y8 k7 l, h3 O
- //修改日期:2012/9/7+ ~4 e% U2 \4 c, l! j, \
- //版本:V1.0( ]! }( X5 F' P% q0 k
- //版权所有,盗版必究。
9 Y) a# Z$ P2 {! ~/ _) ] - //Copyright(C) 广州市星翼电子科技有限公司 2009-2019. D6 w7 q5 ` D3 X3 \
- //All rights reserved
# l3 q7 C4 u2 N; w& F1 Z - ////////////////////////////////////////////////////////////////////////////////// , W! _0 C+ N6 y5 m7 s
- / g! i$ g/ S1 Q. k, |% C% d0 M
- void Adc_Init(void);
' o F+ t) u$ l; V* v9 d - u16 Get_Adc(u8 ch);
0 [* w0 m: k0 M5 b# g - u16 Get_Adc_Average(u8 ch,u8 times); 5 C/ N! V9 W0 s9 a' S
-
, k5 H- k4 c1 G) ]$ s - #endif 1 p9 l" H2 u& x; d: P+ _8 @
复制代码
4 E' u" G% n, d1 M( z5 E- }
) S4 Q7 u( m5 M K |