MCU开发学习记录11 - ADC学习与实践(HAL库) - 单通道ADC采集、多通道ADC采集、定时器触发连续ADC采集 - STM32CubeMX
名词解释:
ADC: Analog-to-Digital
 SAR:Successive Approximation Register
本文将介绍ADC的概念、相关函数以及STM32CubeMX生成ADC的配置函数。针对于ADC实践:单通道采集芯片内部温度传感器(ADC1_ch16);利用软件触发单次触发多通道DMA ADC采集;利用定时器单次/连续触发多通道DMA ADC采集。
1. 什么是ADC?
1.1 ADC概念
1.1.0 ADC采集方法-逐次逼近寄存器型ADC
通过 “逐位试探比较” 的方式,从最高位(MSB)到最低位(LSB)依次确定每一位的二进制值,最终生成与输入模拟信号对应的数字代码。其结构框图如下:
        
一个4位转换示例,y轴(和图中的粗线)表示DAC的输出电压。本例中,第一次比较表明VIN < VDAC。所以,位3置为0。然后DAC被置为0b0100,并执行第二次比较。由于VIN > VDAC,位2保持为1。DAC置为0b0110,执行第三次比较。根据比较结果,位1置0,DAC又设置为0b0101,执行最后一次比较。最后,由于VIN > VDAC,位0确定为1。
        
1.1.1 ADC功能
STM32的ADC(Analog-to-Digital Converter)是一个 12位逐次逼近型(SAR)模数转换器,支持多通道、多模式信号采集,
- 分辨率:可配置为12位、10位、8位或6位(通过牺牲分辨率提升转换速度)。
- 输入通道:最多19个复用通道,包括: - 16个外部引脚(如温度、电压、电流传感器输入)。
- 2个内部信号源(内部温度传感器、内部参考电压)。
- VBAT通道:直接测量电池电压(需特定型号支持)。
 
- 转换模式:单次、连续、扫描、不连续采样模式。
- 数据存储:16位数据寄存器,支持左对齐或右对齐格式。
-  ADC 电源要求:全速运行时为 2.4 V 到 3.6 V ,慢速运行时为 1.8 V
-  ADC 输入范围: V REF- <= VIN <= VREF+
- 模拟看门狗(Analog Watchdog, AWD):监测输入电压是否超出用户设定的阈值范围,触发中断或事件
1.1.2 ADC框图
        
        
         
1.2 ADC功能介绍
1.2.1 ADC开关控制、时钟选择、ADC通道选择
1. ADC开关控制
ADC_CR2.ADON (A/D Converter ON / OFF):(0为禁止ADC;1为使能ADC)
 ADC_CR2.SWSTART(Start conversion of regular channels):开始转换规则通道(1为开始转换)
 ADC_CR2.JSWSTART(Start conversion of injected channels):开始转换注入通道(1为开始转换)
2. ADC时钟选择
- 模拟电路时钟(ADCCLK)- 所有 ADC 共用
 · 驱动ADC的模拟电路部分,包括采样保持电路(Sample&Hold)和SARADC。
 ·RCC_CFGR中的ADCPRE位,设置ADC分频系数。
- 数字接口时钟
 · 等效时钟:直接使用APB2总线时钟(f_{PCLK2}),无分频。
 · 使能控制:通过RCC_APB2ENR寄存器为每个ADC独立使能/禁用数字接口时钟。
 __HAL_RCC_ADC1_CLK_ENABLE(); // 使能ADC1数字接口时钟
3. ADC通道选择(分为规则转换和注入转换)
        
 
 下图为正点原子总结的规则组与寄存器对应表
 
 
 
 下图为正点原子总结的注入组与寄存器对应表
 
 
1.2.2 模拟看门狗
- 发生模拟看门狗标志
 ADC_SR.AWD
- 模拟看门狗中断使能
 ADC_CR1.AWDIE
- 模拟看门狗保护区域
  
