只做了一路,多路的话自己扩展
) S! n- ?% h$ {/ N. l4 b+ ~: h- #include "adc.h"0 `% c, S: T2 x/ U4 i. O
- #include "delay.h"
8 x0 p; Z6 _+ d% j6 z! i& d- s6 p5 | - ////////////////////////////////////////////////////////////////////////////////// 1 k7 @1 i/ E8 @8 {1 {" D: a$ D
- //本程序只供学习使用,未经作者许可,不得用于其它任何用途* ^& ?+ d' g. }1 A( m) b* v8 ^
- //ALIENTEK miniSTM32开发板
/ l* B1 P% W: f7 D. M7 h- n - //ADC 代码
4 q1 X* p9 V9 H( E8 A - //正点原子@ALIENTEK% {+ X9 `& y2 Q5 M1 I8 {
- //技术论坛:www.openedv.com; G U+ q, C- G7 y5 u7 ~) k' }
- //修改日期:2012/9/7
' D9 ^3 y$ d; \3 T1 C - //版本:V1.05 ]! l/ C& l% R& Q
- //版权所有,盗版必究。
0 u3 V; \2 S- |3 a$ X - //Copyright(C) 广州市星翼电子科技有限公司 2009-2019
9 a2 E" J) b2 E* L - //All rights reserved 3 J6 m; B$ n6 e8 S
- //////////////////////////////////////////////////////////////////////////////////
* M0 k! ? R, K% n - " E/ B9 P, ~! O( f3 ^
- __IO uint16_t ADC_ConvertedValue; + B% ` O. O( Y7 c, S
- //初始化ADC
5 [+ w: }- m/ t3 G - //这里我们仅以规则通道为例( M. H9 X# p. r9 Q" W. f
- //我们默认将开启通道0~3 0 F, e( N; E7 ~# _# A* _
- void Adc_Init(void)
" E& i- U# p; w* z5 k) [ - { ! b' d; X$ S5 Z
- ADC_InitTypeDef ADC_InitStructure; 7 `# I) E9 K8 @7 v
- GPIO_InitTypeDef GPIO_InitStructure;
1 b! a: |+ h# } - /*--------------------------DMA部分---------------------------*/
/ N& z5 a" i/ |+ _% r4 S - DMA_InitTypeDef DMA_InitStructure; ( T$ u3 F7 D& w9 B* u6 {
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);// 打开DMA时钟6 `8 b- a9 w% J0 Y* U% w
- DMA_DeInit(DMA1_Channel1);// 复位DMA控制器7 j5 W% w1 X- a0 f& w
- DMA_InitStructure.DMA_PeripheralBaseAddr = ( uint32_t ) ( & ( ADC1->DR ) ); // 配置 DMA 初始化结构体 // 外设基址为:ADC 数据寄存器地址8 o+ d: f- H8 f% ~
- DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;// 存储器地址,实际上就是一个内部SRAM的变量5 n) D ~& s; |6 B
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;// 数据源来自外设2 A: a9 W) _0 |
- DMA_InitStructure.DMA_BufferSize = 1;// 缓冲区大小为1,缓冲区的大小应该等于存储器的大小
" j* ]& S- D* ?- X1 u5 @ - DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;// 外设寄存器只有一个,地址不用递增
& l' N! i2 D/ ?+ v - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; // 存储器地址固定
) t. r5 ]# b5 i; N - DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;// 外设数据大小为半字,即两个字节: }# F: `) |$ }: k/ ]' W. R
- DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;// 存储器数据大小也为半字,跟外设数据大小相同; n' E6 ^, o( F8 g6 w4 G
- DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 循环传输模式
0 s8 b; C; h6 D0 I - DMA_InitStructure.DMA_Priority = DMA_Priority_High;// DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响
. r/ w$ z; V7 r% m% w4 Q - DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;// 禁止存储器到存储器模式,因为是从外设到存储器( A/ t' Y' u& D% b1 V4 B
- DMA_Init(DMA1_Channel1, &DMA_InitStructure);// 初始化DMA |. a. `; b& K% Z
- DMA_Cmd(DMA1_Channel1 , ENABLE);// 使能 DMA 通道; ?$ \1 s5 R0 m j
- /*--------------------------DMA结束---------------------------*/
8 d0 {+ I, |4 g8 u, E% V& q - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE ); //使能ADC1通道时钟
2 d" |& Z1 x, N2 b5 w/ v+ f - RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M& ]2 j8 S# b7 V: W+ R; p
- - }, D' y; B2 t
-
7 g5 u1 g0 P8 |1 u& |, x" r" I( w - //PA1 作为模拟通道输入引脚
- o' J; z L6 }2 h - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;1 e8 B' I3 b6 \
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
1 E7 [ p7 d8 l* M: ]8 j - GPIO_Init(GPIOA, &GPIO_InitStructure);
' G5 t" N: i& t- L - 1 v/ o- _# _! L; G M
- ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
5 |( \+ x! J1 c+ B2 B - $ P# l5 L, w! [5 i
- ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式$ E' D1 t/ I7 G' w* v4 B' u- l
- ADC_InitStructure.ADC_ScanConvMode =DISABLE ; //模数转换工作在单通道模式1 |# R' b# H2 c# k8 e
- ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //模数转换工作在单次转换模式) @) t/ N: c+ ?. e2 o- X
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
v8 R7 z! a' g1 x7 x* }+ D. d! L( Q - ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
+ h/ M. ^8 N9 @6 x, l - ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目
- k/ [8 Z' V& J; q9 `. U' }7 e8 D* o - ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器 # P' b8 M9 T$ Y5 w, ?
- ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5 );
/ j4 [& C; k* b$ \ - ADC_DMACmd(ADC1, ENABLE); // 使能ADC DMA 请求
# L7 i( t. `: S$ c5 k% ] -
6 L s( L6 C9 h$ E5 m4 I - ADC_Cmd(ADC1, ENABLE); //使能指定的ADC13 U* B$ @* L/ W% r/ W6 B8 H
- ADC_ResetCalibration(ADC1); //使能复位校准 \$ x" g1 @6 Y: B6 U9 B
- while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
8 X6 J' M! a; l( V5 f l) m - ADC_StartCalibration(ADC1); //开启AD校准( j+ `; d% l* q# j
- while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束. Q( H$ h/ X9 s! ~ q
- ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
4 d( D: N {$ a) H; U - } ! e; l$ f: O: @0 K
- //获得ADC值3 A4 r# K4 v3 y' `( F. f f% C
- //ch:通道值 0~3
/ B( _3 @) i. F. |+ {" u - u16 Get_Adc(u8 ch) ! L0 M* N P( @. x2 {
- {, a& @* i& H3 w, X) v4 l1 `
- //设置指定ADC的规则组通道,一个序列,采样时间
' y' W+ }$ Y/ {5 f4 o% Y! B7 M6 A - // ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
- E! \. U- k: y) y( I - //
/ t9 R: y* h, C! f b; J$ a' g; y - // ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
- E% u2 O$ ?, ? - //
% G" t) P/ {9 c( @, O" B+ G# P; h - // while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束* b9 h0 }9 ?1 B7 e0 A' y' {
- * c; }0 N2 S3 q% ?: q
- return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果. @* ?4 {' x/ r5 h$ r8 r& a1 f$ z$ t
- }
/ D/ I8 o8 m; P3 ~, U' L- l7 u
5 O d* l+ E8 W$ \1 W- u16 Get_Adc_Average(u8 ch,u8 times)7 K! m1 e' o9 e2 }& D/ |2 X
- {
* k2 I2 Z+ @ n' a* ^9 @ - u32 temp_val=0;1 Z; A0 b# f" s( Z6 q* N A
- u8 t; v p) E5 n$ V" q
- for(t=0;t<times;t++)' A5 e4 q+ }6 Z! j
- {
`7 o+ D8 p! y9 `" c' q - // temp_val+=Get_Adc(ch);
3 P9 j6 E9 |% ^& ^# B! b! e) I - temp_val+=ADC_ConvertedValue;
N+ @. Q3 X- W - delay_ms(5);& L$ y# e! z+ z, C Y u; d
- }
" W- u. S3 L! o. l+ A' R# ~* e - return temp_val/times;. F' n( k, j; \' {; H2 z
- } 4 d6 t$ d/ C, G/ V; l1 a3 M
- - q9 [! r# w& C; h3 G
2 O! d) X% ?7 }7 H
) m& O; c* N( X/ p/ j
3 n4 s$ ^( U& d6 ?! I4 @0 y- : i$ x0 K2 D; V2 r% ^, E8 n N
4 t: _: U8 a" R( u
( b2 l: {+ {7 C$ m- 8 W8 c: v$ r' I
8 e# g# [% i$ x% t x1 f0 e3 {" O
# r [4 s7 Q" l7 p; J
+ t, H! c; t# n8 N- K
2 W" P. `, Y, l. D' i/ Z: ?- ; K0 u( V. t, }
- % Q$ b/ X; ~- E* ^4 i9 U. p
- 9 ?8 G: G- t& Y1 e- Z3 d, C# Z
2 t3 ^6 Y* p- w4 X g5 O- & D* x/ H4 D& z7 H
- ) O b8 ?3 Z0 I: v& @* W
- 0 n+ y9 }6 M( j5 \/ q7 D
; f4 ]% C. w3 |6 F% B
q/ j, B/ J, k A3 b& V8 h v
y& J) C+ a* k9 [, @
0 B5 `8 b& x9 g& H2 c- ' |# n/ p) x6 j9 l# k: Y
4 O9 K% X; n# [- ?6 o9 ~- - p" X9 L/ N' W$ _! ?, B/ B# [
- & Y: L7 m7 B; g* o' N+ t) r
# y' }% ?1 ]& v% ]- , ~! V( K4 G9 z# ~0 I8 o5 e
- , r H( Q: A9 }7 @6 [( R* e
- 9 ^# _! J' l: F4 X, Z9 u
A% B0 }# X# W& V- #ifndef __ADC_H
# l, m2 r( I2 |( l. A+ w - #define __ADC_H
; E; J/ T8 |+ ~ S - #include "sys.h") T! D6 D/ G& s( y' H/ n
- //本程序只供学习使用,未经作者许可,不得用于其它任何用途9 S& \* r" y. r% \' j+ Q; e
- //ALIENTEK战舰STM32开发板
$ r \5 X) W) i8 @ - //ADC 代码
! a$ T! ^! s0 x - //正点原子@ALIENTEK
; ?' @- g- {4 n9 z - //技术论坛:www.openedv.com) h! D4 O( p1 Q" i6 C$ U2 S! t* Z" o
- //修改日期:2012/9/7/ r% W* A- \3 u
- //版本:V1.0
5 u& ?. U- R9 R1 H d4 W p c) m - //版权所有,盗版必究。
" w2 s4 a) d1 d8 S+ w - //Copyright(C) 广州市星翼电子科技有限公司 2009-20197 V& O" O1 \) ]
- //All rights reserved ; b! l0 [9 A; F0 s( W% I
- ////////////////////////////////////////////////////////////////////////////////// . n- t9 y! ?! c6 |( z. p/ D+ n
' f" d5 g/ m, v1 L- void Adc_Init(void);; ~" r* t) `% u( \! Q/ k
- u16 Get_Adc(u8 ch); * T) O# E3 T& ^& `! f
- u16 Get_Adc_Average(u8 ch,u8 times);
* S8 F! p$ B( [0 O - 8 e' E2 M) \) r3 F9 F
- #endif 8 Q* V* P$ w5 R: V
复制代码
{+ e5 ?- I8 c4 e3 M2 {5 E
) U) }- W( ^* p |