电控--ADC(模数转换器)
ADC的理论讲解,Cube操作,keil代码示例
理论知识
一、数字信号 vs 模拟信号
1. 模拟信号(Analog Signal)
- 定义:连续变化的信号,可以取任意值。例如:温度、声音、光线强度等自然界的信号。
- 特点:
- 信号是连续的(比如电压从0V到3.3V平滑变化)。
- 容易受干扰(如噪声、电磁干扰)。
- 例子:麦克风输出的音频信号、温度传感器的输出电压。
2. 数字信号(Digital Signal)
- 定义:离散的信号,只有两个状态:高电平(1)和低电平(0)。
- 特点:
- 信号是离散的(比如只有0V和3.3V两种状态)。
- 抗干扰能力强,适合计算机处理和传输。
- 例子:开关的开关状态、UART通信的数据。
3. 为什么需要ADC?
- 自然界中大多数信号是模拟的(如温度、压力),但计算机只能处理数字信号。
- **ADC(模数转换器)**的作用就是将模拟信号转换为数字信号,供单片机处理。
二、模数转换器ADC的基本原理
1. ADC的核心步骤
- 采样(Sampling):以固定频率采集模拟信号的瞬时值。
- 采样率:每秒采样的次数(例如1kHz)。
- 奈奎斯特定理:采样率必须≥信号最高频率的2倍,否则会失真。
- 量化(Quantization):将连续的模拟值转换为离散的数字值。
- 分辨率:ADC的位数(如12位ADC的分辨率为 2^12=4096 级)。
- 例如:3.3V参考电压下,12位ADC的最小分辨电压为 3.3V / 4096 ≈ 0.8mV。
- 编码(Encoding):将量化后的值转换为二进制数字。
ADC计算过程:
三个参量:1.ADC位数 2.参考低电压Vref- 3.参考高电压Vref+
result = (V - Vref-)/(Vref+ - Vref-)*(2^x - 1)

#### 2. ADC的关键参数
- 分辨率:位数越高,分辨率越强(STM32常用12位ADC)。
- 精度: 性能越高,波动越小,精度越高。
- 转换时间:完成一次转换所需的时间(影响最大采样率)。
- 输入范围:ADC能测量的电压范围(如0~3.3V)。
实际应用注意点
- 抗干扰:模拟信号易受干扰,需加滤波电路(如RC低通滤波)。
- 参考电压稳定性:VREF+的波动会直接影响ADC精度。
- 采样时间:较短的采样时间可能导致误差,需根据信号源阻抗调整。
硬件电路连接
本实验采用ADC1对应的IN4引脚为PA4
- PA4连接学生电源正极
- GND连接学生电源负极
关于学生电源 - 建议输出电压不要超过3.3V
- 如果没有学生电源,用3.3V以内的干电池亦可
- 如果用到了降压稳压模块,请确保稳压模块的质量足够可靠,防止电压尖峰将MCU烧坏
工程配置
CubeMX中
-
选择MCU
-
配置RCC的HSE为外部晶振
-
配置时钟树HSE输出主频
-
Debug选项选择serial wire
-
工程管理中修改工程与路径,注意不要有中文等字符
-
代码生成到单独头文件

配置ADC1
将ADC1的IN4使能 -
ADCs_Common_Settings
- Mode(扫描模式):独立模式, 如果要和其他ADC(如ADC2、ADC3)等配合则需要交替工作模式
-
ADC_Settings
-
Clock Prescaler(时钟预分频):从PCLK2获取,受限于硬件性能,必须在36MHz以内,输入频率通过分频后成为ADC的时钟主频
-
Resolution(分辨率):12位即可(需要15个ADC主频周期的时间来完成一轮采集)
-
Data Alignment(数据对齐):选择右对齐即可,12位需要两字节(16Bit),右对齐相当于ADC真实的数值,左对齐相当于ADC真实数值左移四位,即16倍的关系。
-
Scan Conversion(扫描转换模式):使能会采集ADC所有的通道,否则仅按顺序采集一个通道