- 阈值上下限设置(V = VREF*HTR(LTR)/4096)
 ADC_HTR 与 ADC_LTR
- 模拟看门狗通道选择(ADC_CR1.AWDCH[4:0])
  
  
  
1.2.3 单次转换模式、连续转换模式(ADC_CR2.CONT)
ADC_CR2.CONT:0为单次转换模式;1为连续转换模式
        
1. 单次转换触发方式
        ● 将 ADC_CR2 寄存器中的 SWSTART 位置 1(仅适用于规则通道)
         ● 将 JSWSTART 位置 1(适用于注入通道)
         ● 外部触发(适用于规则通道或注入通道)
2. 单次转换流程
- 规则通道转换完成: - 数据存储:结果存入ADC_DR(16位数据寄存器)。
- 标志位:EOC=1(转换结束标志)。
- 中断触发:若EOCIE=1,产生中断通知CPU读取数据。
- ADC状态:自动停止,等待下次触发。
 
- 数据存储:结果存入
- 注入通道转换完成: - 数据存储:结果存入ADC_JDR1(注入数据寄存器)。
- 标志位:JEOC=1(注入转换结束标志)。
- 中断触发:若JEOCIE=1,产生中断。
- ADC状态:自动停止。
 
- 数据存储:结果存入
3. 连续转换触发方式
- 规则通道: - 软件触发:置位ADC_CR2.SWSTART=1。
- 外部触发:配置外部触发源(如PWM同步信号)。
 
- 软件触发:置位
- 注入通道限制: - 默认禁止连续转换:注入通道无法独立启动连续转换。
- 唯一例外:若使能自动注入(JAUTO=1),注入通道可在规则通道组之后 自动插入转换。
 
4. 连续转换触发方式
● 规则通道组转换完成:
- 数据存储:最新结果覆盖ADC_DR寄存器。
- 标志位:EOC=1(每次转换结束均置位)。
- 中断触发:若EOCIE=1,每次转换均触发中断。
- ADC状态:立即启动下一轮转换,无需外部触发
● 自动注入模式(JAUTO=1)
- 功能:在规则通道组转换完成后,自动插入注入通道转换。
- 流程: - 规则通道组转换完成 → 触发注入通道转换。
- 注入通道结果存入ADC_JDR1,JEOC=1。
- 中断触发:若JEOCIE=1,通知CPU处理注入数据。
- ADC继续下一轮规则通道转换。
 
1.2.4 扫描模式、注入通道管理
1. 扫描模式
        ● ADC_CR1.SCAN 置1-选择扫描模式;
         ● 如果将 CONT 位置 1,规则通道转换不会在组中最后一个所选通道处停止,而是再次从第一个所选通道继续转换。
         ● ADC_SR.EOC:规则通道转换结束 (Regular channel end of conversion)
                 0:转换未完成 (EOCS=0) 或转换序列未完成 (EOCS=1)
                 1:转换已完成 (EOCS=0) 或转换序列已完成 (EOCS=1)
         ● ADC_CR2.EOCS:结束转换选择 (End of conversion selection)
                 0:在每个规则组转换序列结束时将 EOC 位置 1。溢出检测仅在 DMA=1 时使能。
                 1:在每个规则通道转换结束时将 EOC 位置 1。使能溢出检测。
2. 注入通道管理(ADC_CR1.JAUTO)
         
● 触发注入-配置条件
- JAUTO位清零:ADC_CR1.JAUTO=0(禁用自动注入)。
- 触发源选择: - 外部触发:通过ADC_CR2.JEXTSEL选择触发源(如定时器、外部引脚)。
- 软件触发:置位ADC_CR2.JSWSTART=1。
 
- 外部触发:通过
● 触发注入-工作流程
- 启动规则通道组转换: - 外部触发或软件触发规则组转换(如定时器触发)。
 
