【STM32】HAL库-ADC

12位ADC是一种逐次逼近型模拟数字转换器。它有多达18个通道,可测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中。
模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。

ADC的输入时钟不得超过14MHz

在这里插入图片描述

注意点

1. 使用注入通道的自动注入功能,不能同时使用自动注入和不连续采样模式,并且为了安全起见,注入通道应配置软件触发转换,或者禁止注入通道触发

2. 在多重 ADC 模式下,配置外部事件触发转换时,应用必须设置为仅主器件触发而禁止从器件触发,以防止出现意外触发而启动不需要的从转换;或者从ADC设置成软件触发,这样可以防止意外的触发从转换

3. 多重ADC模式下,需要使用DMA进行传输数据(规则通道下),必须开启主ADC的DMA传输,从ADC不需要开启,即ADC_DMACmd(ADC1, ENABLE);

ADC开关控制

通过设置ADC_CR2寄存器的ADON位可给ADC上电。当第一次设置ADON位时,它将ADC从断电状态下唤醒。

ADC上电延迟一段时间后(tSTAB),再次设置ADON位时开始进行转换。

tSTAB可查询数据手册
一般来说是1us在这里插入图片描述

通过清除ADON位可以停止转换,并将ADC置于断电模式。在这个模式中,ADC几乎不耗电(仅几个μA)。
也就是 启动ADC,第一次置位ADON位后,等待tSTAB时间后,硬件将ADON置位,如果这时候软件第二次置位ADON位,则ADC开始转换

寄存器ADCx_CR2的ADON位如下:
在这里插入图片描述
我们应该通过寄存器ADCx_CR2的SWSTART/JSWSTART位来启动ADC的转换,而不是置位ADON来启动转换。(在通过软件触发启动ADC转换的情况下)
在这里插入图片描述
将ADC从断电模式中唤醒的HAL库的代码如下:
函数ADC_Enable()
在这里插入图片描述

通道选择

在这里插入图片描述
在这里插入图片描述

单次/连续转换

可通过寄存器ADCx_CR2的CONT位来选择是单次转换还是连续转换
在这里插入图片描述

扫描模式

此模式用来扫描一组模拟通道。
扫描模式可通过设置ADC_CR1寄存器的SCAN位来选择。一旦这个位被设置,ADC扫描所有被A**DC_SQRX寄存器(对规则通道)ADC_JSQR(对注入通道)**选中的所有通道。

在每个组的每个通道上执行单次转换。在每个转换结束时,同一组的下一个通道被自动转换。如果设置了CONT位,转换不会在选择组的最后一个通道上停止,而是再次从选择组的第一个通道继续转换。

如果设置了DMA位,在每次EOC后,DMA控制器把规则组通道的转换数据传输到SRAM中。而注入通道转换的数据总是存储在ADC_JDRx寄存器

注入通道没有DMA搬运数据的功能。

最小转换时间

ADC最大时钟频率为14MHz,最小采样时间为1.5周期 + 12.5固定周期 = 14个周期,即1us
通过寄存器ADC_SMPRx的位SMPx设置采样时间。
在这里插入图片描述

DMA请求

因为规则通道转换的值储存在一个仅有的数据寄存器中,所以当转换多个规则通道时需要使用DMA,这可以避免丢失已经存储在ADC_DR寄存器中的数据。

只有在规则通道的转换结束时才产生DMA请求,并将转换的数据从ADC_DR寄存器传输到用户指定的目的地址。
注入通道没有DMA请求
但是注入通道有4个数据寄存器ADC 注入数据寄存器x (ADC_JDRx) (x= 1…4) 和4个数据偏移寄存器ADC注入通道数据偏移寄存器x (ADC_JOFRx)(x=1…4)
在这里插入图片描述

只有ADC1和ADC3拥有DMA功能。由ADC2转化的数据可以通过双ADC模式,利用ADC1的DMA功能传输。

注入通道

注入通道有4个数据寄存器ADC 注入数据寄存器x (ADC_JDRx) (x= 1…4)
在这里插入图片描述

4个数据偏移寄存器ADC注入通道数据偏移寄存器x (ADC_JOFRx)(x=1…4)
在这里插入图片描述

