1. STM32F103 ADC 本例使用STM32F103芯片的PA1引脚测试模拟输入的电压值。 查看文档《STM32F103X.pdf》第31页,引脚定义图:
3 Y2 w. R3 F! Z5 `& O6 w' p+ u$ t3 M4 t& c% J( l
得知PA1使用ADC1的通道1。 查看文档《STM32F103X.pdf》第13页,时钟树图:
4 `4 N5 `9 B# ~6 h- [3 C. \, L" J
得知ADC1可2,4,6,8分频,又ADC输入时钟不得超过14MHZ(参见STM32参考手册RM0008第11章ADC)。 - //初始化ADC
3 E- z6 E% E0 _; k7 \/ \- x, O: e2 S6 p - //这里我们仅以规则通道为例
8 |5 J' g( l. n( r8 B3 U; @ - //我们默认将开启通道0~3
' N+ Q' x+ Q( [ F, n0 k5 L. u; @ - void Adc_Init(void)) k I) y8 j0 i/ [8 m! L' ]& C
- {
! c5 o* M8 R4 x3 U - ADC_InitTypeDef ADC_InitStructure; 6 A4 E v" j, L
- GPIO_InitTypeDef GPIO_InitStructure;7 i0 Z, }4 @9 v$ ^
- & ~0 C- Y. I2 X# o- n/ w4 K4 H
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE ); //使能ADC1通道时钟
3 |. F t# K c4 ^4 m2 M - * A* f3 c( k* O8 W
- / U' q' `1 L8 e" V$ Y% X
- RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M! j9 S# n% j8 e- d7 c) Q3 C0 b* z
( @% u1 X( u8 g- //PA1 作为模拟通道输入引脚 0 [ X5 H6 l7 a* c
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
$ ]& ^$ F0 U/ {# ` - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
4 g4 {& ], d# F% Q - GPIO_Init(GPIOA, &GPIO_InitStructure); ) C* i1 A8 x5 q8 _
- 1 [# ?6 p$ t* w& T
- ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值! Q9 N) c+ @, d. L( e' s6 v
- J+ U! T. x3 w7 U2 A
- ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
5 d/ {5 d/ g' K - ADC_InitStructure.ADC_ScanConvMode = DISABLE; //模数转换工作在单通道模式* G: Z8 I6 ?) n5 ]
- ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模数转换工作在单次转换模式. l! U) c5 |1 _% m
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
# K- B; H4 _: v8 D. i6 l - ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
1 s* ~ b0 n, v* Q3 s - ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目3 l9 G2 X7 M. P' ^& }. ]3 X& ?
- ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
# S8 J- J- t; S9 b$ X - ' j1 r' T8 `! c0 l
- ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
: [) i3 I! S3 C% t0 n9 m6 V - ADC_ResetCalibration(ADC1); //使能复位校准 " E# R# P c' g9 X: Q# B
- while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束' h9 D" I* b& E D. g( J! P! Y; o
- ADC_StartCalibration(ADC1); //开启AD校准
. z7 X5 H4 j: f* m. e! B: t' _ - while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
6 e& j7 l4 ]- V y/ N' w - ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
( C3 O4 F$ {7 b8 ^& M9 l7 } - }
复制代码- //获得ADC值0 Q% l! R* x' ~7 P' M
- //ch:通道值 0~3
8 v9 Y- k, M5 ~- _& v - u16 Get_Adc(u8 ch) " {1 n: `8 [2 q S3 M; ?2 x* m
- {
! z! ~/ [" A4 z4 t - //设置指定ADC的规则组通道,一个序列,采样时间
- w& P# w9 p5 ]$ n _ - ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期 3 w1 b* ]0 e* x0 @( J5 d2 m, K
- ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能 0 l( ] s" v2 ]0 j
- while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
9 V" v. J0 x0 u1 k2 W - return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果
% }) k# F5 i7 {- q - }
, g7 q/ ~+ \8 |7 w% N
; L9 Q) t: T5 a, N- u16 Get_Adc_Average(u8 ch,u8 times)) u' G9 J E$ A3 r8 m
- {
" I8 x) {" p8 E! j; |; c8 k - u32 temp_val=0;+ g2 \. W3 p0 ` U9 u5 D$ V
- u8 t;4 w4 J4 h. S6 Z' M* }7 \
- for(t=0;t<times;t++)
& s- q2 l* h- b3 @/ S - {
5 a8 g) {# R/ q# b" W/ m - temp_val+=Get_Adc(ch);; }% X7 x* W/ H6 B/ d, B* ]" _$ b$ I
- delay_ms(5);
M4 A% p) h6 k3 b; u' e8 j6 { - }
/ h9 _% l1 \" o# } - return temp_val/times;
* y$ g7 I# T# S! S4 ` - }
6 ~& Q3 w* x ~) V. j. Z) ]
F4 [7 h) G8 C% ?- void ADCTask(void)/ b2 Q1 U+ x: r M9 L. n! D$ L& K
- {3 J' ?5 z! }9 t; k
- float vol, adcx; G: p( t( m) z0 D
- while(1)
) t& l( u& j8 v# d$ Q& C* t: P( _2 G - {
( `8 { ^9 f4 x \5 F4 m - adcx=Get_Adc_Average(ADC_Channel_1,10); //ADC的值
4 p6 \2 L5 o+ y' b- R" K, J& Q6 L: Z - vol=(float)adcx*(3300/4096); //电压值(mv)
* I" o/ y6 c+ M# N8 ]1 I& s - delay_ms(200);; \% y( y6 H1 l7 [2 K" P: _9 B# |
- }, Y. M$ k" e6 f* {+ [
- }
复制代码 % }* s& M4 Y. G) C% o' N z# d w
2、 STM32F407 ADC 本例使用STM32F407芯片的PF9引脚测试模拟输入的电压值。
7 |0 g5 f$ n- `/ ]1 L* {
: e4 Y) r! b: ^查看文档《STM32F4x7-Datasheet.pdf》第43页,引脚定义图:
7 g, L- {% |2 K$ O9 N; v% H4 i查看文档《STM32F4x7-Reference manual.pdf》第51页,内存映射: 4 a1 B' Z% ~4 @7 J# B. T0 U4 T# x1 t
点击链接查看ADC寄存器映射: 3 I* K8 V" ?, o4 {2 t
又查看数据寄存器偏移量: # x7 t4 M6 R# U( V( o( n& M2 Z: E& @$ ^ |
得知数据寄存器地址:#define ADC3_DR_ADDRESS ((uint32_t)0x4001224C)
* W) W$ e8 p* C
3 r, `; P8 i5 t9 I: P得知使用DMA2 Stream0 通道2映射ADC3。 - #define ADC3_DR_ADDRESS ((uint32_t)0x4001224C)1 i) n1 r- A8 O% x7 c n
- / n0 c# m1 k8 g
- __IO uint16_t ADC3ConvertedValue = 0;
0 ?) y+ n5 h+ y. s: X3 G: ] - __IO uint32_t ADC3ConvertedVoltage = 0;
7 T3 l1 `" c# b! v. x; ?4 ]
: p. f6 v* U4 ^ R( @3 D8 y+ O- //ADC3 channel07 with DMA configuration# W9 Y" q5 [) o8 K2 E( W7 g1 B' h
- void ADC3_CH7_DMA_Config(void)
0 M h- {6 I$ U0 D- g, k( `7 ]" L - {6 t; H: O4 p. G% g {( Z
- ADC_InitTypeDef ADC_InitStructure;" |5 y) `. ~; ?" `$ c
- ADC_CommonInitTypeDef ADC_CommonInitStructure;" Y3 R" B$ u7 e- B: O$ Z
- DMA_InitTypeDef DMA_InitStructure; z5 J2 ?: r1 v+ T w/ \5 H
- GPIO_InitTypeDef GPIO_InitStructure;
7 m2 T# g$ A" Q$ c
$ P$ {! z" Y8 W- g5 G- /* Enable ADC3, DMA2 and GPIO clocks ****************************************/
5 C* E6 E# B8 D. m) t2 S - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOF, ENABLE);
' X) u4 \0 q5 [) [; z% j - RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
, B8 R- l- m/ b3 v - $ G+ A P0 K4 M9 f5 R+ w! j
- /* DMA2 Stream0 channel2 configuration **************************************/% J1 s& S& K; v" b
- DMA_InitStructure.DMA_Channel = DMA_Channel_2; + U9 u# ]* V- D A
- DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC3_DR_ADDRESS;4 G+ A; m0 p% |
- DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC3ConvertedValue;; K3 Y" B0 q( j: v! i9 j. ]- O8 b
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
0 F! h- W4 {8 T5 Y1 C; }3 C& X! ^& ? - DMA_InitStructure.DMA_BufferSize = 1;
. A9 L: B( g+ U - DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;* k4 X% N: t* K' H: B0 A2 E O+ B5 E
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
9 B. R1 Z J8 C+ }" j8 N0 R! _' K+ d - DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
' E7 k t0 U. s, p# I4 k' S7 V - DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;, d( Q/ b/ I& y0 o- f5 h* L. V- h
- DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;# s5 S { E2 ?1 ?
- DMA_InitStructure.DMA_Priority = DMA_Priority_High;7 v: i! g1 n0 f/ ? h
- DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; $ V" h- W0 ]* O- t2 C2 a
- DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
# k" b( @; a+ @' M - DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
9 r6 {# i$ q* ^+ H" ~! t* W; C8 ? - DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
3 x2 m4 z" A) ^7 Y( k - DMA_Init(DMA2_Stream0, &DMA_InitStructure);1 l3 P, [4 V R5 W3 r% s
- DMA_Cmd(DMA2_Stream0, ENABLE);
O5 f& o; M. o* @0 D" N5 j- g( W% T9 H - . s$ P6 ~7 @; i0 Y' }
- /* Configure ADC3 Channel7 pin as analog input ******************************/' ^. m4 ?, ]- p% h7 N
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
! a; q1 h2 R1 N6 _# u - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
8 w$ ?1 Q' x: A: m - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
0 ^! X! f$ f0 M - GPIO_Init(GPIOF, &GPIO_InitStructure);
G- B: k$ W4 F7 i - : G, v+ ?$ a: P, _
- /* ADC Common Init **********************************************************/9 k( y/ g) X9 W# c9 A
- ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
: _$ `) N$ n! q4 ~$ j) f# u - ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
@! J% j9 \: D3 }9 B/ [2 W8 E - ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;8 N2 C- A: U* e; ?/ X, A
- ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; r/ z2 Y1 ^- c5 | s: Y
- ADC_CommonInit(&ADC_CommonInitStructure);2 d! O% ]0 T, f. w, Z
- . M3 X: ~7 f1 {1 z; @8 P0 }- k4 _
- /* ADC3 Init ****************************************************************/
|8 w, n O1 d! Y" V0 q7 J - ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
+ k% c: p8 A+ a; C6 H" ~# p - ADC_InitStructure.ADC_ScanConvMode = DISABLE;: G! Y4 c" ^7 l# f ~: P
- ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;4 v; J& g0 Z) g3 ~3 q4 U
- ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;, c7 e5 M6 a0 |! K4 i
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;- z4 G, T' i# ?+ q% I/ e
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;0 j8 O% Q2 V0 m& {
- ADC_InitStructure.ADC_NbrOfConversion = 1;& }7 n1 J+ c. F1 H/ n
- ADC_Init(ADC3, &ADC_InitStructure);5 z+ X4 J O% y
4 M; n. r8 b, i; Z4 J7 L& N4 b+ a- /* ADC3 regular channel7 configuration *************************************/
: Y! T0 Q0 [. B! @ - ADC_RegularChannelConfig(ADC3, ADC_Channel_7, 1, ADC_SampleTime_3Cycles);
0 i9 B; C& D! V4 s1 {7 q R {
9 f& Q3 S6 z& a4 t+ T1 c9 B% b- /* Enable DMA request after last transfer (Single-ADC mode) */
- U( z8 @9 X. u( `2 \( y' Q' G - ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE);" i, j" H; q9 Q
% I0 q4 [! }5 V- /* Enable ADC3 DMA */. k: L1 V* _; f5 Q! {. x# R5 g
- ADC_DMACmd(ADC3, ENABLE);
4 p( j' p& w8 V0 i - , C4 O% [2 U. K$ {. D
- /* Enable ADC3 */
: p/ |% L7 i: W - ADC_Cmd(ADC3, ENABLE);
V/ X% @) g" @+ f" ] - }
% [ M) `! G- \2 c2 a: W - 0 l" r1 k6 {- I- y: @
- int main(void)
3 |3 C+ ?* j- u/ W: w - {: k1 {' p* Z0 e. u8 P
- /* ADC3 configuration *******************************************************// }. v4 ^7 U9 T& O8 t
- /* - Enable peripheral clocks */
! d [) D# \* y3 c1 [ - /* - DMA2_Stream0 channel2 configuration */* ~( G% {- w7 y9 Z9 j' I
- /* - Configure ADC Channel7 pin as analog input */
' `2 a- w1 [1 ~+ E) T - /* - Configure ADC3 Channel7 */- f% G+ z+ ^9 V6 K0 t9 q8 }
- ADC3_CH7_DMA_Config();! i; u" e, e9 w/ |
8 d1 Z3 t8 @4 D( j: g6 E- /* Start ADC3 Software Conversion */
1 w+ v6 C! U/ g8 e - ADC_SoftwareStartConv(ADC3);
6 r& z7 I- ]6 Z6 E6 H" A
: ^' [$ t" t8 S: i, R& A {; t- while (1)( y3 \0 V( b- j( t1 R
- {8 B+ V7 [1 V" }( ]6 g' J5 s
- ADC3ConvertedVoltage = ADC3ConvertedValue *3300/0xFFF;: j( v& g2 f9 B4 W8 u' F( s( k; H
" F; `9 k) @! i: |( @& w P- delay_ms(200);9 W; H8 o% v3 n; A4 w# k
- }8 }; O: F( e! Z4 s) d
- }
复制代码 % d! Z9 `' n [! N
D6 h. b/ Q5 A2 x |