- 触发注入事件: - 在规则组转换期间,若检测到注入触发信号: - 复位当前规则转换:立即停止当前规则通道的转换。
- 执行注入组转换:以单次扫描模式完成注入通道组的转换。
 
 
- 在规则组转换期间,若检测到注入触发信号: 
- 恢复规则转换: - 注入组完成后,从被中断的规则通道继续转换。
 
● 自动注入-配置条件
- JAUTO位置1:ADC_CR1.JAUTO=1(启用自动注入)。
- 禁用注入触发:必须关闭外部触发(ADC_CR2.JEXTEN=0)。
- 连续模式支持: - 若ADC_CR2.CONT=1,规则组和注入组将循环转换。
 
- 若
● 自动注入-工作流程
- 规则组转换完成: - 规则组转换结束后,自动启动注入组转换。
 
- 注入组转换: - 按ADC_JSQR配置的顺序转换注入通道,结果存入ADC_JDR1~4。
 
- 按
- 循环转换(CONT=1时): - 注入组完成后,立即重启规则组转换。
 
1.2.5 不连续采样模式
1. 规则组
        ADC_CR1.DISCEN - 不连续采样模式使能
         ADC_CR1.DISCNUM[2:0] - n个子序列组
         ADC_SQR1.L[3:0] - 定义总序列长度
         
2. 注入组
        ADC_CR1.JDISCEN - 不连续采样模式使能
         ADC_JSQR1.L[1:0] - 定义总序列长度
         
        不能同时使用自动注入和不连续采样模式。
         不得同时为规则组和注入组设置不连续采样模式。只能针对一个组使能不连续采样模式。
1.3 数据对齐、通道采样时间、快速转换模式
1.3.0 规则/注入数据寄存器
1. 规则数据寄存器(ADC_DR)
        
2. 注入数据寄存器(ADC_JOFRx、ADC_JDRx)
        ADC_JDRx = 结果 - ADC_JOFRX (取16位补码)
         SEXT位(扩展的符号值):负数填充1;正数填充0
        
1.3.1 数据对齐ADC_CR2.ALIGN
ALIGN =0 右对齐(默认);=1 左对齐。
1. 右对齐(参考1.3.0)
        
2. 左对齐(参考1.3.0)
        
1.3.2 通道采样时间与转换时间
通过ADC_SMPR1、ADC_SMPR2的SMPx[2:0]控制各个通道的采样周期。
        
1.3.3 快速转换模式(降低精度转换)ADC_CR1.RES
        可通过降低 ADC 分辨率来执行快速转换。下列为转换时间。
         
1.4 外部触发和触发极性
1.4.1 外部触发极性
        
        
1.4.2. 外部触发条件
 
1.5 ADC数据采集方式(三种)
1.5.1 使用 DMA(ADC_CR2.DMA 置1)
1. 配置步骤
- 使能DMA:置位ADC_CR2寄存器中的DMA位。
- 配置DMA控制器:设置目标地址(内存缓冲区)和传输次数(NDTR计数器)。
2. 数据丢失(溢出)处理
- 溢出标志:若数据未及时读取且DMA未传输,ADC_SR寄存器中的OVR位会置1,并可能触发中断(需使能OVRIE位)。
- 溢出后果: - DMA传输被禁止,后续DMA请求被忽略。
- 正在进行的规则转换被中止,后续规则触发无效。
 
- 恢复步骤: - 重新初始化DMA:调整目标地址和NDTR计数器。
- 清除溢出标志:将ADC_SR中的OVR位清零。
- 重启转换:触发ADC开始新的转换。
 
- 重新初始化DMA:调整目标地址和
3. DMA传输结束
- 若ADC_CR2的DDS位为0,最后一次传输后停止DMA请求,需手动复位DMA位(先写0再写1)重启。
  