注入通道序列

不同于规则转换序列,如果JL[1:0]的长度小于4,则转换的序列顺序是从(4-JL)开始
在这里插入图片描述

注入通道管理

在这里插入图片描述

ADC独立模式-扫描连续转换-DMA-软件触发-规则和注入通道-自动注入demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

ADC1开启3个规则通道,转换序列为:通道0(PA0),通道1(PA1),通道2(PA2)
在规则通道每个通道转换完成之后,DMA负责将转换的数据从ADC_DR寄存器传输到用户指定的目的地址

开启3个注入通道,转换序列为:通道0(PA0),通道1(PA1),通道2(PA2)
注入通道触发选择为自动注入(当规则通道的所有通道转换完成之后开始转换注入通道)

开启注入转化完成中断。
注入转换完成之后在注入通道转换完回调函数中串口输出转换的数据

规则通道所有通道共享一个数据寄存器,而注入通道各有一个数据寄存器

配置过程

  1. 开启ADC、DMA、GPIO的时钟
  2. 配置GPIO为复用模拟模式
  3. 数据对齐方向;设置ADC_CR2寄存器的ALIGN位
  4. 连续转换;设置ADC_CR2寄存器的CONT位
  5. 扫描模式;设置ADC_CR1寄存器的SACN位,多通道的需要开启扫描模式

规则和注入通道配置

  1. 规则通道的外部触发;设置ADC_CR2寄存器的EXTTRIG位
  2. 选择启动规则通道组转换的外部事件,软件触发;设置ADC_CR2寄存器的EXTSEL[2:0]位为111
  3. 注入通道的自动注入;设置ADC_CR1寄存器的JAUTO位
  4. 配置通道1/2/3的采样时间;设置ADC_SMPRx寄存器
  5. 配置规则通道转换序列与需要转换的通道个数;设置ADC_SQRx寄存器
  6. 配置注入通道转换序列与需要转换的通道个数;设置ADC_JSQRx寄存器
  7. 配置注入通道数据偏移寄存器;设置ADC_JOFRx寄存器

ADC的DMA配置

  1. 开启规则通道的DMA传输;设置ADC_CR2寄存器的DMA位
  2. 配置ADC使用的DMA通道(传输方向、外设地址、SRAM地址、地址自增等等),但不使能DMA通道
  3. 根据需要使能DMA通道全局中断,及配置DMA全局中断优先级,使能DMA传输完成/半传输完成中断等

ADC的中断

  1. 使能ADC全局中断,配置ADC全局中断优先级
  2. 使能注入通道转换完成中断;先清除ADC_SR寄存器的JEOC位,再设置ADC_CR1寄存器的JEOCIE位

使能ADC和DMA

  1. 从断电状态中唤醒ADC;设置ADC_CR2寄存器的ADON位可给ADC上电。当第一次设置ADON位时,它将ADC从断电状态下唤醒。等待tSTAB后,检查ADON位是否硬件置位,是则成功唤醒ADC,如果成功唤醒ADC后软件置位ADON位,则ADC开始转换。
  2. 使能DMA通道
  3. 开启规则通道转换;设置ADC_CR2寄存器的SWSTART位

STM32CubeMX配置
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
注入通道的序列配置与上图类似
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

DMA传输
定义一个数组adc1Value
独立ADC模式下只用到低16位,故只定义uint16_t类型
在这里插入图片描述
ADC初始化函数添加用户代码
开启注入通道转换完成中断(在中断函数中HAL库会关闭该中断,我们可以根据需要再次开启该中断)
在这里插入图片描述
注入通道转换完成(所有通道都转换完成)回调函数void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc)
通过串口发送数据
在这里插入图片描述
这里再给出规则通道转换完成回调函数void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc);

工程文件下载链接

注意点-注入通道序列配置BUG

注入通道序列配置有BUG,仔细观察1/2/3
本次开启3个注入通道,转换序列为:第一个转换(通道0),第二个(通道1),第三个(通道2)
可是STM32CubeMX生产的配置全都是ADC_INJECTED_RANK_1即第一个转换,执行了三次HAL_ADCEx_InjectedConfigChannel()都是配置第一个转换的通道,最后变了转换序列为:第一个转换(通道2),第二个(通道0),第三个(通道0)
故需要我们手动调用HAL_ADCEx_InjectedConfigChannel()进行注入通道序列配置,如方框3
在这里插入图片描述

