EDA365电子工程师网
标题:
STM32的ADC
[打印本页]
作者:
cyxs
时间:
2016-6-15 16:25
标题:
STM32的ADC
一、基础知识
0 ]; _9 X1 \' R8 X! J9 \+ H
1. 18个通道,可测16个外部和2个内部信号源,可设置成单侧、连续、扫描、间断模式执行
) a2 n0 F. N) E* c: C. T l
2. 12位精度
# C8 e/ s9 J3 D" k! v# |* h
3. 扫描模式,通道0到通道n的自动转化
) {. m" O/ y2 V4 t% q7 k( J3 m
4. 自校准
* `! T: w7 D% v7 |
5. 按通道配置采样时间
" z3 E/ Q, x& a+ P; T. B4 Z: |7 g% A
6. 间断模式?
$ i0 a& t1 n* |- D. }8 k1 ^, z
7. 双ADC模式?
8 J, i+ P; `% @2 }. x
8. 供电要求2.4~3.6V
" U) L t! B0 {# S
9. 输入范围0~3.6V
- |' A3 z ?, l2 s9 [: p9 ^
二、功能描述
8 e" c2 ~9 z7 f
1. 通道选择:
: K, ~( E- H0 J
STM32的每个ADC模块通过内部的模拟多路开关,可以切换到不同的输入通道并进行转换。在任意多个通道上以任意顺序进行的一系列转换构成成组转换。例如,可以如下顺序完成转换:通道3、通道8、通道2、通道2、通道0、通道2、通道2、通道15。
. v' |: A4 L6 ]: m1 ]
有2种划分转换组的方式:规则通道组和注入通道组。通常规则通道组中可以安排最多16个通道,而注入通道组可以安排最多4个通道。
/ i) E ]* @5 T
在执行规则通道组扫描转换时,如有例外处理则可启用注入通道组的转换。规则转换和注入转换均有外部触发选项,规则通道转换期间有DMA请求产生,而注入转换则无DMA请求,需要用查询或中断的方式保存转换的数据。
! ?+ v: i+ @4 V5 i/ d- i" C
一个不太恰当的比喻是:规则通道组的转换好比是程序的正常执行,而注入通道组的转换则好比是程序正常执行之外的一个中断处理程序。 规则组由多达16个转换组成。规则通道和它们的转换顺序在ADC_SQRx寄存器中选择。规则组中转换的总数写入ADC_SQR1寄存器的L[3:0]位中。
9 R6 q+ a/ v5 K' w
注入组由多达4个转换组成。注入通道和它们的转换顺序在ADC_JSQR寄存器中选择。注入组里的转换总数目写入ADC_JSQR寄存器的L[1:0]位中。
- S5 }1 f' Y9 K
如果规则转换已经在运行,为了在注入转换后确保同步,所有的ADC(主和从)的规则转换被停止,并在注入转换结束时同步恢复
5 T) Y1 ?9 c/ u
) y; P% _7 f! e- O5 D9 k( v
5 z- w9 ]5 X8 ^' f5 ~
2. 单次转换模式:
( D( Q9 ?0 v9 d+ i' x
单次转换模式里,ADC 只执行一次转换。
, T" Q& u8 ?+ C2 r
3. 连续转换模式:
) X3 B4 j+ t' ]. W2 c
在连续转换模式中,当前面ADC 转换一结束马上就启动另一次转换。
9 G: M; y2 [# R$ F7 X X
4. 扫描模式:
; J+ c) P/ Y4 z4 ?
此模式用来扫描一组模拟通道。
* |. N0 G, S! W# H* @0 M' p0 |8 i
5. 注入模式管理:
; z" f3 n& E+ Q5 {) k/ ~& D
(1)触发注入。详见参考手册
/ p B6 b' ?1 ` o
(2)自动注入。如果设置了 JAUTO 位,在规则组通道之后,注入组通道被自动转换。这可以用
" h4 r% ], l- s, U. l
来转换在ADC_SQRx 和ADC_JSQR 寄存器中设置的多至20 个转换序列。
/ U8 v% Z! k9 Q, C# A2 p
在此模式里,必须禁止注入通道的外部触发。
i9 j6 [1 c, x) h
6. 间断模式:
0 h0 R5 |3 m o: B
(1)规则组
+ f# k6 _3 T6 [2 o! a7 R7 }' s
此模式通过设置 ADC_CR1 寄存器上的DISCEN 位激活。它可以用来执行一个短序列的n 次转换(n<=8),此转换是ADC_SQRx 寄存器所选择的转换序列的一部分。N 由ADC_CR1 寄存器的DISCNUM[2:0]位给出。一个外部触发信号可以启动ADC_SQRx 寄存器中描述的下一轮 n 次转换,直到此序列所有的转换完成为止。总的序列长度由ADC_SQR1 寄存器的L[3:0]定义。
* Y# V" T r& v I- `% J
举例:
) d' s" u4 }$ Q
n=3,被转换的通道 = 0, 1, 2, 3, 6, 7, 9, 10
S, d, C+ W5 n" _
第一次触发:转换的序列为 0,1,2
' {6 L+ J8 A: q6 g! E$ u& l
第二次触发:转换的序列为 3,6,7
H9 _. ?# t. ?0 c- G% w
第三次触发:转换的序列为 9,10,并产生EOC 事件
5 v' X4 A0 t* N5 M$ @
第四次触发:转换的序列 0,1,2
6 V8 q) n( J( P' \. o" F
注意: 当一规则组以间断模式转换时,转换序列结束后不自动从头开始。当所有子组被转换完成,下一次触发启动第一个子组的转换。在上面的例子中,第四次触 发重新转换第一子组的通道 0,1 和2。
8 E* Y7 N* \( f7 l; B$ s& q$ H. V
(2)注入组
* p! B) ]" N4 ~2 i# R- ^
此模式通过设置 ADC_CR1 寄存器的JDISCEN 位激活。在一个外部触发事件后,给模式按序转换ADC_JSQR 寄存器中选择的序列。
+ |: u& q* _- {
一个外部触发信号可以启动ADC_JSQR 寄存器选择的下一个通道序列的转换,直到序列中所有的转换完成为止。总的序列长度ADC_JSQR 寄存器的JL[1:0]位定义。
! d) L1 z% v/ \5 r, Y
例子:
, i8 K e1 t5 u# J3 v" X1 [
n=1,被转换的通道 = 1,2,3
. a* j7 k; A" M- B( ~
第一次触发:通道1 被转换
; Y4 e& ~1 }! N, I
第二次触发:通道2 被转换
1 I, _6 T8 I. G" j! P+ ~9 B
第三次触发:通道3 被转换,并且产生EOC 和JEOC 事件
6 v9 [2 o, J0 B
第四次触发:通道1 被转换
) S; v1 {7 s. \5 f
注意:1 当完成所有注入通道转换,下个触发启动第1 个注入通道的转换。在上述例子中,第四个触发重新转换第1 个注入通道1。
2 K( x9 v7 i1 J
2 不能同时使用自动注入和间断模式。3 必须避免同时为规则和注入组设置间断模式。间断模式只能作用于一组转换。
& b& P1 j, O8 t. T U
7. 双ADC模式
! Y8 U' \- b9 f- l
8. 数据对齐
# X: y% D8 J: y, a4 Q! r
ADC_CR2 寄存器中的ALIGN位选择转换后数据储存的对齐方式。数据可以左对齐或右对齐,如图146 和图147 所示。
3 r6 T& @8 I$ I& w( b9 o' W9 v
注入组通道转换的数据值已经减去了在ADC_JOFRx 寄存器中定义的偏移量,因此结果可以是一个负值。SEXT 位是扩展的符号值。
) W+ z$ {7 X( R. L
对于规则组通道,不需减去偏移值,因此只有12 个位有效。
. q! z- O& p+ w% ^+ ], }/ r' g
数据右对齐:
, `( p3 m6 V. e3 ]6 g7 p
注入组
! r0 v3 J0 D) x( ?( D" U! D
SEXT SEXT SEXT SEXT D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
- z5 _* e2 Z' B- ]5 u7 _* {! W
规则组
9 I; S- x5 }# r5 W- v
0 0 0 0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
0 u5 {" q1 t. |) v3 L
数据左对齐:
9 M9 T' z$ c3 T% W1 k
注入组
, z& R+ b7 Z. Z
SEXT D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 0 0 0
" N( V E$ N7 w: Z% G+ z: q# M. y
规则组
1 I5 n' }, T* C
D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 0 0 0 0
* g& G/ u2 [) J/ N, H1 K$ T1 A
三、 程序设计与软件配置
! G6 k/ l7 x1 [) @
1.
. _' ?) K$ R$ \# }
void ADC_Config(void)
, h) H( O4 f- n2 U, f# z( p; X$ x) u
{
" _8 P3 c3 s% [/ G( X& J. S& k
ADC_InitTypeDef ADC_InitStructure;//定义ADC初始化结构体变量
* {. x5 M7 ^8 l9 [) S
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC1和ADC2工作在独立模式
: j) D. L) h# k6 S( E
ADC_InitStructure.ADC_ScanConvMode = ENABLE; //使能扫描
2 } p7 F* m }
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//ADC转换工作在连续模式
S! U/ k1 i" d9 J! A5 ?6 ?% Q8 Z2 @
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//由软件控制转换
H$ a7 _1 Q) W
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//转换数据右对齐
. c; d' d9 E; e4 C+ z+ S7 s
ADC_InitStructure.ADC_NbrOfChannel = 1;//转换通道数目为1
7 M7 \! L: ^" W( u" m" u
ADC_Init(ADC1, &ADC_InitStructure); //初始化ADC
) h# g+ J( d7 [0 q2 `# F1 t
ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_28Cycles5);
8 b0 l J6 H8 n0 W
//ADC1选择通道14,规则组采样顺序(1~16),采样时间239.5个周期
- y" M9 Y1 N8 O8 u% `
ADC_DMACmd(ADC1, ENABLE);//使能ADC1模块DMA
) h5 V+ A$ D5 c5 c2 R/ s
ADC_Cmd(ADC1, ENABLE);//使能ADC1
) y/ W7 v5 q6 q; K+ z/ Z$ n
ADC_ResetCalibration(ADC1); //重置ADC1校准寄存器
. s5 B& h" P& H: @6 ?. f
while(ADC_GetResetCalibrationStatus(ADC1));//等待ADC1校准重置完成
+ M! R7 y% M) e$ f& y
ADC_StartCalibration(ADC1);//开始ADC1校准
; o5 ]; G8 q4 v+ u
while(ADC_GetCalibrationStatus(ADC1));//等待ADC1校准完成
3 _- T# U+ o% J
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能ADC1软件开始转换
; l1 P4 N" i6 g1 n2 D' c/ X. i; L* N
}
作者:
cyxs
时间:
2016-6-15 16:25
欢迎光临 EDA365电子工程师网 (https://bbs.elecnest.cn/)
Powered by Discuz! X3.2