只做了一路,多路的话自己扩展4 X0 p1 s; P8 X, f/ t9 ~
- #include "adc.h"% \( m8 { |- k" _3 A! r
- #include "delay.h". B7 B$ G( o1 ^
- ////////////////////////////////////////////////////////////////////////////////// - Q* U+ x1 ?! w& v6 G9 }6 [ u- O
- //本程序只供学习使用,未经作者许可,不得用于其它任何用途
6 a$ T3 B! {5 Z. m5 n# A; Z9 v - //ALIENTEK miniSTM32开发板$ x& S; c6 S5 w' {" o/ h6 E
- //ADC 代码
/ |: M5 \1 }, ^ - //正点原子@ALIENTEK! l9 X- B, L: G8 l3 L; b
- //技术论坛:www.openedv.com
9 S* R' i" e3 I, ^1 X$ v* { - //修改日期:2012/9/7
0 r) }& j, u& O6 A. y - //版本:V1.02 ?) O- ~3 I6 v2 T& |, o
- //版权所有,盗版必究。
6 T( G, \0 Y% j& f: @ a. N$ B6 Y } - //Copyright(C) 广州市星翼电子科技有限公司 2009-2019! t% ]* A1 U1 b4 n% I
- //All rights reserved
8 Y- u1 C) S* }: Z - ////////////////////////////////////////////////////////////////////////////////// * ^. ?1 R) {! T! Y
- % y4 p% e! f1 n+ w( p: N
- __IO uint16_t ADC_ConvertedValue; B3 G8 j( l9 g+ r: Z# v% L0 x+ J
- //初始化ADC# {' U r. m/ d8 {) S
- //这里我们仅以规则通道为例
" Y; \' T( P7 q& S, i2 H$ i- G! j - //我们默认将开启通道0~3
% V. W3 h- Y9 F9 W4 Z+ g. j - void Adc_Init(void)
; J2 Y5 E, h/ W+ N2 }. H - { % H6 R' S3 N( x( v' y4 ~$ l" i) V
- ADC_InitTypeDef ADC_InitStructure; / y8 f% L; h" h6 p2 H+ r+ }- t
- GPIO_InitTypeDef GPIO_InitStructure;
" E0 T# |2 d- M7 x3 ~3 P - /*--------------------------DMA部分---------------------------*/
$ s* U. O K8 a. z e c# C - DMA_InitTypeDef DMA_InitStructure; . p" ?& ~5 l2 f7 i9 x6 E! N' p
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);// 打开DMA时钟6 w. O+ ], A( L* h$ B5 F
- DMA_DeInit(DMA1_Channel1);// 复位DMA控制器* u+ Z7 l# ]6 q2 J' H6 i
- DMA_InitStructure.DMA_PeripheralBaseAddr = ( uint32_t ) ( & ( ADC1->DR ) ); // 配置 DMA 初始化结构体 // 外设基址为:ADC 数据寄存器地址
: J J- M8 C! A6 S, Z5 A9 S - DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;// 存储器地址,实际上就是一个内部SRAM的变量* O7 }8 i7 x( g
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;// 数据源来自外设' o0 b& n B8 t. r" x
- DMA_InitStructure.DMA_BufferSize = 1;// 缓冲区大小为1,缓冲区的大小应该等于存储器的大小
! H5 i1 Y; I8 E' r - DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;// 外设寄存器只有一个,地址不用递增
& y: ~3 K% p: E# [7 |* r; J, ^ - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; // 存储器地址固定' Q) H8 U! n5 ^7 f
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;// 外设数据大小为半字,即两个字节
, k& d1 }/ h8 y - DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;// 存储器数据大小也为半字,跟外设数据大小相同
6 v& B4 N* t- v+ F6 K6 f - DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 循环传输模式6 R$ u. H* _+ s" M
- DMA_InitStructure.DMA_Priority = DMA_Priority_High;// DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响
0 l( B+ x' r8 A% i5 n$ h1 A - DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;// 禁止存储器到存储器模式,因为是从外设到存储器% o4 h. [0 U0 l9 V
- DMA_Init(DMA1_Channel1, &DMA_InitStructure);// 初始化DMA
' b2 ?' ]$ b {" u - DMA_Cmd(DMA1_Channel1 , ENABLE);// 使能 DMA 通道
6 K5 n' i! F6 G - /*--------------------------DMA结束---------------------------*/
$ c6 s' S- M/ y8 w; g; P - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE ); //使能ADC1通道时钟0 a1 y5 g5 [. Y8 \
- RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M: a9 [# _. E5 |3 j1 G" N( U" i
8 v; p9 b5 O# n4 M0 t-
# o: D2 P! |$ e' ]! i - //PA1 作为模拟通道输入引脚
2 L4 W" j! l/ Q% {5 H( o& n - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;+ S8 V9 `2 B$ l* Q
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
7 q8 N, G5 ?' [. Q% W/ g - GPIO_Init(GPIOA, &GPIO_InitStructure);
7 q# C3 f6 t( T$ B5 @, ~* F+ k, }
! b% x! @: b% l, ^. `" `3 x9 V- ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
! H1 a, p9 T W1 p9 p. _ - + l6 \9 e. a6 O( X: D+ E: s
- ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式: R4 |$ b& T! e- G& I: L
- ADC_InitStructure.ADC_ScanConvMode =DISABLE ; //模数转换工作在单通道模式
+ q, h7 t1 Z v- |- [' y7 f, q5 | - ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //模数转换工作在单次转换模式
2 P- M1 R( @- U: A, j6 A - ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
4 q7 W' h$ }1 c# V0 @2 Z8 R - ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
I& R/ v, x: ]. j0 p - ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目
b4 t" [# w2 e1 v) e; D8 [" z - ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器 ! z1 o, f1 ^, e8 S4 a$ Y3 f
- ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5 ); ^* z( Q9 R5 ^$ U1 l
- ADC_DMACmd(ADC1, ENABLE); // 使能ADC DMA 请求7 K {0 B+ d4 e6 V) y- q4 \
- + t t8 C. }6 j9 \( c, C3 E1 D
- ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1- M7 n4 {) y: R! s3 V* S, M5 X1 E
- ADC_ResetCalibration(ADC1); //使能复位校准
' v ~% x' u/ F6 h - while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
1 y! Z7 W7 F) @6 M0 z, s' z- a - ADC_StartCalibration(ADC1); //开启AD校准- e: ^: w* W! Y1 a0 o r& r( x
- while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束4 Q i% B3 K. S/ Z F3 j
- ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
s1 }6 ]9 N+ b0 }- ] - } " X" l; e7 [* O# m( L1 x9 @! }
- //获得ADC值0 O5 ]8 U [6 A" d) r3 G0 D+ v
- //ch:通道值 0~3 P- Q- ?3 N8 `; F. b3 E
- u16 Get_Adc(u8 ch) & n& k7 |/ @# e( I9 f ]
- {
& J2 K/ j3 _* x3 r7 Z$ J6 d+ o - //设置指定ADC的规则组通道,一个序列,采样时间
$ W1 b* Z5 n8 H - // ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
% c. h; F4 {' t1 U8 s2 [) ` - // # v) N0 d d" A7 d0 Y7 h, T
- // ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能 , Z/ L3 b: V) I; {0 g$ |" K
- // 4 z) |" z/ ^2 F; ]6 n8 h4 R* x
- // while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束6 V! H) X6 q& P5 |, Z: ?" D
- F4 i+ Z( E9 J: b+ M- return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果+ O5 b- u( P& N6 V" d. p
- }- u2 F- t' N/ X0 U4 n" Y
2 d. E6 u \0 \) |: l0 |' o( G- u16 Get_Adc_Average(u8 ch,u8 times)
1 i# M+ H* H9 a" S - {. t: {1 h$ Z9 l$ q( z
- u32 temp_val=0;
- ]/ q3 A, d# B& k6 q - u8 t;5 s8 a* G' [4 {+ |( w
- for(t=0;t<times;t++)
' e' m4 e, R9 H% t% z5 x - {6 r1 r4 I0 Q# D
- // temp_val+=Get_Adc(ch);) w( F- J3 [1 B) [8 [( A
- temp_val+=ADC_ConvertedValue;% N' z) i6 m5 I$ h- w; ~* C1 Z
- delay_ms(5);. l5 f& H/ h6 s
- }
# s) s* b5 s. Q - return temp_val/times;
! x5 I+ A! F9 w - }
' W. A- H/ @7 f. u0 W, b7 h) S+ V
6 I, S/ p( Q, w; j/ M# L% U# Q) i1 \
. H2 m* B. c7 D- 2 r- K$ }: D5 h
8 A2 d7 A% R- v' _; Q0 H- - o k! H. A6 Q9 F2 [
+ {. \. _! u/ G8 u5 k
% C# W4 d5 Z1 @, ~
; @+ D. Z5 m9 U% J- # G) S+ f2 H+ [# Z
- - ^1 U3 R& z0 E0 C1 M6 F4 s
- 5 \+ b; |* k( X; B: W# Q
y) \: c3 `) d+ t5 a8 e
& W4 q% b* z; g* Z- 3 l, |8 B2 u4 E8 B9 ^
- 3 C: z9 R) W. q7 Z* @3 o5 d: w
- 2 Q- y* Q. X, a+ {
- ! o3 ^0 u; K3 z2 r. x4 ~
, z+ l* w8 L' m. Y- 9 Q; z4 Z. E+ }5 Q3 T% a
- + _7 z5 s/ }- I
- 9 Y( B' D6 |. C- \) [% W8 |3 {/ n% J
5 D- `: z1 N, J8 P$ Z5 X! ~- o
5 _6 o, F4 F8 g. `* G
8 Y* B& w2 u: U' A9 d) ~
' [7 s- t6 a: y E; T5 @8 V
& y/ V% c8 [' z0 Z0 G" b w1 a
! G7 t- ^% S4 X2 \6 }
& m! [, \5 V" I8 y) O; ]: ]# Z0 k- 7 b4 m5 h) o) a
) ~( I% y5 s7 Q3 c5 F. N
) o& T% X6 O' k9 u2 j
1 V" L# B* _- E- #ifndef __ADC_H
% e' {6 t: U; z' [; S3 k - #define __ADC_H 8 F: w+ A& P1 I
- #include "sys.h"
' G+ a1 G9 c O - //本程序只供学习使用,未经作者许可,不得用于其它任何用途0 }4 V# ^- M D" r6 J/ m
- //ALIENTEK战舰STM32开发板) ?0 u' \& O! f4 `
- //ADC 代码
1 l* P* H* ~: V2 ~ - //正点原子@ALIENTEK; ?( Q, o4 H; G$ X- ]3 p7 Y# Z- ]
- //技术论坛:www.openedv.com, ^$ t) ^; W; F' A3 p* ~! }
- //修改日期:2012/9/7' w" Z0 i& p9 l7 C+ [
- //版本:V1.0
5 V+ z% X6 d9 W- P& S m$ Q - //版权所有,盗版必究。2 C1 w; p3 G9 t3 ]! d; h
- //Copyright(C) 广州市星翼电子科技有限公司 2009-2019$ R6 {" @# |# ~4 J! w" z
- //All rights reserved 4 o3 N# G2 n6 p0 q& Q7 J* S `0 D3 U
- //////////////////////////////////////////////////////////////////////////////////
3 g0 U) `" c3 E% n* \$ v2 ~
z: S3 A: X# I: P$ X- void Adc_Init(void);! x7 Y1 l& P/ K% V/ a. [( D: ^
- u16 Get_Adc(u8 ch);
) `+ D$ C# n- J* G - u16 Get_Adc_Average(u8 ch,u8 times);
! P" A! X( l4 X' x* P. ? - ! [! [1 K, M5 v6 [
- #endif
% T4 ^1 T* w( j r |2 K8 f+ E" Z) O
复制代码 - N% C& h: U) A# [1 m% ?" q
1 H; L) }/ g+ m; B8 Z+ q |