注意点:注入通道的自动注入功能

如果使用注入通道的自动注入功能(当规则通道的所有通道转换完成之后开始转换注入通道)

最好的做法就是自己写代码,而不是利用STM32CubeMX进行配置,如下图
在这里插入图片描述
手动添加代码实现自动注入功能

/* 设置注入通道的外部触发 软件触发 */
MODIFY_REG(hadc1.Instance->CR2, ADC_CR2_JEXTSEL, ADC_INJECTED_SOFTWARE_START);//设置为软件触发
SET_BIT(hadc1.Instance->CR2, ADC_CR2_JEXTTRIG);//使能注入通道的外部触发

原因:
HAL库的注入通道配置函数HAL_ADCEx_InjectedConfigChannel()
在这里插入图片描述
在独立ADC模式中,可以通过HAL库进行配置注入通道的自动注入功能,但是多重ADC模式中,注入通道外部触发源默认为000,不是软件触发,故如果通过STM32CubeMX配置,则出错。

ADC的外部触发

转换可以由外部事件触发(例如定时器捕获,EXTI线)。如果设置了EXTTRIG控制位,则外部事件就能够触发转换。EXTSEL[2:0]和JEXTSEL2:0] 控制位允许应用程序选择8个可能的事件中的某一个,可以触发规则和注入组的采样。

注意: 当外部触发信号被选为ADC规则或注入转换时,只有它的上升沿可以启动转换
在这里插入图片描述

ADC独立模式-扫描单次转换-DMA-外部触发-规则和注入通道-自动注入demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

ADC单次转换,规则通道的外部触发为定时器3的TRGO,定时器3的TRGO事件来源于更新事件,每500ms更新一次,即ADC每500ms转换一次

ADC1开启3个规则通道,转换序列为:通道0(PA0),通道1(PA1),通道2(PA2)
在规则通道每个通道转换完成之后,DMA负责将转换的数据从ADC_DR寄存器传输到用户指定的目的地址

开启3个注入通道,转换序列为:通道0(PA0),通道1(PA1),通道2(PA2)
注入通道触发选择为自动注入(当规则通道的所有通道转换完成之后开始转换注入通道)

开启注入转化完成中断。

注入转换完成之后在注入通道转换完回调函数中串口输出转换的数据

配置要点

  1. 配置好ADC的参数,规则/注入通道的参数,DMA的配置后
  2. 规则通道的外部触发;设置ADC_CR2寄存器的EXTTRIG位
  3. 选择启动规则通道组转换的外部事件,定时器3的TRGO触发;设置ADC_CR2寄存器的EXTSEL[2:0]位为100
  4. 使能ADC相应中断
  5. 使能ADC和DMA

STM32CubeMX配置
定时器3配置

在这里插入图片描述
定时器初始化函数添加用户代码
在这里插入图片描述
ADC配置
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

ADC初始化函数添加用户代码
这个时候ADC_CR2寄存器的SWSTART位由外部触发来控制
在这里插入图片描述
注入通道转换完成中断回调函数
在这里插入图片描述
工程文件下载链接

如果是使用EXTI线来触发ADC转换则配置如下
在这里插入图片描述

在这里插入图片描述

数据对齐

在这里插入图片描述

ADC校准

在这里插入图片描述
注意在校准之前得开启ADC的时钟与完成使用ADC的GPIO配置(复用模拟模式)

在这里插入图片描述
在这里插入图片描述

配置过程

  1. 使能ADC时钟与相应的GPIO配置
  2. 使ADC处于断电状态至少2个ADC时期;复位ADC_CR2寄存器的ADON位,并保证该位在复位状态超过2个ADC时期
  3. 将ADC从断电模式中唤醒;具体查看ADC开关控制章节
  4. 初始化校准寄存器并等待初始化结束;置位ADC_CR2寄存器的RSTCAL位,并等待硬件将RSTCAL位复位
  5. 开始校准ADC并等待校准结束;置位ADC_CR2寄存器的CAL位,并等待硬件将CAL位复位
  6. 校准结束;校准值存储在ADC_DR寄存器中。

