STM32 ADC1和ADC2同时多通道获取模拟电压(HAL库)_stm32多路adc采集电压
当前很多传感器都是通过ADC模拟电压来传输数据的。所以,当我们同时使用多个传感器时就需要使用ADC的多个通道来获取所有传感器的数据。因为引脚口的占用问题,我们可能会需要ADC1和ADC2同时来多通道获取数据,下面是使用方法及代码。(使用的是STM32G431RBT6)
一、CubeMX配置
(这里不在赘述。直接上adc配置以及讲解)
(这里我只详细介绍ADC1的配置界面,ADC2的配置同理,一样的步骤)
1、ADC配置
在这里的47.5Cycles代表着采样时间,注意:采样时间太小会导致采样时间不准确,越大采样越精确,但是会影响你的采样速度。我选用的是47.5Cycles。
2、DMA配置:
二、Keil 代码部分
配置好相应时钟和文件路径后,就可以生成代码了。
新建my_adc.c和my_adc.h
1、my_adc.h
#define adc_max 40#define adc_max2 40extern uint16_t My_adcData[adc_max];extern uint16_t My_adcData2[adc_max2];struct adcValue_type{uint16_t value1;uint16_t value2;uint16_t value3;uint16_t value4;uint16_t value5;uint16_t value6;uint16_t value7;uint16_t value8;};extern struct adcValue_type adcValue;void ADC_dispose (void);void ADC_dispose2(void);
2、my_adc.c
uint16_t My_adcData[adc_max]={0};uint16_t My_adcData2[adc_max2]={0}; //这里一定要定义的uint16_t 的数据,因为我们在Cube选择的就是Half Word 类型的数据struct adcValue_type adcValue ;/* USER CODE BEGIN 1 *//**adc数据处理*每通道的数据进行10次获取,数据的每一组的第一个和最后一个不要,并且将剩下的进行取平均值**/void ADC_dispose (void){// 函数减速,用来防止程序阻塞static uint32_t ADC_Tick1;if(uwTick - ADC_Tick1 < 5)return;ADC_Tick1 = uwTick;// 函数减速结束adcValue .value1=adcValue .value2=adcValue .value3=adcValue .value4 =0;HAL_ADC_Start_DMA(&hadc1, (uint32_t *)My_adcData,adc_max);//因为你选择的软件触发,所以每次采集都需要开启一次static uint8_t i;for(i=1;i<=8;i++){ //遍历8次,进行滤波adcValue .value1 += My_adcData[0+4*i]*330/4096;adcValue .value2 += My_adcData[1+4*i]*330/4096;adcValue .value3 += My_adcData[2+4*i]*330/4096;adcValue .value4 += My_adcData[3+4*i]*330/4096;}adcValue .value1 = adcValue .value1/8 ;adcValue .value2 = adcValue .value2/8 ;adcValue .value3 = adcValue .value3/8 ;adcValue .value4 = adcValue .value4/8 ; //函数消除干扰,舍去微小电压if(adcValue .value1<5)adcValue .value1=0;if(adcValue .value2<5)adcValue .value2=0;if(adcValue .value3<5)adcValue .value3=0;if(adcValue .value4<5)adcValue .value4=0;}/* USER CODE END 1 *//* USER CODE BEGIN 2 */void ADC_dispose2(void){static uint32_t ADC_Tick2;if(uwTick - ADC_Tick2 < 10)return;ADC_Tick2 = uwTick;adcValue .value5=adcValue .value6=adcValue .value7=adcValue .value8 =0;HAL_ADC_Start_DMA(&hadc2, (uint32_t *)My_adcData2,adc_max2);static uint8_t m;for(m=1;m<=8;m++){ //遍历8次,进行滤波adcValue .value5 += My_adcData2[0+4*m]*330/4096;adcValue .value6 += My_adcData2[1+4*m]*330/4096;adcValue .value7 += My_adcData2[2+4*m]*330/4096;adcValue .value8 += My_adcData2[3+4*m]*330/4096;}adcValue .value5 = adcValue .value5/8 ;adcValue .value6 = adcValue .value6/8 ;adcValue .value7 = adcValue .value7/8 ;adcValue .value8 = adcValue .value8/8 ;if(adcValue .value5<5)adcValue .value5=0;if(adcValue .value6<5)adcValue .value6=0;if(adcValue .value7<5)adcValue .value7=0;if(adcValue .value8<5)adcValue .value8=0;}/* USER CODE END 2 */
3、main.c中:初始化
HAL_ADCEx_Calibration_Start(&hadc1,ADC_SINGLE_ENDED);HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED); HAL_ADC_Start_DMA(&hadc1,(uint32_t *)My_adcData,adc_max);HAL_ADC_Start_DMA(&hadc2,(uint32_t *)My_adcData2,adc_max2);
while(1)里面:
ADC_dispose();
ADC_dispose2();
这里初始化我建议大家也封装一下,这样可以减少main.c的代码行数,方便修改。
三、获取ADC
这样就完成ADC读取了,我们需要知道ADC的值就直接读取adcValue .value1、adcValue .value2、adcValue .value3、adcValue .value4、adcValue .value5、adcValue .value6、adcValue .value7、adcValue .value8的数值就可以了。
以上就是双ADC多通道获取的方法,仅仅供大家参考一下,如有错误,还希望大家指出,一起进步!