- 如上图所示,如果使能扫描转换模式则会采样4、5、6、7四个通道,否则一次采样只会采集一个通道。
-
Continuous Conversion Mode(连续转换模式):使能则可以在使能ADC时便自动开始采集,而非手动采集
-
Discontinuous Conversion Mode(间断采集模式):使能则可以在一轮采集完后暂停采集等待指令控制下一轮采集
ADC_Regular_Conversion Mode:配置ADC通道采集顺序等
另外的ADC转换策略,采用DMA,可以自动转换且对系统影响较小
- Cube中配置好采样通道,在原来的配置基础上进行操作更改
- 使能ADC对应的DMA通道,循环搬运,半字(2字节,16bit)转换
- 扫描转换模式使能
- 连续转换模式使能
- 间断采集模式禁用
- DMA连续请求使能
- 主程序只需在初始化后增加下述代码
- HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADC_Value,1);
- 第一个参量是ADC对应的外设地址
- 第二个参量是ADC值的地址
- 第三个参量是一个循环的采样数
代码编写
uint16_t ADC_Value;
while (1)
{
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1,50);
if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1),HAL_ADC_STATE_REG_EOC))
{
ADC_Value = HAL_ADC_GetValue(&hadc1);
HAL_Delay(500);
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
以下是对该段STM32 HAL库代码的逐行解析:
if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1),HAL_ADC_STATE_REG_EOC))
{
ADC_Value = HAL_ADC_GetValue(&hadc1);
HAL_Delay(500);
}
一、函数解析
-
HAL_ADC_GetState(&hadc1)
- 功能:获取ADC外设当前状态
- 参数:指向ADC句柄的指针(此处为
hadc1) - 返回值:ADC状态寄存器值(32位掩码)
-
HAL_IS_BIT_SET(state, flag)
- 功能:检测状态寄存器中指定标志位是否置位
- 参数:
state:状态寄存器值flag:待检测的标志位(此处为HAL_ADC_STATE_REG_EOC)
- 返回值:布尔值(1表示置位,0表示未置位)
-
HAL_ADC_GetValue(&hadc1)
- 功能:读取ADC数据寄存器(DR)的转换结果
- 参数:ADC句柄指针
- 返回值:12位ADC转换值(0-4095)
-
HAL_Delay(500)
- 功能:实现毫秒级阻塞延时
- 参数:延时时间(单位ms)
二、代码功能说明
-
状态检测:
- 检测
HAL_ADC_STATE_REG_EOC标志位(规则组转换完成标志) - 当规则通道转换完成时,该标志位自动置1
- 检测
-
数据读取:
- 当检测到转换完成标志后,读取ADC数据寄存器
- 读取操作会自动清除EOC标志位
-
延时控制:
- 每次读取后阻塞500ms(相当于2Hz采样率)
- 该延时会影响程序实时性
三、注意事项
-
标志位特性:
HAL_ADC_STATE_REG_EOC仅针对规则通道- 注入通道需使用
HAL_ADC_STATE_INJ_EOC
-
数据寄存器特性:
- ADC数据寄存器为32位,实际有效位取决于分辨率
- 12位模式下数据存储在低12位(DR[11:0])
-
延时问题:
- 在中断服务函数中禁止使用
HAL_Delay - 建议改用非阻塞方式(如定时器中断)
- 在中断服务函数中禁止使用
补充
Resolution(分辨率)参数解释
一、12位分辨率
- 表示ADC的量化精度为2^12=4096个等级
- 模拟输入电压将被转换为0~4095的数字值
- 例如当参考电压VREF+ = 3.3V时:
最小可分辨电压 = 3.3V / 4096 ≈ 0.8mV
二、15个ADC主频周期
指ADC转换过程需要的时间组成:
- 采样时间:15个ADC时钟周期(配置寄存器
SMPx设置) - 转换时间:
- 12位分辨率需要12.5个周期(固定值)
- 总周期数 = 15(采样) + 12.5(转换)= 27.5周期
计算公式
总转换时间 = (采样周期数 + 转换周期数) × ADC时钟周期
示例(当ADC时钟配置为14MHz时):
总时间 = 27.5 × (1/14MHz) ≈ 1.96μs
参数优化原则
- 采样时间↑ → 抗噪能力↑ → 转换速度↓
- 分辨率↑ → 精度↑ → 转换速度↓
- 高频信号建议使用较低分辨率+较短采样时间
若教眼底无离恨,不信人间有白头。 —辛弃疾
更多推荐



所有评论(0)