>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采样配置过程

  1. 配置GPIO口
    • 设置GPIO口模拟输入模式
    • 选择物理CHx(外部采用通道), 对应采样通道。
  2. 配置采样端口ADC初始化
    • 初始化ADC模块,设置相关参数
    • 分辨率:12位(0-4095)。
    • 对齐方式:选择LSB或MSB对齐。
    • 采样时间:根据输入频率选择合适采样时间,避免信号失真。
    • 配置工作方式:单次、连续、扫描。
  3. 设置中断频率
    • 配置定时器触发ADC采样,设置中断频率。例如19.2KHz中断意味每秒采19200次。
    • 确保中断频率满足奈奎斯特采样定理(采样频率大于信号频率的两倍)。
  4. 读取采样数据
    • 在中断服务函数程序或轮询中读取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进阶知识

img

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

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

=======================================================================================================

知识再回顾

再次配置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;
}

加粗

  1. 小标题
  • 备注
    ===========

posted on 2025-05-24 17:23  Yanron  阅读(181)  评论(0)    收藏  举报

导航