STM32 HAL库ADC多通道DMA扫描模式:采样顺序与数据对齐的配置陷阱与实战
一、原理讲解:扫描模式与DMA的协作机制
在STM32中,ADC多通道采集通常采用扫描模式(Scan Mode)配合DMA传输,以避免CPU频繁中断。其核心机制如下:
-
扫描模式:ADC按预设的规则组序列依次转换多个通道。序列顺序由
ADC_RegularChannelConfig()中的Rank参数决定(Rank 1最先转换)。 -
DMA请求:每次转换完成后,ADC产生DMA请求,将转换结果从
ADC_DR寄存器搬运到用户指定的内存数组。 - 数据对齐:ADC结果可配置为左对齐或右对齐(12位分辨率下,右对齐时数据位于低12位,左对齐时位于高12位)。
关键陷阱:许多开发者误以为DMA搬运顺序与通道编号一致,或忽略数据对齐导致数值错误。实际上,DMA搬运顺序严格遵循规则组的Rank顺序,且数据对齐方式直接影响读取值的解析。
二、CubeMX配置步骤
-
使能ADC:选择ADC1,勾选
Scan Conversion Mode,Continuous Conversion Mode根据需求选择(单次或连续)。 -
配置规则组:在
Rank列表中按顺序添加通道,例如Rank1=Channel0,Rank2=Channel1,Rank3=Channel4。 -
使能DMA:在DMA Settings中添加ADC1的DMA请求,模式为
Circular或Normal,数据宽度为Half Word(16位)。 -
数据对齐:在ADC参数设置中,
Data Alignment选择Right alignment(推荐)或Left alignment。 - 生成代码:确保HAL_ADC_Start_DMA()在初始化后调用。
三、完整代码示例
以下代码实现3个通道(IN0、IN1、IN4)的连续扫描+DMA采集,结果存入数组adc_values[3]。
#include "main.h"
ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;
uint16_t adc_values[3]; // 存放3个通道的转换结果
void ADC_Init(void)
{
// 1. ADC时钟与GPIO初始化(略,由CubeMX生成)
// 2. ADC参数配置
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; // 右对齐
hadc1.Init.NbrOfConversion = 3;
HAL_ADC_Init(&hadc1);
// 3. 配置规则组通道顺序(Rank 1 -> 2 -> 3)
ADC_ChannelConfTypeDef sConfig = {0};
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_28CYCLES;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = 2;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = 3;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
// 4. 启动DMA传输
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_values, 3);
}
// DMA转换完成回调(可选)
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if (hadc->Instance == ADC1) {
// adc_values[0]对应Rank1(IN0),[1]对应Rank2(IN1),[2]对应Rank3(IN4)
// 用户数据处理
}
}
四、注意事项与陷阱规避
-
采样顺序陷阱:DMA数组索引与Rank顺序一一对应,而非通道编号。例如Rank1=IN4时,
adc_values[0]是IN4的结果。务必在代码注释中明确映射关系。 - 数据对齐陷阱:若配置为左对齐,12位结果位于高12位,直接读取会得到错误值。建议统一使用右对齐,或读取后右移4位(左对齐时)。
-
DMA传输宽度:必须设置为
Half Word(16位),否则可能因字节对齐问题导致数据错位。 -
规则组长度:
NbrOfConversion必须与Rank数量一致,否则DMA搬运长度错误。 -
连续模式与DMA循环:若使用
ContinuousConvMode+DMA Circular,数组会不断被覆盖,需确保数据处理速度跟得上采样率。 -
过采样与校准:多通道扫描时,建议在初始化后执行
HAL_ADCEx_Calibration_Start(),并注意采样时间足够长(尤其高阻抗信号源)。
通过理解扫描序列与DMA的映射关系,并正确配置数据对齐,可避免绝大多数多通道ADC采集的“数据错位”问题。实际项目中,建议用已知电压源验证每个通道的映射顺序,确保万无一失。
暂无评论,来抢沙发~