- 若DDS位为1,DMA继续生成请求,支持双缓冲区循环模式(适合连续流数据)。
1.5.2 在不使用 DMA 的情况下管理转换序列
1. 配置步骤
- 禁止DMA:ADC_CR2的DMA位清零。
- 使能每次转换结束中断:置位ADC_CR1的EOCS位为1(EOC在每次转换结束时置1)。
  
- 溢出处理: - 与DMA模式相同:需手动清除OVR位并重启转换。
 
- 与DMA模式相同:需手动清除
2. 配置步骤
- 启动转换序列:触发ADC开始转换。
- 等待EOC标志:每次转换结束,EOC位置1。
- 读取数据:从ADC_DR读取当前通道数据。
- 处理溢出(若发生):清除OVR位并重启转换。
1.5.3 在不使用 DMA 和溢出检测的情况下进行转换
- 禁止DMA:ADC_CR2的DMA位清零。
- 仅在序列结束置位EOC:EOCS位清零。
- 禁用溢出检测:默认情况下溢出检测已关闭。
1.6 多重 ADC 模式
1.6.1 多重 ADC 模式介绍(ADC_CCR.MULTI[4:0])
        
1. 四种模式(也可以组合使用)
● 规则同时模式
2. 多重ADC框图
注: 1. 尽管 ADC2 和 ADC3 上存在外部触发,但它们并未显示在此图中。
         2. 在双重 ADC 模式下,不存在 ADC3 从器件部分。
         3. 在三重 ADC 模式下,ADC 通用数据寄存器 (ADC_CDR) 包含 ADC1、ADC2 和 ADC3 的规则转换数据。按照所选的存储顺序使用全部 32 个寄存器位。在双重 ADC 模式下,ADC 通用数据寄存器 (ADC_CDR) 包含 ADC1 和 ADC2 的规则转换数据。使用全部32个寄存器位。
 
 
1.6.2 多重模式下DMA模式(ADC_CCR.DMA[1:0])(三种)
        
1. DMA模式1(半字传输)
- 核心特性
 传输单位:每个DMA请求传输 一个半字(16位),对应单个ADC的转换结果。
 触发条件:每完成一次ADC转换(一个数据项可用)时触发DMA请求。
- 数据传输顺序
 · 两重模式
 请求顺序为 ADC1→ADC2→ADC1→ADC2...,依次循环。
  
 · 三重模式
 请求顺序为 ADC1→ADC2→ADC3→ADC1→ADC2→ADC3...,依次循环。
  
- 应用场景
 规则同时模式:需要逐个读取多ADC数据的场景。
 示例:多通道温度监测,ADC1、ADC2、ADC3分别采集不同区域的温度值。
2. DMA模式2(字传输)
- 核心特性
 传输单位:每个DMA请求传输 一个字(32位),包含 两个半字(两个ADC的转换结果)。
 触发条件:每完成两次ADC转换(两个数据项可用)时触发DMA请求。
- 数据传输顺序 · 两重模式 
 每个字的高16位存储 ADC2数据,低16位存储 ADC1数据。
  
 · 三重模式
 按 固定组合顺序 传输三个ADC的数据,每个字包含两个半字:
  
- 应用场景
 交替模式:需要同时读取两个ADC数据的场景,例如电机控制中电流和电压同步采集。
 示例:双重交替模式下,ADC1采集电流信号,ADC2采集电压信号,每个DMA请求同时传输两者数据。
3. DMA模式3(字节传输)
- 核心特性
 传输单位:每个DMA请求传输 两个字节(8位×2),适用于 6位或8位分辨率 的ADC。
 触发条件:每完成两次ADC转换(两个数据项可用)时触发DMA请求。
- 数据传输顺序
 · 两重模式
 每个DMA请求的高8位存储 ADC2数据,低8位存储 ADC1数据。 
 · 三重模式
 数据传输顺序与DMA模式2相似,但以字节为单位:
  
- 应用场景
 规则同时模式:适用于6位或8位ADC的快速数据采集,简单传感器信号(如光敏电阻)。
 示例:ADC1和ADC2分别采集两个低分辨率传感器的开关状态。