调用HAL库的HAL_ADCEx_Calibration_Start()来校准ADC。
在这里插入图片描述

ADC校准demo

该demo在ADC独立模式-扫描单次转换-DMA-外部触发-规则和注入通道-自动注入demo的基础上,添加ADC校准功能

STM32CubeMX配置相同

不同之处,在ADC初始化前,开启ADC时钟和配置ADC的GPIO之后,添加ADC校准代码,如下

HAL_ADC_MspInit()中添加
在这里插入图片描述
注入通道的数据偏移寄存器写入ADC校准值
函数MX_ADC1_Init()
在这里插入图片描述
注入通道中断回调函数
在这里插入图片描述
工程文件下载链接

多ADC模式

在这里插入图片描述
使用触发模式时,从ADC需要设置使能外部触发,并且是软件触发。
需要转换完成的中断或者其他中断,尽量使用从ADC的中断

在这里插入图片描述
在这里插入图片描述

同步注入模式

在这里插入图片描述
在这里插入图片描述
ADC1和ADC2同时开始转换,但是每次转换的通道不能相同,转换完成后的数据存储在每个ADC接口的ADC_JDRx寄存器中,如果需要转换完成中断,则开启相应中断。

同步规则通道

在这里插入图片描述
与同步注入通道类似,ADC1的数据在ADC1_DR寄存器的低16位中,ADC2的数据在ADC1_DR的高16位中,如果需要转换完成中断,则开启相应中断。

双ADC模式-同步规则模式-DMA-外部触发demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

ADC1和ADC2都是单次转换,ADC1的规则通道的外部触发为定时器3的TRGO,定时器3的TRGO事件来源于更新事件,每500ms更新一次,即ADC每500ms转换一次

ADC1开启2个规则通道,转换序列为:通道0(PA0),通道1(PA1)
ADC2开启2个规则通道,转换序列为:通道0(PA1),通道1(PA0)

ADC1和ADC2设置相同通道的转换时间都一样。如,在规则通道上,ADC1和ADC2的通道0转换时间相同。

在规则通道每个通道转换完成之后,DMA负责将转换的数据从ADC_DR寄存器传输到用户指定的目的地址

开启ADC2的规则通道转化完成中断。

转换完成之后在规则通道转换完回调函数中串口输出转换的数据

配置要点
先配置从ADC和双重ADC使用的DMA

  1. 配置好从ADC的参数,规则/注入通道的参数,双重ADC使用的DMA的配置后
  2. 规则/注入通道的外部触发;设置ADC_CR2寄存器的EXTTRIG位
  3. 选择启动规则/注入通道组转换的触发来源,软件触发;设置ADC_CR2寄存器的EXTSEL[2:0]位为111
  4. 使能从ADC相应中断
  5. 从断电模式唤醒从ADC

主ADC

  1. 配置好主ADC的参数,规则/注入通道的参数,置位主ADC的ADC_CR2寄存器的DMA位
  2. 规则/注入通道的外部触发;设置ADC_CR2寄存器的EXTTRIG位
  3. 选择启动规则/注入通道组转换的触发来源,定时器3的TRGO触发;设置ADC_CR2寄存器的EXTSEL[2:0]位为100
  4. 双重ADC的模式选择;寄存器ADC_CR1的DUALMOD[3:0]位
  5. 从断电模式唤醒从ADC
  6. 使能主ADC和双重ADC使用的DMA

STM32CubeMX配置

主ADC配置
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
从ADC配置

在这里插入图片描述
在这里插入图片描述

ADC1的初始化函数添加用户代码
在这里插入图片描述
在这里插入图片描述
ADC2的初始化函数添加用户代码
在这里插入图片描述
规则通道转换完成自动回调函数
在这里插入图片描述

其实也可以不使用ADC2的规则通道转换完成中断,因为双重ADC使用DMA搬运数据,HAL库会开启DMA的传输完成中断,在DMA传输完成中断会调用ADC的规则转换完成中断回调函数

在同步注入模式下,注入通道有相应的DR寄存器,不需要DMA来搬运,故需要开启注入通道转换完成中断让我们知道转换完成了。

