>ADC采样配置学习
一.ADC采样原理及运行机制
Datasheet:MCU 片上集成了 12 位逐次逼近式模数转换器模块(ADC),可以采样来自于 16 个外部通道和 2 个内部通道上的模拟信号。这 18 个 ADC 采样通道都支持多种运行模式,采样转换后,转换结果可以按照最低有效位对齐(LSB)或最高有效位对齐(MSB)的方式保存在相应的数据寄存器中。片上的硬件过采样机制可以通过减少来自 MCU 的相关计算负担来提高性能。
> 让我们用生活中的例子来形象地理解这个 12 位逐次逼近式ADC模块。
场景设定:厨房里的“智能秤”
想象你有一个 智能厨房秤,它的功能类似 ADC 模块:
任务:测量食材重量(类似测量电压)。
精度:能精确到 1 克(类似 12 位分辨率,把电压分成 4096 份)。
量程:最大能称 5 公斤(类似 ADC 的参考电压范围,比如 0~3.3V)。
1. 逐次逼近式工作原理:猜数字游戏
假设你想猜一个 0~4095 之间的数字(对应 12 位精度),但只能通过“是或否”提问:
第一问:数字是否 ≥ 2048?
如果“是”,记录最高位为 1,否则为 0。
第二问:根据上一结果,调整范围再问(比如若第一次是 1,则问是否 ≥ 3072?)。
重复 12 次,逐步缩小范围,最终锁定精确值。
这就是 逐次逼近式 ADC 的核心:通过二进制搜索逼近真实电压值,每次确定 1 位,12 次完成转换。
2. 18 个通道:多路输入接口
你的智能秤有 18 个传感器接口:
16 个外部接口:连接不同的食材容器(类似外部 ADC 通道,比如 PA0~PA7 等引脚)。
例如:接口1接面粉,接口2接糖,接口3接盐...
2 个内部接口:监控秤自身的温度或电池电压(类似内部通道,如芯片温度传感器、参考电压)。
通过切换接口,你可以测量不同来源的重量(电压),而无需重新接线。
3. 数据对齐方式:书籍排版
转换结果保存在寄存器中,有两种对齐方式:
LSB(最低有效位对齐):
就像一本书的页码标注在右下角(低位对齐),例如:
值 = 0x0ABC (十六进制)
LSB对齐存储:0xBC 0x0A (低字节在前)
MSB(最高有效位对齐):
就像页码标注在左上角(高位对齐),例如:
值 = 0x0ABC
MSB对齐存储:0x0A 0xBC (高字节在前)
> 对齐方式影响数据解析的便捷性,需根据需求选择(类似阅读习惯左对齐或右对齐)。
4. 运行模式:工作方式选择
ADC 支持多种运行模式,就像智能秤的称重模式:
单次模式:按一次按钮,称一次重量(单次转换)。
连续模式:持续监测重量变化(连续转换)。
扫描模式:自动轮流称所有食材(多通道扫描)。
总结:ADC 就像智能厨房秤
逐次逼近:通过“猜数字”快速锁定精确值。
多通道:支持 16 种食材 + 2 种自检(外部 + 内部)。
对齐方式:数据存储的排版规则(LSB/MSB)。
12 位精度:能区分 4096 种不同的重量(电压)。
============================================================================================================
二、ADC采样配置过程
- 配置GPIO口
- 设置GPIO口模拟输入模式
- 选择物理CHx(外部采用通道), 对应采样通道。
- 配置采样端口ADC初始化
- 初始化ADC模块,设置相关参数
- 分辨率:12位(0-4095)。
- 对齐方式:选择LSB或MSB对齐。
- 采样时间:根据输入频率选择合适采样时间,避免信号失真。
- 配置工作方式:单次、连续、扫描。
- 设置中断频率
- 配置定时器触发ADC采样,设置中断频率。例如19.2KHz中断意味每秒采19200次。
- 确保中断频率满足奈奎斯特采样定理(采样频率大于信号频率的两倍)。
- 读取采样数据
- 在中断服务函数程序或轮询中读取ADC采样值。
*配置过程
ADC常规初始化
* 设置分频系数
rcu_adc_clock_config();
* 使能时钟
rcu_periph_clock_enable(RCU_ADC0);
ADC_Driver_ADCx_Initial(PR_ADC0);
// 双ADC并行
// 扫描模式
// 禁用连续模式,表示每次触发后仅采样一次。
// 右对齐
// 启用DMA功能
* ADC触发源专用初始化
配置SHRTIMER(高精度时钟源)
* ADC常规通道初始化
配置前关闭ADC
ADC_Driver_ADCx_Disable(PR_ADC0); //adc_disable(ADCx);
设置rank,即需要ADC转换的通道数量
adc_channel_length_config(ADCx, ADC_REGULAR_CHANNEL, SequencerNbRanks);
*作用:DC可以采样多个通道,配置通道序列的长度(即通道数量)决定了ADC在一次触发中需要采样的通道个数。
例如,如果设置长度为3,则ADC会依次采样3个通道。
应用场景:当需要采集多个传感器信号时(如温度、电压、电流等),可以通过配置通道序列长度来实现多通道采样。
* GPIO 初始化
GPIO_Driver_Input_Initial
ADC_Driver_Config_Rankx_Channel
*中断读取数据
通过DMA读取通道数据,在中断中进行8次平均值计算,并对外进行赋值运算。
============================================================================================================
三、ADC进阶知识

19.2KHz的中断频率内读取采样数据

AD值4095代表什么?
采样频率是多高?电池电流
对于95KHz的频率能不能采到?
对于这个图像如何解释?


=======================================================================================================
知识再回顾
再次配置ADC时遇到新的问题,有新的解决思路
1、使用芯片STM32G0B1进行配置ADC,原本添加6路ADC+5路新ADC。但该芯片最大使用可配置RANK为8.进行了再一波ADC学习。
ADC配置中的扫描模式:一次可以读取多通道并进行保存数值。存在多种配置方式。
1. 不扫描模式:表示一次只读取一个通道,且读完结束产生EOC中断。
2. 全序列扫描模式:表示每个通道和RANK都可以自己配置,该模式最多RANK为8.即分配8个采样先后顺序。
3. 不全序列扫描模式:单向可配置向前扫描或者向后扫描,但是根据硬件引脚划分,不可变更。
问题点:本次配置采样点不连续且大于8。
1.使用不扫描模式,需要每次扫描完重新配置一次RANK1对应的采用通道。
2.使用全序列模式,需要分两次进行扫描,且中途需要重新分配扫描通道,将未扫描的channels配置在可rank范围内。
3.使用不全序列扫描模式:需要应用层调用时完全接收通道。
最终使用方案1:
添加代码
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; // 启用扫描模式,允许多通道转换
uint32_t ADCReadChannel(uint32_t channel)
{
ADC_ChannelConfTypeDef sConfig = {0};
// 配置采样通道
sConfig.Channel = adc_channels[i];
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
return 0xFFFF; // 错误码
}
// 启动转换
if (HAL_ADC_Start(&hadc1) != HAL_OK)
{
return 0xFFFF;
}
// 等待转换完成(轮询)
if (HAL_ADC_PollForConversion(&hadc1, 10) != HAL_OK)
{
HAL_ADC_Stop(&hadc1);
return 0xFFFF;
}
// 读取结果
uint32_t value = HAL_ADC_GetValue(&hadc1);
return value;
}
加粗
- 小标题
- 备注
===========
浙公网安备 33010602011771号