
前言: 本系列教程将 对应外设原理,HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用& d* W, e# V2 S. b) u* Q( J. w7 E 所用工具:+ O) O) l* g, y- T2 A) C k0 }9 I3 G2 V 1、芯片: STM32F407ZET6/ STM32F103ZET60 [% a ?$ V8 e) g * z( j7 Q; A# H" D3 x: x& ]( u 2、STM32CubeMx软件 3、IDE: MDK-Keil软件 4、STM32F1xx/STM32F4xxHAL库! X' `0 z6 z; t$ p5 i: H + W$ h* [0 g3 }6 ?& B% u/ U+ M# h 知识概括: & E ^- m5 c' ^; K1 Y- i 通过本篇博客您将学到: ACD工作原理% {, O o |# d. o( V- g+ o STM32CubeMX创建ADC例程 ; z, }7 {$ j7 @5 K; x2 L HAL库定时器ADC函数库 ) _, M- [2 C) t1 G& ~- ] 什么是ADC' A6 O, t* m) K* m/ ~( O) K Analog-to-Digital Converter的缩写。指模/数转换器或者模拟/数字转换器。是指将连续变量的模拟信号转换为离散的数字信号的器件。 典型的模拟数字转换器将模拟信号转换为表示一定比例电压值的数字信号。1 i& r7 C% o! F6 i9 m 9 @2 b+ N! B: I4 v) k f 简单地说就是将模拟电压值,转换成对应的肉眼可读数值$ a6 R; s0 F Q* s' ~1 C* }/ p 12位ADC是一种逐次逼近型模拟数字转换器。它有,3个ADC控制器,多达18个通道,可测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中。" X: \5 i o, @5 X' C6 c " |. y. z; r6 x- T9 g9 S 12位模拟数字转换器$ P5 j0 n$ k9 E 就是ADC的数字存储是12位的 也就是说转换器通过采集转换所得到的最大值是4095 “111111111111”=4095 二进制的12位可表示0-4095个数, 对应着所测电压的实际值,转换的电压范围是0v-3.3v的话,转换器就会把0v-3.3v平均分成4096份。设转换器所得到的值为x,所求电压值为y。 ![]() 4 z- e& H" l- y5 W A 同理,可以理解8位精度和10位精度8 i% W1 w6 f' Z" | 具体的转压范围下面我们会讲% z0 I/ @- R- h, b! K ( L. M0 W) L0 f8 d0 h* j" [0 k) n( g 3个ADC控制器, C! b. S( L& C 就是说STM32一共有3个ADC ADC1,ADC2,ADC35 M. ~1 D% Z# P) ^ 7 {- [0 e. ~4 p9 x' k ![]() ! x, G I3 I' P; B0 V 18个通道 STM32 的ADC 多达18 个通道,( {! F% D+ [) l h 16个外部通道和2个内部信号源 具体是哪一个IO 口可以从手册查询到3 G, r7 a8 `, b% C& _2 p& b STM32F10x系列芯片ADC通道和引脚对应关系 :0 F3 p* @) K$ v/ y* h& m6 q6 r & i8 u, N( t! @3 W. O ![]() 16个外部通道:芯片上有16个引脚是可以接到模拟电压上进行电压值检测的1 B- F1 l, Z: f, b4 [ 2个内部信号源 : 一个是内部温度传感器,一个是内部参考电压2 ~4 |) R- q# C- F! {( T 一共支持23个引脚支持ADC,包括21个外部和2个内部信号源 9 {0 P+ d: Y. ^2 l, ~8 f4 |- ? W$ K ; C$ `- v# M5 a ADC的转换模式 (重要,请务必看懂)4 H# I4 D! y, M; n 1 单次转换模式:ADC只执行一次转换; * K; G+ S1 y+ _; Q1 G* [2 y& Z" I2 Y 2 连续转换模式:转换结束之后马上开始新的转换; k+ T3 Z' {4 A3 a1 e 4 k; A! X2 K) |: E6 L$ T, Z 3 扫描模式:ADC扫描被规则通道和注入通道选中的所有通道,在每个组的每个通道上执行单次转换。在每个转换结束时,这一组的下一个通道被自动转换。如果设置了CONT位(开启了连续 转换模式),转换不会在选择组的最后一个通道上停止,而是再次从选择组的第一个通道继续转换。 4 间断模式:触发一次,转换一个通道,在触发,在转换。在所选转换通道循环,由触发信号启动新一轮的转换,直到转换完成为止。$ V5 @9 |2 q3 M5 F/ } 扫描模式简单的说是一次对所有所选中的通道进行转换,比如开了ch0,ch1,ch4,ch5。 ch0转换完以后就会自动转换通道1,4,5直到转换完这个过程不能被打断。如果开启了连续转换模式,则会在转换完ch5之后开始新一轮的转换。9 Z4 x& G+ t( w5 ?- L. I4 b- W ! i- V0 f6 R+ X( F 这就引入了间断模式,可以说是对扫描模式的一种补充。它可以把0,1,4,5这四个通道进行分组。可以分成0,1一组,4,5一组。也可以每个通道单独配置为一组。这样每一组转换之前都需要先触发一次。 ADC单通道: Y4 L0 Y! u% \* R5 H 只进行一次ADC转换:配置为“单次转换模式”,扫描模式关闭。ADC通道转换一次后,就停止转换。等待再次使能后才会重新转换3 y6 n$ A% h! o% M: x# z 进行连续ADC转换:配置为“连续转换模式”,扫描模式关闭。ADC通道转换一次后,接着进行下一次转换,不断连续。 ADC多通道: 3 b5 d! [" m) [3 B2 ?" N. x 只进行一次ADC转换:配置为“单次转换模式”,扫描模式使能。ADC的多个通道,按照配置的顺序依次转换一次后,就停止转换。等待再次使能后才会重新转换 a0 d( u$ _# ~- S. l) \+ K 进行连续ADC转换:配置为“连续转换模式”,扫描模式使能。ADC的多个通道,按照配置的顺序依次转换一次后,接着进行下一次转换,不断连续。8 Q' C2 b) u8 M" u 也就是:多通道必须使能扫描模式 上面转换模式介绍一部分为转自他人. F: H0 V, o0 r) v/ X+ R4 U- W3 f 左对齐或右对齐 因为ADC得到的数据是12位精度的,但是数据存储在 16 位数据寄存器中,所以ADC的存储结果可以分为左对齐或右对齐方式(12位) - Z# {. N& l/ m; S4 Q ![]() ADC的工作框图 A1 E" T# O6 h3 L5 s! B ![]() # n6 f: g1 Y' X% a1 b2 a! J 图:stm32f103参考手册 接下来我们介绍下ADC的工作框图,让您有个更直白地了解,涉及到寄存器的一些部分不再详细讲解, 1 q1 ?- }# O( u3 ~6 r' w 1电压输入范围3 f. m# X' Z/ j; G% H. ~/ v ; R2 Q+ P# y8 o- U, K8 J1 w+ S/ m ![]() c# T( ^, w6 b2 W0 p5 J0 {: `! F0 c ADC一般用于采集小电压,其输入值不能超过VDDA,即ADC输入范围:VREF- ≤ VIN ≤ VREF+。具体的定义见上图。 一般把VSSA和VREF- 接地, VREF+ 和 VDDA接3V3,那么ADC的输入范围是0~3.3V。( x. _. y0 l: \0 ?' | 2ADC输入通道8 T$ G: j5 T( s1 L 从ADCx_INT0-ADCx_INT15 对应三个ADC的16个外部通道,进行模拟信号转换 此外,还有两个内部通道:温度检测或者内部电压检测 选择对应通道之后,便会选择对应GPIO引脚,相关的引脚定义和描述可在开发板的数据手册里找 5 J2 F% ^) Z/ M: N 3注入通道,规则通道, C5 C C. a6 o 我们看到,在选择了ADC的相关通道引脚之后,在模拟至数字转换器中有两个通道,注入通道,规则通道,1 K: V6 C/ N1 \$ j: O+ z) |! o4 g 规则通道至多16个,注入通道至多4个, A" V! Y1 u) d# p. [ 规则通道: 规则通道相当于你正常运行的程序,看它的名字就可以知道,很规矩,就是正常执行程序" S3 a/ P2 D: a2 m5 U + F: ^# u2 {7 R: p 注入通道:5 z6 G/ S j# @- y 注入通道可以打断规则通道,听它的名字就知道不安分,如果在规则通道转换过程中,有注入通道进行转换,那么就 要先转换完注入通道,等注入通道转换完成后,再回到规则通道的转换流程 ![]() 图:正点原子: G1 Q3 a! m' }3 ` : v5 r& l$ B3 x+ l" s$ s 你可以通过上图有一个更直观的认识,可以简单地把注入通道理解为中断形式,可以更好理解 4ADC时钟 图中的ADC预分频器的ADCCLK是ADC模块的时钟来源。通常,由时钟控制器提供的ADCCLK时钟和PCLK2(APB2时钟)同步。RCC控制器为ADC时钟提供一个专用的可编程预分频器。 分频因子由RCC_CFGR的ADCPRE[1:0]配置,可配置2/4/6/8分频6 d% a0 @# p" s& [( o9 {$ u 7 w' }" V# w; ~+ h( Z3 }/ v8 V3 f STM32的ADC最大的转换速率为1MHz,也就是说最快转换时间为1us,为了保证ADC转换结果的准确性,ADC的时钟最好不超过14M。3 J) u% T7 u7 z * Z; F" f- V) J- W- |6 d9 n T = 采样时间 + 12.5个周期,其中1周期为1/ADCCLK- a- ?& j! U! k W n 例如,当 ADCCLK=14Mhz 的时候,并设置 1.5 个周期的采样时间,则得到: Tcovn=1.5+12.5=14 个周期=1us。 5外部触发转换 ADC 转换可以由ADC 控制寄存器2: ADC_CR2 的ADON 这个位来控制,写1 的时候开始转换,写0 的时候停止转换 9 F3 R2 j% k5 v! U 当然,除了ADC_CR2寄存器的ADON位控制转换的开始与停止,还可以支持外部事件触发转换(比如定时器捕捉、EXTI线) 包括内部定时器触发和外部IO触发。具体的触发源由ADC_CR2的EXTSEL[2:0]位(规则通道触发源 )和 JEXTSEL[2:0]位(注入通道触发源)控制。 / a: q+ [, n2 F N$ ], ^ 同时ADC3的触发源与ADC1/2的触发源有所不同,上图已经给出,3 `7 `% ~* I% R+ E 具体查看第五部分框图即可理解0 g7 t: r+ e8 `, {/ D+ g3 @& Z' I 6中断6 T7 I, M r; t# J$ b6 ^ 中断触发条件有三个,规则通道转换结束,注入通道转换结束,或者模拟看门狗状态位被设置时都能产生中断, % W5 D! Y! [, u/ A, ~) w' B' ] ![]() 转换结束中断就是正常的ADC完成一次转换,进入中断,这个很好理解 " J7 G0 |6 K8 [2 b 模拟看门狗中断7 p0 Z1 t1 @7 x3 S+ q" A ,当被ADC转换的模拟电压值低于低阈值或高于高阈值时,便会产生中断。阈值的高低值由ADC_LTR和ADC_HTR配置 模拟看门狗,听他的名字就知道,在ADC的应用中是为了防止读取到的电压值超量程或者低于量程 DMA 同时ADC还支持DMA触发,规则和注入通道转换结束后会产生DMA请求,用于将转换好的数据传输到内存。 * t; R1 G0 C& B: w 注意,只有ADC1和ADC3可以产生DMA请求 因为涉及到DMA传输,所以这里我们不再详细介绍,之后几节会更新DMA,一般我们在使用ADC 的时候都会开启DMA 传输。 7 ?2 k7 C% ~1 j4 p ADC的主要特征 STM32F10x ADC特点 12位逐次逼近型的模拟数字转换器。9 p. Z+ \. D u2 H' j% q 最多带3个ADC控制器 最多支持18个通道,可最多测量16个外部和2个内部信号源。 支持单次和连续转换模式, y+ r1 S# v& F; i 转换结束,注入转换结束,和发生模拟看门狗事件时产生中断。 通道0到通道n的自动扫描模式 自动校准1 p( M! y+ N) P, M: W+ v 采样间隔可以按通道编程 规则通道和注入通道均有外部触发选项" A3 R7 q+ d; z0 _- b( J1 w# q8 Q 转换结果支持左对齐或右对齐方式存储在16位数据寄存器4 D+ [/ G% I9 h# y* @0 @. u ADC转换时间:最大转换速率 1us。(最大转换速度为1MHz,在ADCCLK=14M,采样周期为1.5个ADC时钟下得到。)1 c" \* [4 x! J ADC供电要求:2.4V-3.6V# B+ a' S" \0 X ADC输入范围:VREF- ≤ VIN ≤ VREF+ STM32F4x ADC特点 9 J( ^/ n, J/ R# k# T ![]() 6 ]" Y6 M: k5 S. _ 注: 上部分来自正点原子 2 L3 r: V G* J3 j& @ F1与F4区别 F4的ADC支持12位,10位,8位和6位精度,F1只支持12位, W( \' W/ s& U4 I) K( B F1和F4都具有3个ADC,F1可提供21个输入通道,F4可以提供24个输入通道。 \9 l, k+ R# t $ L4 D! J- m3 m8 g5 b; A: ]' x F1的ADC最大采样频率为1Msps,2路交替采样可到2Msps(F1不支持3路交替采样)。F4的ADC最大采样频率为2.4Msps,3路交替采样可到7.2Msps。4 I& L1 j+ ?, Y 下面到了CubeMax的创建时间: V/ L* ~: F$ H% L3 z* K 工程创建( u% [/ c! H8 m$ b 1设置RCC 设置高速外部时钟HSE 选择外部时钟源; C7 v# H! I, C+ T9 B0 ?% H6 R & h8 a( [7 B0 {4 Y9 u4 _0 C ![]() ( C$ S4 ?0 I, R1 X0 m6 O3 [ 设置ADC引脚 - s1 l7 ?/ _, f0 s( }& F6 E( w5 O ![]() ; X4 _9 \! t& ~, r% ~9 a4 w% H+ | 因为只有设置了ADC的引脚,才能够设置ADC的时钟分频( \' v0 A/ }( H8 R# q 2设置时钟 A4 G0 B$ L3 T7 E( ^0 I ![]() 9 A- g4 q( ?$ ]& a& n 我的是 外部晶振为8MHz' w* q) V/ ^4 t 1选择外部时钟HSE 8MHz 2PLL锁相环倍频9倍1 G6 T. l- |: ~. I: d 3系统时钟来源选择为PLL( T, ~) ~. n1 g6 Z 4设置APB1分频器为 /2) H: V/ s' H6 G! b, Z: @& |2 ? 5 设置ADC时钟分频 ,只能是6/8分频 如果ADC时钟频率大于14MHz则会报错 0 Q# m) r' X0 a3 p$ m# W) [: S3 h& K ![]() 1 k0 L6 u7 y- ?0 @) B& O! ^ ADC配置6 B8 B, x- |7 q W& }8 Y ![]() 这个我们简单的讲解下,如果看懂上方原理讲解,看这几个配置也是很简单的% a# u" g+ E. }* Q6 W1 i - a) O3 z1 R: [ N ADCs_Common_Settings ADC模式设置' |. K" V0 J3 R7 Y Mode ADC_Mode_Independent 这里设置为独立模式 独立模式模式下,双ADC不能同步,每个ADC接口独立工作。所以如果不需要ADC同步或者只是用了一个ADC的时候,应该设成独立模式,多个ADC同时使用时会有其他模式,如双重ADC同步模式,两个ADC同时采集一个或多个通道,可以提高采样率 5 }* Y0 {+ l5 [9 U Data Alignment (数据对齐方式): 右对齐/左对齐$ e4 y$ L- s- C1 `* G$ I3 L . Z% V& k K( c/ T& t1 G7 a 这个上方有讲解,数据的左右对齐2 T# c% q2 y) z: g( c9 G0 Q% J Scan Conversion Mode( 扫描模式 ) : DISABLE; V d( t) v1 E' z: i' g9 ~% } $ ^7 h4 ~6 I) r u" n 如果只是用了一个通道的话,DISABLE就可以了(也只能DISABLE),如果使用了多个通道的话,会自动设置为ENABLE。 就是是否开启扫描模式% J, c8 i9 s7 n& h0 ?* Z Continuous Conversion Mode(连续转换模式) ENABLE L7 O9 z8 b/ K" ` 设置为ENABLE,即连续转换。如果设置为DISABLE,则是单次转换。两者的区别在于连续转换直到所有的数据转换完成后才停止转换,而单次转换则只转换一次数据就停止,要再次触发转换才可以进行转换0 I1 i/ M! E3 _ S, o4 v6 O 1 U7 I: {9 {9 U5 X( B Discontinuous Conversion Mode(间断模式) DISABLE 3 M. K- O( X' U- w+ w$ |4 m/ Z 因为我们只用到了1个ADC,所以这个直接不使能即可- O2 F, W! A- `7 ^ 规则通道设置 Enable Regular Conversions (启用常规转换模式) ENABLE0 Q$ m5 v0 R! ^6 X ) X$ S, ]% X) A7 j( I& } 使能 否则无发进行下方配置- \, D/ _; r2 w# H" k; C Number OF Conversion(转换通道数) 1# Z! h$ l( r: @3 ?: i 用到几个通道就设置为几- p; l/ D' b+ ]$ Q$ b3 b+ n7 ? 多个通道自动使能扫描模式! `1 C' U: r5 x( j: e- P( J ![]() Extenal Trigger Conversion Source (外部触发转换源), A J: O( e7 r 设定ADC的触发方式 ![]() Regular Conversion launched by software 规则的软件触发 调用函数触发即可0 {! K; {- B0 Z2 d1 ^# e/ b& G! ~ Timer X Capture Compare X event 外部引脚触发, + Q e, T1 @2 t7 a8 J Timer X Trigger Out event 定时器通道输出触发 需要设置相应的定时器设置 这个具体在上方ADC框图的5部分有讲解 Rank 转换顺序( j. m2 ?% t/ |% Z, V( [9 b1 c0 U4 x' [ 这个只修改通道采样时间即可 默认为1.5个周期 1 ^, n* k. J, n& K; [; ?1 r ![]() : U$ P" z Q8 @+ v 多个通道时会有多个Rank,可以设定每个通道的转换顺序 ADC总转换时间如下计算: TCONV = 采样时间+ 12.5个周期 当ADCCLK=14MHz(最大),采样时间为1.5周期(最快)时,TCONV =1.5+12.5=14周期=1μs。 8 a( X4 }) I5 o, z+ y7 B 因此,ADC的最小采样时间1us(ADC时钟=14MHz,采样周期为1.5周期下得到) 这个上方也有讲解6 v6 c3 @$ C) ^* t1 ` / C1 q% s) N9 C6 L* m 注入通道设置 也就是注入通道的设置,和转换通道没啥太大区别,这里不再详解 ![]() - N8 d/ `! Z- ]3 `# J& q* x WahchDog Enable Analog WatchDog Mode(使能模拟看门狗中断) 8 ~; \, C& p# T) E" a7 w3 A+ V& y 这个上方有讲解,本质也测量值就是超出测量范围或者低于最低范围,启动看门狗: `) v4 ?$ P, Z7 c" O5 N$ ^: S( F, ^" N 具体的配置看下图: 8 A# I0 {" m' P) ^ ![]() ; F/ K1 G0 N9 D$ K ADC转换结束中断. k0 E8 a' y. T+ A9 X ( U) ?1 n; U; u1 Y+ h2 R, l4 Y" X% l ![]() + Y2 ]( {! d, _- s# L$ h" O ADC的DMA传输- Q2 F/ k. E3 b6 _, d4 k0 B/ C7 A ![]() GPIO的模式为模拟模式 ![]() ![]() * e |2 {: t% Y a2 T. l5 \% L% N+ e 1 设置项目名称. @+ Y9 m# n! k8 P 2 设置存储路径 3 选择所用IDE* t2 T) x" @! `( K5 i n; w ![]() 7 ~! T# P* H, C4 ?; c$ n; l% r 创建工程文件 然后点击GENERATE CODE 创建工程 配置下载工具 新建的工程所有配置都是默认的 我们需要自行选择下载方式,勾选上下载后复位运行 ( Q; P" B$ Z8 _. C ![]() ! }- R! d; j9 W 例程: 在main.c中加上$ ^4 @5 V3 x" S0 G. Q! o" B
在ADC初始化之后加上AD校准函数
while中加上:: _. j# B+ B7 ?! Q' E S) f# V 4 X0 v- X' v. U7 y" H) H& l
就可以完成正常读取8 }6 U! I. R4 g; q ![]() ( R$ w- E m' L5 Z, j7 K) f 中断读取: ) w5 U- |) }3 `" \: c- i/ x 如果使能了ADC转换结束中断,并且使能了定时器中断,可以这样写:7 B* p! M6 p. u! r6 g) f) ~ , P" ]* P. u Y' t& o* R4 R# b, D0 F
函数讲解: & c: ?. j! t/ ?7 [ 开启ADC 3种模式 ( 轮询模式 中断模式 DMA模式 )( w$ U5 G0 V1 D8 t • HAL_ADC_Start(&hadcx); //轮询模式开启ADC" Y+ }: c6 X' L& e" p) S1 { • HAL_ADC_Start_IT(&hadcx); //中断轮询模式开启ADC • HAL_ADC_Start_DMA(&hadcx); //DMA模式开启ADC# [6 {2 P' G! L( N: a4 R) g 关闭ADC 3种模式 ( 轮询模式 中断模式 DMA模式 )) N4 v0 ~9 m- h$ D# e 8 u& v2 D$ u" W Y* ?# c V3 c3 \4 v; [) x • HAL_ADC_Stop() • HAL_ADC_Stop_IT() • HAL_ADC_Stop_DMA() 8 q7 I; }' ~- T4 y1 E ADC校准函数 : • HAL_ADCEx_Calibration_Start(&hadcx); " M( J l$ d/ T8 Z0 U F4系列不支持, B b, q( Z+ K6 P7 [ " O I8 l* F& G) Z 读取ADC转换值 • HAL_ADC_GetValue() 等待转换结束函数 * d# l2 l! t/ a7 m, w* D% h • HAL_ADC_PollForConversion(&hadc1, 50);+ X2 U" Z3 S3 d; u9 w ' H1 i* R3 ~! J; \ 第一个参数为那个ADC,第二个参数为最大等待时间 # \2 u9 }& b9 X6 O' N) }' t- B- D& \ ADC中断回调函数/ A6 [2 T9 V. G; K7 r! P1 p: o • HAL_ADC_ConvCpltCallback(). Q* P; O* T1 z1 Y9 R8 \ ; `- ? {8 {' v9 N1 f: k( S 转换完成后回调,DMA模式下DMA传输完成后调用9 L" Q9 y: s. E7 f7 w 3 x# a, r' m+ N; c 规则通道及看门狗配置! G4 ^8 s( C3 e* k0 V7 C 0 I0 {1 P% v7 x • HAL_ADC_ConfigChannel() 配置规则组通道 • HAL_ADC_AnalogWDGConfig() $ a5 B* f. D! S3 ? 5 h. D8 x$ Z7 R& L# S + V6 [8 u7 y, [% p |
【2025·STM32峰会】GUI解决方案实训分享5-调通板载的NRF24L01 SPI接口并使用模块进行无线通信(发送和接收)
【2025·STM32峰会】GUI解决方案实训分享2-编译运行TouchGFX咖啡机例程(含桌面仿真)
实战经验 | Keil工程使用NEAI库的异常问题
STM32 ISP IQTune:真正零门槛的免费ISP调整软件
【经验分享】STM32 新建基于STM32F40x 固件库的MDK5 工程
意法半导体MCU双供应链策略,打消中国客户后顾之忧
【经验分享】基于STM32使用HAL库实现USB组合设备CDC+MSC
2024意法半导体工业峰会:赋能智能电源和智能工业,构筑可持续未来
ST推出灵活、面向未来的智能电表通信解决方案,助力能源转型
意法半导体 x Qu-Bit Electronix:推动新一轮的数字声音合成革命