坐骑图鉴

一、ADC 外设使用原理

1. ADC 基本特性

分辨率与数值范围:

STM32 的 ADC 为 12 位精度,满量程对应数值为 212=4096。输入电压与转换值的关系为:电压值=4096ADC 值×3.3V​

例如,当 ADC 值为 4096 时,对应输入电压为 3.3V。

转换时间计算:

总转换时间 Tconv​ 由采样时间和固定周期组成:Tconv​=采样时间+12.5个时钟周期

若 ADC 时钟频率为 14 MHz,采样时间设为 1.5 周期,则:Tconv​=(1.5+12.5)×14MHz1​=1μs采样时间与精度的权衡:采样时间越长,精度越高,但转换速率越低。

时钟配置:

ADC 时钟(ADCCLK)需通过 APB2 时钟分频得到,且最高不超过 14 MHz(否则精度下降)。例如,APB2 时钟为 72 MHz 时,可通过 6 分频(/6)得到 12 MHz 的 ADCCLK。

2. 数据存储与对齐方式

寄存器结构:ADC 转换结果存储在 16 位寄存器中,支持右对齐和左对齐:

右对齐:低 12 位为有效数据(D11~D0),高 4 位补 0,范围为 0~4095。左对齐:高 12 位为有效数据(D15~D4),低 4 位补 0,适用于需要移位运算的场景。

多通道采集:

规则组:常规转换通道,支持扫描模式(依次转换多个通道)。注入组:优先级高于规则组,用于紧急通道(如中断触发的转换)。

二、ADC 中断原理

1. 中断触发条件

转换完成事件(EOC):单个通道或规则组转换完成后触发中断。注入转换完成事件:注入组通道转换完成后触发。溢出事件:转换数据未及时读取导致溢出时触发。

2. 中断处理流程

使能中断功能:通过 HAL_ADC_Start_IT() 启动中断模式。注册回调函数:

HAL_ADC_ConvCpltCallback():转换完成时调用。HAL_ADC_ErrorCallback():错误发生时调用。

中断服务函数:STM32 自动调用 HAL_ADC_IRQHandler(),该函数会触发注册的回调函数。

3. 与 DMA 结合使用

DMA 中断:当 DMA 搬运完指定数量的数据时,触发 DMA 传输完成中断(如 DMA1_FLAG_TC1)。中断优化:在 DMA 中断中仅置位标志位(如 adc_complete_flag),主程序通过标志位处理数据,避免中断服务函数耗时过长。

三、ADC 使用方法总结

1. 初始化配置步骤

使能时钟:

使能 ADC 对应总线时钟(如 APB2 时钟)和 GPIO 时钟。示例:RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

GPIO 配置:

将输入引脚设为模拟输入模式(如 GPIO_Mode_AIN)。

ADC 基础配置:

设置分辨率(12 位)、数据对齐方式(右对齐为主)。配置转换模式:

单次转换:转换一次后停止,需软件重新触发。连续转换:持续循环转换,适用于实时采集。

启用扫描模式(多通道时),设置规则组通道数及采样时间。

时钟与预分频:

通过 ADC_Prescaler 配置分频系数,确保 ADCCLK ≤ 14 MHz。

中断 / DMA 配置(可选):

中断模式:启用 ADC 中断,注册回调函数。DMA 模式:配置 DMA 通道、传输方向(外设到内存)、数据长度等。

2. 数据采集方式

方式特点适用场景轮询(Polling)阻塞式等待转换完成,通过 HAL_ADC_PollForConversion() 查询状态。简单单通道采集,对实时性要求不高。中断(IT)非阻塞式,转换完成后触发中断,通过回调函数处理数据。多任务系统,需及时响应转换结果。DMA非阻塞式,自动搬运数据到内存,支持连续采集和环形缓冲区。高速多通道采集,大数据量场景。

3. 关键函数

启动转换:

轮询:HAL_ADC_Start(&hadc1);中断:HAL_ADC_Start_IT(&hadc1);DMA:HAL_ADC_Start_DMA(&hadc1, pData, Length);

读取数据:HAL_ADC_GetValue(&hadc1);(轮询 / 中断模式)。DMA 配置:设置外设地址(如 ADC1_DR_Address)和内存地址,启用连续传输模式。

四、应用示例

示例 1:单通道轮询采集(温度测量)

c

运行

// 声明变量

uint16_t AD_Value = 0;

float temperature = 0.0f;

// 主循环

while (1) {

HAL_ADC_Start(&hadc1); // 启动 ADC 转换

HAL_ADC_PollForConversion(&hadc1, 50); // 等待转换完成(超时 50ms)

if (HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC)) {

AD_Value = HAL_ADC_GetValue(&hadc1); // 读取转换值

// 温度计算(假设传感器公式:T = (1.43 - V)/0.0043 + 25)

temperature = (1.43f - (AD_Value * 3.3f / 4096)) / 0.0043f + 25.0f;

printf("Temperature: %.1f°C\r\n", temperature);

}

HAL_Delay(1000); // 延时 1s

}

示例 2:多通道 DMA 采集(规则组 2 通道,环形缓冲区)

初始化配置:

启用扫描模式,规则组通道数设为 2,DMA 配置为连续传输、环形模式。定义内存缓冲区:uint16_t ADC_Buffer[256][2] = {0};(256 组数据,每组 2 通道)。

DMA 启动代码:

c

运行

HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADC_Buffer, sizeof(ADC_Buffer)/sizeof(uint16_t));

DMA 中断处理:

c

运行

void DMA1_Channel1_IRQHandler(void) {

if (DMA_GetITStatus(DMA1_IT_TC1)) { // 传输完成中断

DMA_ClearITPendingBit(DMA1_IT_TC1);

adc_dma_complete = 1; // 置位标志位

}

}

主程序处理数据:

c

运行

while (1) {

if (adc_dma_complete) {

adc_dma_complete = 0;

// 处理 ADC_Buffer 中的数据(如滤波、计算平均值等)

}

}

五、注意事项

时钟频率限制:确保 ADCCLK ≤ 14 MHz,否则精度下降。采样时间设置:多通道采集时,每个通道需单独设置采样时间,长采样时间可提高精度。DMA 与中断协同:DMA 中断仅用于标志位通知,数据处理应在主循环中完成,避免中断阻塞。电源与滤波:模拟输入引脚需加滤波电容(如 0.1 μF),减少噪声干扰。

通过合理配置 ADC 时钟、采样时间及中断 / DMA 模式,可灵活适配不同采集需求,实现高精度、高效率的数据采集。