前言:蓝桥杯扩展板中ADC按键与主板中模拟输入1均为ADC2,所以需要进行ADC的多通道采集。目前已经完成了查询模式的数据采集且无误,但是对于多通道DMA模式却遇到了一些问题。首先先把查询模式的做法写出,然后将遇到的问题记录下。
(1)查询模式(无误):
一、CubeMX配置:
解释:将对应的PB15与PA5的ADC使能。配置采集通道数Number Of Conversion为2,并确保Rank为不同的通道。配置到通道采集数后启用间断模式Discontinuous Conversion Mode,该模式会使每次使能ADC(HAL_ADC_Start(&hadc1))时按照Rank依次进行转换,并将转换完成的值放入寄存器中。所以在进行数据读取时应使能一次读取一次,这时读到的数据即为不同通道的ADC值。
二、代码部分:
校准ADC:
HAL_ADCEx_Calibration_Start(&hadc2);
轮寻读取ADC寄存器中的数据:
uint16_t Value[2]={0}; //先创建数组来保存ADC结果
for(int i=0;i < 2;i++){
HAL_ADC_Start(&hadc2); //使能一次ADC
HAL_ADC_PollForConversion(&hadc2,10); //轮询等待ADC转换完成
Value[i]=HAL_ADC_GetValue(&hadc2); //将两个通道的采样值存在数组里
}
此时DAC的值已按照Rank中的顺序存入Value中。
(2)DMA模式(有问题):
问题:使用DMA模式读取多通道ADC的值时,发现数据并不会从Value[0]进行存储,而是从Value[1]开始。操作如下:
一、CubeMX配置:
DMA配置:
解释:打开DMA通道,并选择循环(Circular)模式,由于ADC寄存器为16位,故数据长度均选择半字(Half Word)。
ADC配置:
解释:根据通道数配置Number Of Conversion并检查Rank。由于使用DMA并且是多通道,故使能转换模式Continuous Conversion Mode。
二、代码部分:
uint16_t Value[3]; //创建数组接收数据
HAL_ADCEx_Calibration_Start(&hadc2); //校准ADC
HAL_ADC_Start_DMA(&hadc2,(uint32_t *)Value,3); //启动ADC的DMA模式
串口输出查看Value的值:
printf("V1=%d ",Value[0]);
printf("V2=%d ",Value[1]);
printf("V3=%d ",Value[2]);
printf("\n");
结果如下:
初步认为是因为打开DMA时强制转换指针类型导致,将类型为uint16_t的Value指针转换为uint32_t,又因为ADC数据配置为右对齐,故前16位数据为0。因为DMA数据长度选择的是半字(16位),故接下来指针移动16位,不影响接下来的数据。所以呈现出来的现象就是Value[0]一直被赋值为0,数据从第二位开始。然而其他教程中并未提及该情况。
如有想法,欢迎评论区讨论!后续如果找到了问题所在,我会进行更新。