1.7 多重 ADC 模式
1.7.1 注入同时模式
 
  
 
1.7.2 规则同时模式(ADC_CDR)
ADC_CDR:适用于双重和三重模式的 ADC 通用规则数据寄存器
注:必须禁止注入转换。
        
1. 双重ADC
- 触发条件:当任意一个ADC(ADC1或ADC2)完成一次转换时,触发DMA请求。
- DMA配置: - 设置 ADC_CCR寄存器的DMA[1:0] = 0b10。
- 生成 单次32位DMA传输请求,将 ADC2和ADC1的转换数据 组合传输。
 
- 设置 
- 数据格式: - 32位数据寄存器 ADC_CDR的高16位存储 ADC2的转换结果,低16位存储 ADC1的转换结果。
- 示例:若ADC1转换值为 0x1234,ADC2转换值为0x5678,则ADC_CDR = 0x56781234。
 
- 32位数据寄存器 
- 传输流程: - DMA将 ADC_CDR高16位(ADC2数据)写入SRAM目标地址。
- DMA将 ADC_CDR低16位(ADC1数据)写入下一个SRAM地址。
- 重复直到所有通道转换完成。
 
- DMA将 
    • 中断生成:
          EOC中断:当 所有常规通道均完成转换 后,触发EOC(转换结束)中断。
          中断使能:需在 至少一个ADC接口 的 ADC_CR1 寄存器中使能 EOCIE 位。
        
2. 三重ADC
- 触发条件:当任意一个ADC(ADC1、ADC2或ADC3)完成一次转换时,触发DMA请求。
- DMA配置: - 设置 ADC_CCR寄存器的DMA[1:0] = 0b01。
- 生成 三次32位DMA传输请求,分别传输 ADC1、ADC2、ADC3的转换数据。
 
- 设置 
- 数据格式: - 每个ADC的转换结果存储在独立的 ADC_CDR寄存器中。
- 传输顺序:先ADC1→再ADC2→最后ADC3。
 
- 每个ADC的转换结果存储在独立的 
- 传输流程: - 第一次DMA传输:ADC1数据写入SRAM地址A。
- 第二次DMA传输:ADC2数据写入地址A+4(32位对齐)。
- 第三次DMA传输:ADC3数据写入地址A+8。
- 重复直到所有通道转换完成。
 
-  中断生成 
 EOC中断:当 所有常规通道均完成转换 后,触发EOC(转换结束)中断。
 中断使能:需在 至少一个ADC接口 的ADC_CR1寄存器中使能EOCIE位。
        
1.7.3 交替模式
此模式只能用于规则组(通常为一个通道)。外部触发源来自 ADC1 的规则通道多路复用器。
 ADC_CCR.DELAY[3:0] - 设置交替模式下的采样时间。
        
1. 双重 ADC 模式
ADC1立即启动,经过几个ADC时钟周期延迟后ADC2启动。
只有一共ADC能够对输入信号采样,即DELAY设置的延迟时间小于采用时间时,延迟时间=采样时间+2个ADC_CLK时钟周期。如果 ADC1 和 ADC2 上的 CONT 位均置 1,则这两个 ADC 所选规则通道会连续进行转换。
        
        
2. 三重 ADC 模式
ADC1 立即启动,经过几个ADC时钟周期延迟后ADC2启动,在ADC2转换经过几个ADC时钟周期的延迟后ADC3启动。
        
         
1.7.4 交替触发模式
只能用于注入组。外部触发源来自 ADC1 的注入组多路复用器。
        
1. 双重 ADC 模式
        ● 发生第一次触发时,将转换ADC1中注入组的所有通道
                 当组中的所有注入 ADC1 通道都转换完成后,会生成一个 JEOC 中断(如果已使能)
         ● 发生第二次触发时,将转换ADC2中注入组的所有通道
                 当组中的所有注入 ADC2 通道都转换完成后,会生成一个 JEOC 中断(如果已使能)
        
