STM32学习笔记,双ADC_DMA同步采集(CUBEMX+HAL+过采样)

双ADC同步采集可以节省一半时间
CUBEMX配置ADCSTM32学习笔记,双ADC_DMA同步采集(CUBEMX+HAL+过采样)_第1张图片
STM32学习笔记,双ADC_DMA同步采集(CUBEMX+HAL+过采样)_第2张图片
STM32学习笔记,双ADC_DMA同步采集(CUBEMX+HAL+过采样)_第3张图片
STM32学习笔记,双ADC_DMA同步采集(CUBEMX+HAL+过采样)_第4张图片


void Read_adc( void )
{

//dma方式*****************************************
    uint16_t ad1[20],ad2[20];
    AdcDMA_flag = 0;
    HAL_ADCEx_MultiModeStart_DMA(&hadc1, ADC_Value, 18);//启动多通道,双ADC同步采集DMA模式,ADC1在低16位,ADC2在高16位

    while(AdcDMA_flag == 0)  //因为要配合DAC进行采集,这里用用单次阻塞式采集,
    {
        delay_us(1);
    }
    /*******************************************
    双ADC同步DMA采样,各采样18次,去除最高和最低
    保留16次采样,右移2位得到14Bit采样值
    ********************************************/

    for (i=0 ; i< 18; i++) {  //分离提取ADC中各通道值 ,取18个
        ad1[i] = ADC_Value[i];
        ad2[i] = ADC_Value[i]>>16;
//        printf("No.%d= %d, %d\r\n",i,ad1[i],ad2[i]);
    }
    uint32_t   total_ad1 = 0, ad1_max = 0, ad1_min = 4095;
    uint32_t   total_ad2 = 0, ad2_max = 0, ad2_min = 4095;

    for ( i = 0;  i < 18; i++)  //累加18次,去除最大和最小值,相当于累加16次
    {
        
        if (ad1_max < ad1[i]) 		 ad1_max = ad1[i];
        if (ad2_max < ad2[i])		 	 ad2_max = ad2[i];

        if (ad1[i] < ad1_min)      ad1_min = ad1[i];
        if (ad2[i] < ad2_min)      ad2_min = ad2[i];
        total_ad1 += ad1[i];
        total_ad2 += ad2[i];
//       printf("total_1=%d,total_2=%d\r\n",total_1,total_2);
    }

    total_ad1 = (total_ad1 - ad1_min - ad1_max) ;
    total_ad2 = (total_ad2 - ad2_min - ad2_max) ;
    //    printf("max= %d min= %d\r\n",ad1_max,ad1_min);
//       printf("total_16= %d, total_2=%d\r\n",total_1,total_2);

//计算过采样14b的值
//    AdcDMA_flag = 0;
    V_ADC14b= (total_ad1)>>2;
    I_ADC14b= (total_ad2)>>2;
}

ADC初始化后要先校准

    HAL_ADCEx_Calibration_Start(&hadc1,ADC_SINGLE_ENDED); //校准ADC1
    HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED); //校准ADC2

在While(1)中读取ADC

    uint32_t  time = HAL_GetTick(); //同步时间
    while (1)
    {
        if(HAL_GetTick()-time >=1000)
        {
            time = HAL_GetTick(); //同步时间
            Read_adc();
            printf("V_ADC=%d,I_ADC=%d\r\n",V_ADC14b,I_ADC14b);
        }
        /* USER CODE END WHILE */
        /* USER CODE BEGIN 3 */
    }

电压/电流差分采样电路
STM32学习笔记,双ADC_DMA同步采集(CUBEMX+HAL+过采样)_第5张图片
开始是使用STM32F303内部运放进行差分采样,结果发现读数跳动较大,无输入时也有底数,且OPAMP之间有串扰,改用外置运放后读数相对稳定,无输入时读数为0,实测ADC读数跳动在3~4个字,注意这里使用了14位过采样,不使用过采样的话读数会更稳定。
完整程序下载:
https://download.csdn.net/download/u013348132/12034532

你可能感兴趣的:(STM32学习笔记,双ADC_DMA同步采集(CUBEMX+HAL+过采样))