STM32F407 HAL库 ADC笔记

本文详细介绍了STM32F407的ADC特性,包括其3个12位ADC、19个复用通道、多种采样模式、数据存储方式和电压输入范围。还讨论了ADC的时钟、独立/双重/三重ADC模式,并提供了ADC转换的时间计算方法。此外,文章还涵盖了单次和连续转换模式、扫描和不连续采样模式的使用,以及数据管理中如何利用DMA。最后,通过实例展示了单通道和多通道ADC的配置和操作,以及实际运行效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

STM32F407 ADC简介

  • stm32f407系列有312位精度逐次趋近型ADC,每个ADC具有多达 19 个复用通道,可测量来自 16 个外部 源、两个内部源和 V B A T V_{BAT} VBAT 通道的信号。

  • 采样模式:单次、连续、扫描、不连续采样

  • 数据存储:左对齐或右对齐16位数据寄存器

  • ADC 输入范围: V R E F − V_{REF-} VREF <= V I N V_{IN} VIN <= V R E F + V_{REF+} VREF+

    • 正模拟参考电压输入 V R E F − V_{REF-} VREF
    • 负模拟参考电压输入 V R E F + V_{REF+} VREF+
  • ADC时钟ADCCLK:由APB2分频而来

  • 支持独立/双重/三重ADC模式

ADC框图

请添加图片描述

ADC电压输入范围

请添加图片描述

请添加图片描述
(开发板通过跳线帽将VREF+与VDDA相连)
(从原理图上得: V D D V_{DD} VDD = 3.3V)请添加图片描述

ADC通道

每个ADC有2个通道组:规则通道组及注入通道组

规则通道组最多 16 个转换,必须在 ADC_SQRx 寄存器中选择转换序列的规则通道及其顺序

注入通道组最多 4 个转换

  • 注入通道的转换可以打断规则通道的转换(相当于中断), 在注入通道被转换完成之后,规则通道才得以继续转换

请添加图片描述

  • 触发注入

    要使用触发注入,必须将 ADC_CR1 寄存器中的 JAUTO 位清零。

    1. 通过外部触发或将 ADC_CR2 寄存器中的 SWSTART 位置 1 来启动规则通道组转换。
    2. 如果在规则通道组转换期间出现外部注入触发或者 JSWSTART 位置 1,则当前的转换会复位,并且注入通道序列会切换为单次扫描模式。
    3. 然后,规则通道组的规则转换会从上次中断的规则转换处恢复。 如果在注入转换期间出现规则事件,注入转换不会中断,但在注入序列结束时会执行规 则序列。

    注意: 使用触发注入时,必须确保触发事件之间的间隔长于注入序列。例如,如果序列长度为 30 个 ADC 时钟周期(即,采样时间为 3 个时钟周期的两次转换),则触发事件的最小间隔不能小于 31 个 ADC 时钟周期。

    自动注入

    ​ 如果将 JAUTO 位置 1,则注入组中的通道会在规则组通道之后自动转换。这可用于转换最多由 20 个转换构成的序列,这些转换在 ADC_SQRx 和 ADC_JSQR 寄存器中编程。 在此模式下,必须禁止注入通道上的外部触发。 如果 CONT 位和 JAUTO 位均已置 1,则在转换规则通道之后会继续转换注入通道。

    注意: 不能同时使用自动注入和不连续采样模式

采样时间和转换时间

  • 总转换时间 = 采样时间 + 转换时间
  • 最小采样时间:3个周期
  • 转换时间 = 12周期
    • 例如:12位ADC,ADCCLK = 36MHz;则转换时间 t = 1 36 ∗ 1 0 6 ∗ 12 t =\frac{1}{36*10^6}*12 t=36106112

采样模式

单次转换模式

ADC仅执行一次转换

连续转换模式

ADC 结束一个转换后立即启动一个新的转换

扫描模式

此模式用于扫描一组模拟通道。

为组中的每个通道都执行一次转换。每次转换结束后,会自动转换该组中的下一 个通道

不连续采样

该模式可用于转换含有 n (n <= 8) 个转换的短序列,该短序列是在 ADC_SQRx 寄存器中选择的转换序列的一部分。可通过写入 ADC_CR1 寄存器中的 DISCNUM[2:0] 位来指定 n 的值。

出现外部触发时,将启动在 ADC_SQRx 寄存器中选择的接下来 n 个转换,直到序列中的所有转换均完成为止。

示例: n = 3,要转换的通道 = 0、1、2、3、6、7、9、10

​ 第 1 次触发:转换序列 0、1、2

​ 第 2 次触发:转换序列 3、6、7

​ 第 3 次触发:转换序列 9、10 并生成 EOC 事件

​ 第 4 次触发:转换序列 0、1、2

数据管理

使用DMA

在使能DMA模式后,每完成规则通道组中的一个通道的转换后,都会生成一个DMA请求。

进入实战

一、单通道 阻塞(轮询)模式

  • 不建议用阻塞模式进行多通道采集 通道序列可能出现问题(可打开不连续模式解决)
cubemx配置

请添加图片描述
请添加图片描述

添加代码
//main.c

/* USER CODE BEGIN PV */
float ADC_Value = 0;
/* USER CODE END PV */

while(1){
    /* USER CODE BEGIN 3 */
	ADC_Value  = get_adc_value_zuse(); //读取数据
	HAL_Delay(0);   //延时1ms
}
/* USER CODE END 3 */

/* USER CODE BEGIN 4 */
float get_adc_value_zuse(void){
	HAL_ADC_Start(&hadc1);  //开启ADC(阻塞模式)
	HAL_ADC_PollForConversion(&hadc1,50);   //查看规则通道组是否完成转换
	if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1),HAL_ADC_STATE_REG_EOC)){  //查看ADC状态是否为EOC
		return (float)HAL_ADC_GetValue(&hadc1)/4096.0*3.3;  //读取并处理数据
	}
	else return 0;
}
/* USER CODE END 4 */

运行效果

在开发板上用杜邦线将PB0与输出3.3V的I/O口相连

使用ST-Link调试,查看ADC_Value的值
在这里插入图片描述

二、多通道 ADC模式

多通道必须使用扫描模式

cubemx配置

在这里插入图片描述

请添加图片描述在这里插入图片描述

添加代码
main.c
/* USER CODE BEGIN PV */
uint16_t adc_value[40];
float ad_voltage[40];  
/* USER CODE END PV */

 /* USER CODE BEGIN 2 */
 HAL_ADC_Start_DMA(&hadc1,(uint32_t *)adc_value,40);  //开启ADC(DMA模式)
 /* USER CODE END 2 */
 
 /* USER CODE BEGIN 3 */
 uint16_t i;
 for(i = 0;i<40;i++){
 ad_voltage[i] = (float)adc_value[i]/4096.0*3.3;  //转换为实际电压
 HAL_Delay(0);
 /* USER CODE END 3 */
运行效果

使用ST-Link调试,查看ad_voltage数组的值
在这里插入图片描述

后记

感谢大家的阅读 如有不当或错误之处,欢迎指出

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值