1. STM32F103 ADC 本例使用STM32F103芯片的PA1引脚测试模拟输入的电压值。 查看文档《STM32F103X.pdf》第31页,引脚定义图: + }- S# \% e2 Z8 j/ d8 N1 l' a" g1 e
) x/ U; d; T$ t8 B6 v8 y& Y/ L
得知PA1使用ADC1的通道1。 查看文档《STM32F103X.pdf》第13页,时钟树图:
; {8 u. ^# |" r s. M1 U+ ^+ H# y4 \# M' x( M
得知ADC1可2,4,6,8分频,又ADC输入时钟不得超过14MHZ(参见STM32参考手册RM0008第11章ADC)。 - //初始化ADC
4 g ~0 u& y$ p, }5 y) B - //这里我们仅以规则通道为例5 l6 Q5 W2 G# @! J$ Y
- //我们默认将开启通道0~3 & I9 N2 F( p: P: E
- void Adc_Init(void). Q- l! O" w7 ~+ H! b- Q
- {
% S5 y4 ^9 n) @4 U6 \8 P - ADC_InitTypeDef ADC_InitStructure;
; e& r ^/ k6 a$ {% s" K+ P - GPIO_InitTypeDef GPIO_InitStructure;/ A: C4 f6 t( n# A5 Z
- - o8 A) [7 @, D. l5 j# K. U
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE ); //使能ADC1通道时钟' A5 O: y1 R8 e
- ) I$ S8 K" g- ~
) c1 f+ m$ A( U, b u8 ]- RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
3 E! e+ o1 T, [' T( i! P
! b: I3 f2 o! Y% ]2 I9 U4 z$ [9 I$ m- //PA1 作为模拟通道输入引脚 ! ]6 z. O: T9 m
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
: e7 ]# Z, {4 c9 E0 k/ S - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
" L1 e9 W- N* _, ~4 j - GPIO_Init(GPIOA, &GPIO_InitStructure); 7 v. @3 _- j9 n; o$ @' T
" t5 E/ V" E% ^0 _6 m- ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
6 K. @5 J# |2 U$ [9 H7 T - 1 ~7 o! y/ T' O5 z4 d5 }3 E
- ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式 t: o) {3 Z8 W' [; d! n s
- ADC_InitStructure.ADC_ScanConvMode = DISABLE; //模数转换工作在单通道模式
# \8 [3 u ^+ ? W* d: E - ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模数转换工作在单次转换模式
' p; s/ Q, i" O) R$ a& F - ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动% j6 N% |7 \3 O4 c
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
7 r# E3 y/ c! N$ L F0 L( i - ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目- Z/ {+ g7 u4 t( \5 ^# G
- ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
0 H1 l: l- W/ k0 `8 u
1 y- w1 ^: p0 R) U6 \8 L- ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1( s4 y$ Y0 B- C3 R$ Z; W
- ADC_ResetCalibration(ADC1); //使能复位校准 o+ o! R1 ~7 i* k' A, p$ I
- while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束; u" a! }. q$ ?6 X" B2 Q
- ADC_StartCalibration(ADC1); //开启AD校准
* @ i% O. w. ?4 u - while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束1 L5 F' n6 a @
- ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
0 Q% ~4 r3 u9 G( \% F! ` - }
复制代码- //获得ADC值1 }. x \9 f {4 L4 P3 B1 T9 z! @! R
- //ch:通道值 0~3$ |/ |* N0 N9 p# X) w1 d: a4 V" r
- u16 Get_Adc(u8 ch) % j8 u/ Q/ T! ]& [4 S0 z
- {- D4 e, Z5 u% |( `, V$ O8 s) \
- //设置指定ADC的规则组通道,一个序列,采样时间4 E, k% c2 }" k) {! @. h/ O' K
- ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
1 Q7 q% J/ K% R0 ? - ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
# G E; A! \: a, @. G+ @; I - while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
4 \( T. I5 \" e - return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果5 {+ v; p$ F4 V- P& C# t o
- }
6 \* s; R `" S9 d# V& F6 B4 H8 ^$ b - . [) e! U! t* h0 j
- u16 Get_Adc_Average(u8 ch,u8 times)
$ m: \( N: F; m0 C) f - {
( G% \" O# z5 i! \- w) G, }4 A - u32 temp_val=0;
: V. T- K$ |4 `! q% c* a$ r - u8 t;
, z; [: _2 F( z% N% Z - for(t=0;t<times;t++)
1 L2 S8 n) a+ |. J4 R9 M - {
( ~1 _; {; M* \. ]1 E' _' a, G - temp_val+=Get_Adc(ch);* Q! N( u7 R/ m2 N. V
- delay_ms(5);
/ v3 x+ r6 L" L9 H& ^ - }+ ^+ Z" l$ V4 `- H: |& x
- return temp_val/times;2 F* W& _" r. R
- }2 \2 T% Z8 u# N* h/ Y4 o9 j' p) k
- 6 _& t2 I( W$ f6 @ ]. p
- void ADCTask(void)# _4 G: {" l8 ~/ _" s/ n7 m( N8 x7 W2 G4 x
- {
' `! v" N1 S0 u' f* ?; W - float vol, adcx;
9 n0 [% P& P( s8 L. S# E) D9 P B - while(1)
/ h3 }( s9 F S$ R+ Z - {# @/ i7 c+ w: p5 v& F
- adcx=Get_Adc_Average(ADC_Channel_1,10); //ADC的值/ M8 X* r( d8 u7 u% |
- vol=(float)adcx*(3300/4096); //电压值(mv)
/ i: K% z. U( l/ |! C, C - delay_ms(200);( h9 `- r0 [: k x2 t
- }
9 l; }. D. q4 Z - }
复制代码 % v' p% F5 o D7 h4 f! {
2、 STM32F407 ADC 本例使用STM32F407芯片的PF9引脚测试模拟输入的电压值。
1 O- p+ Y6 g, G% m# R. v8 X, X0 ]. u' s+ m1 n1 w
查看文档《STM32F4x7-Datasheet.pdf》第43页,引脚定义图: % g) {8 ]: o: k5 K
查看文档《STM32F4x7-Reference manual.pdf》第51页,内存映射:
0 v# u8 c4 @- ]! C, d: T2 a点击链接查看ADC寄存器映射: & Z8 L; D, u4 c/ {
又查看数据寄存器偏移量: 8 \4 Q6 v) H, F
得知数据寄存器地址:#define ADC3_DR_ADDRESS ((uint32_t)0x4001224C)
6 Z$ j' E9 |9 |( {, {) \
$ R+ [, U' |# ^2 k" X W3 [ M得知使用DMA2 Stream0 通道2映射ADC3。 - #define ADC3_DR_ADDRESS ((uint32_t)0x4001224C)% k, o, z% |) s
- 4 c5 ]6 |/ X9 Z
- __IO uint16_t ADC3ConvertedValue = 0;
. U+ K2 `% L# `2 L+ \ - __IO uint32_t ADC3ConvertedVoltage = 0;
4 F# W3 @9 S7 w - / G. [9 D1 n% r
- //ADC3 channel07 with DMA configuration
( F0 S" O! @3 f/ V - void ADC3_CH7_DMA_Config(void)
% [9 i5 Y d- ?# x4 w9 G - {
' d2 {3 V' V( |) ]+ Q2 i* K - ADC_InitTypeDef ADC_InitStructure;9 s4 ?0 i7 X5 R
- ADC_CommonInitTypeDef ADC_CommonInitStructure;
) P# O. L3 }& w; t r - DMA_InitTypeDef DMA_InitStructure;' l6 d8 z" e) p" A- T
- GPIO_InitTypeDef GPIO_InitStructure;7 ^ g/ R! H( C, \. N) z2 I
( t" t( c4 Y3 @, @$ s4 k' ^/ [- /* Enable ADC3, DMA2 and GPIO clocks ****************************************/! w( Q5 \/ m$ U+ g S- N( v6 x$ B
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOF, ENABLE);
, O h* p! X( w- b/ K: l8 ~( \8 s$ X - RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
7 c0 {- b1 n2 a
7 x) W6 ?/ L$ A- /* DMA2 Stream0 channel2 configuration **************************************/
' N/ T2 }, x9 j+ j. r' e - DMA_InitStructure.DMA_Channel = DMA_Channel_2; : i. l0 L* b' G; m
- DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC3_DR_ADDRESS;
( j2 {1 x1 M) C3 F/ m - DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC3ConvertedValue;
+ a' t& N$ r- o$ ? - DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
$ W0 D, V E4 p4 Q - DMA_InitStructure.DMA_BufferSize = 1;. _. T0 ]+ k7 J
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;; Q# [. Q+ A' C0 T& U
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
5 x* s, l9 k- x& \1 ?5 x - DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;& [4 z5 e- W5 G2 Q1 J
- DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;+ y; h9 _0 _0 o0 I; ^
- DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
+ l' i/ b# ?! r# {: X" E+ @ D9 V - DMA_InitStructure.DMA_Priority = DMA_Priority_High;" a" K- e8 J2 S; x# H
- DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
' n+ n9 X% h/ j& A - DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
; L- q2 r! c5 f) N - DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;# }. ~5 c/ Z* i1 G4 I' { u
- DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
' |3 G- q* |1 ^7 u( f. [ - DMA_Init(DMA2_Stream0, &DMA_InitStructure);
3 t1 Q" `0 J' o& y6 K7 E% I* b - DMA_Cmd(DMA2_Stream0, ENABLE);
, g; m [- x0 P0 Q3 Y+ r: e
# Q5 p! v( K2 j% p* R+ b- /* Configure ADC3 Channel7 pin as analog input ******************************/- ~* A: [ T4 t
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
3 }0 l4 v5 v0 A0 f# ` - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;( Q6 |' u! Q$ ]# i+ x J$ u. W; K
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;2 Y, O4 f f* `- w( Q/ ^8 W# S2 _
- GPIO_Init(GPIOF, &GPIO_InitStructure);6 n5 u* r8 Q. X( o- z/ r6 @4 b
- % [, ?% m# z* W" s
- /* ADC Common Init **********************************************************/
_& D$ h1 S: ]6 C2 X7 }# k8 s) M4 B - ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
3 |# z/ A( ?. P/ G9 f3 j6 e7 M2 R( \ - ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
1 G! L+ z n1 N( G0 Z$ X - ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;& L2 X" A0 s$ V: O1 t Q" k; `
- ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
4 ~: W# a, k' W3 P7 N - ADC_CommonInit(&ADC_CommonInitStructure);
4 Q9 ?. m3 \( J# x* d
/ ?0 ^) l) `, q+ H$ I& ~3 F# d+ T- /* ADC3 Init ****************************************************************/3 p' M) B' C7 {" a3 H
- ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;/ Q; Q1 Q: H4 c( \! a: H
- ADC_InitStructure.ADC_ScanConvMode = DISABLE;
% e) N! I: u. w$ g$ [7 i) A - ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
3 K3 f( n8 ^# H# X' o. q& r1 P - ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;: U/ ~! e0 }# ?
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; W1 }! f/ N: b5 I/ _! ^$ p
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;6 s6 x0 E% m t7 u. m. U% j
- ADC_InitStructure.ADC_NbrOfConversion = 1; `: x; _) \0 E3 M
- ADC_Init(ADC3, &ADC_InitStructure);
5 C7 ]+ P% X( p! F S; }4 o - 8 s5 S4 G/ D( ]# S# t
- /* ADC3 regular channel7 configuration *************************************/
, g) t" x8 T* r8 ? P - ADC_RegularChannelConfig(ADC3, ADC_Channel_7, 1, ADC_SampleTime_3Cycles);
# m& ~" Q! |( P: h# E - 6 Z- S' E: F/ U) T; }. d9 N0 h
- /* Enable DMA request after last transfer (Single-ADC mode) */1 T4 M l! |, A3 ?4 T5 _
- ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE);
1 p2 |3 S. k5 J - 1 T; e- k! @+ ~6 u3 Z! A) T
- /* Enable ADC3 DMA */" @/ K: g0 n' `6 b
- ADC_DMACmd(ADC3, ENABLE);5 a' r# T& _4 k2 J# _9 [6 J2 [
: N( m0 {7 e& ]2 u2 Y$ [- /* Enable ADC3 */
2 |7 _# Y4 r( w - ADC_Cmd(ADC3, ENABLE);- H# U& }; ?$ Z0 B
- }3 t+ N" n, c6 U! k5 _
6 M, N/ m* v! @- int main(void) U$ U q4 k& D1 Y, ?6 _% t
- {( N& r0 c6 V! q i4 l# Q
- /* ADC3 configuration *******************************************************/
- n5 b7 P4 Q3 x3 a; l- T8 y - /* - Enable peripheral clocks */
! M) r" P* C9 J - /* - DMA2_Stream0 channel2 configuration */
- Y2 J" }/ |% H' ~ - /* - Configure ADC Channel7 pin as analog input */
( H6 q! C* ?; \! b1 U6 | - /* - Configure ADC3 Channel7 */. g5 |! \+ U/ N8 C# A0 X
- ADC3_CH7_DMA_Config(); n$ \2 b* C, D9 o. j7 k! X, s
- , K# S' r/ R: z
- /* Start ADC3 Software Conversion */ " {9 f/ v! \* B: T8 E
- ADC_SoftwareStartConv(ADC3);$ O3 B9 v$ [- t. j& c
, N" w8 }4 V) U! j& y* G, E, w- while (1)
" u4 {$ B$ j7 D5 N* \0 R - {) ~1 g% K1 a+ R3 U G2 Q
- ADC3ConvertedVoltage = ADC3ConvertedValue *3300/0xFFF;6 R! R! u! f+ l3 Z2 S! ]
f5 k; U0 l I" v! y L6 m7 Q- delay_ms(200);+ m) }4 h! _* g; K4 [& n
- }
! w: |! E0 o# n$ i0 D( l% A - }
复制代码
+ w; A$ D: o U5 \0 D8 ^; O$ |8 x9 S1 t9 _$ y7 t! H) U
|