工程文件下载链接

双ADC模式-同步规则模式-DMA-外部触发-自动注入demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

ADC1和ADC2都是单次转换,ADC1的规则通道的外部触发为定时器3的TRGO,定时器3的TRGO事件来源于更新事件,每500ms更新一次,即ADC每500ms转换一次

ADC1开启2个规则通道,转换序列为:通道0(PA0),通道1(PA1)
ADC1开启2个注入通道,转换序列为:通道0(PA0),通道1(PA1)
ADC2开启2个规则通道,转换序列为:通道0(PA1),通道1(PA0)
ADC2开启2个注入通道,转换序列为:通道0(PA1),通道1(PA0)

ADC1和ADC2设置相同通道的转换时间都一样。如,在规则通道上,ADC1和ADC2的通道0转换时间相同。

在规则通道每个通道转换完成之后,DMA负责将转换的数据从ADC_DR寄存器传输到用户指定的目的地址

开启ADC1和ADC2的自动注入功能。
开启ADC2的注入通道转化完成中断。

转换完成之后在注入通道转换完回调函数中串口输出转换的数据

STM32CubeMX配置

ADC1
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
ADC2
在这里插入图片描述
在这里插入图片描述
MX_ADC2_Init()
在这里插入图片描述
MX_ADC1_Init()
在这里插入图片描述
注入通道转换完成中断回调函数
在这里插入图片描述
工程文件下载链接

快递交叉模式

在该模式下,采样周期必须要小于7个ADC周期
仅用于规则通道,不能使用注入通道的自动注入
在这里插入图片描述

慢速交叉模式

在该模式下,采样周期必须要小于14个ADC周期
仅用于规则通道,不能使用注入通道的自动注入
在这里插入图片描述
在交叉模式下,不能有注入通道的外部触发产生,包括自动注入模式下

双ADC模式-快速交叉模式-DMA-外部触发demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

ADC1和ADC2都是单次转换,ADC1的规则通道的外部触发为定时器3的TRGO,定时器3的TRGO事件来源于更新事件,每500ms更新一次,即ADC每500ms转换一次

ADC1开启2个规则通道,转换序列为:通道0(PA0),通道1(PA1)
ADC2开启2个规则通道,转换序列为:通道0(PA0),通道1(PA1)

ADC1和ADC2设置相同通道的转换时间都为1.5个ADC周期。如,在规则通道上,ADC1和ADC2的通道0转换时间相同。

在规则通道每个通道转换完成之后,DMA负责将转换的数据从ADC_DR寄存器传输到用户指定的目的地址

开启ADC1的规则通道转化完成中断。

转换完成之后在规则通道转换完回调函数中串口输出转换的数据

STM32CubeMX配置
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
ADC初始化函数
在这里插入图片描述
ADC1初始化函数
在这里插入图片描述
规则转换完中断回调函数
在这里插入图片描述

工程文件下载链接

交替触发模式

在这里插入图片描述
在这里插入图片描述

混合的规则/注入同步模式、混合的同步规则+交替触发模式、混合同步注入 + 交叉模式

这些模式自行参考用户手册,以后随缘添加demo工程

模拟看门狗

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

温度传感器/VREFINT内部通道

温度传感器和通道ADC1_IN16相连接,内部参照电压VREFINT和ADC1_IN17相连接。可以按注入或规则通道对这两个内部通道进行转换。
注意: 温度传感器和VREFINT只能出现在主ADC1中。

内部参照电压VREFINT即VREF的电压值
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

ADC-温度传感器 + VREFINTdemo

采用STM32F103C8T6单片机,KeilMDK5.32版本

ADC1采样温度和VREFINT数据。
串口输出相关信息

STM32CubeMX配置
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
ADC1时钟为12MHz,温度采样建议值为17.1us,则设置采样周期为 17.1 * 12 = 205.2个ADC周期,最接近的为239.5ADC周期

ADC1初始化函数
在这里插入图片描述
转换传输完成中断回调函数(由DMA传输完成中断调用该函数)
在这里插入图片描述
工程文件下载链接

  • 9
    点赞
  • 92
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值