如果使能 ADC1 和 ADC2 的注入不连续采样模式:
        ● 发生第一次触发时,将转换第一个注入 ADC1 通道
         ● 发生第二次触发时,将转换第一个注入 ADC2 通道
         ● 发生第三次触发时,将转换第二个注入 ADC1 通道
         ● 发生第四次触发时,将转换第二个注入 ADC2 通道
         ● ……
         当组中的所有注入 ADC1 通道都转换完成后,会生成一个 JEOC 中断(如果已使能)
         当组中的所有注入 ADC2 通道都转换完成后,会生成一个 JEOC 中断(如果已使能)
        
2. 三重 ADC 模式
        ● 发生第一次触发时,将转换ADC1中注入组的所有通道
                 当组中的所有注入 ADC1 通道都转换完成后,会生成一个 JEOC 中断(如果已使能)
         ● 发生第二次触发时,将转换ADC2中注入组的所有通道
                 当组中的所有注入 ADC2 通道都转换完成后,会生成一个 JEOC 中断(如果已使能)
         ● 发生第三次触发时,将转换ADC3中注入组的所有通道
                 当组中的所有注入 ADC3 通道都转换完成后,会生成一个 JEOC 中断(如果已使能)
        
1.7.5 混合型规则/注入同时模式
可以中断规则组的同时转换,然后开始注入组的同时转换。
1.7.6 规则同时 + 交替触发组合模式
可以中断规则组的同时转换,然后开始注入组的交替触发转换。
        注入事件后立即开始注入交替转换。当规则转换处于运行状态时,为确保在注入转换后实现同步,所有的(主/从) ADC规则转换均将停止,并会在注入转换结束时得以恢复运行。
         
        
1.8 ADC中断
| 中断事件 | 标志位 | 使能控制位 | 触发条件 | 
|---|---|---|---|
| 规则组转换结束 | EOC | EOCIE | 规则通道组所有通道转换完成(单通道或扫描模式) | 
| 注入组转换结束 | JEOC | JEOCIE | 注入通道组所有通道转换完成(需外部触发或自动注入) | 
| 模拟看门狗状态位置 1 | AWD | AWDIE | 输入电压超过模拟看门狗阈值(高 / 低阈值由 ADC_HTR 和 ADC_LTR 定义) | 
| 数据溢出(Overrun) | OVR | OVRIE | 数据寄存器(ADC_DR 或 ADC_JDRx)未及时读取,新数据覆盖旧值 | 
2. 基于HAL库配置ADC外设
2.1 CubeMX配置ADC外设
2.1.1 单通道采集内部温度传感器
         
2.1.2 多通道ADC采集(单次DMA请求)
        
        
2.1.3 多通道ADC采集 (定时器触发ADC采集(单次/连续))
         
         
2.2 基本定时器寄存器基地址
        
2.3 基本定时器寄存器
        
         
3. ADC实践
本次实践分为三个部分:单通道采集芯片内部温度传感器(ADC1_ch16);利用软件触发单次触发多通道DMA ADC采集;利用定时器单次/连续触发多通道DMA ADC采集。
多通道是内部温度传感器(ADC1_ch16)、光敏传感器(ADC1_ch1)
3.1 单通道采集内部温度传感器(查询)
- main函数
  
- 功能函数  
- 实践结果
  
3.2 多通道ADC采集(单次DMA)
- main函数
  
- 中断回调函数
  
- 实践结果
        
3.3 多通道ADC采集(定时器单次/连续触发DMA)
- main函数
  
- 中断回调函数
  
- 实践结果
  
4. 本文的工程文件下载链接
工程Github下载链接:https://github.com/chipdynkid/MCU-DL-STM32
 (国内)工程Gitcode下载链接https://gitcode.com/chipdynkid/MCU-DL-STM32
