CN / EN
CN / EN

提问

设计支持

您的项目私密技术问题如需获得一对一支持,请点击下方联系我们。

ADC差分与单通道采样数据不准 GR551x

今天加班吗

2025-09-26 15:40

你好,我有以下ADC采集的疑问需要解答

设计目标:采用ADC0、1实现差分采样,ADC4单通道采样,2Khz中断采集

设计难题:ADC0、1在无输入信号时,采样信号与ADC4一致,若单独进行ADC0、1或ADC4采样则正常

代码:
ADC接口宏定义
/*******ADC IO CONFIG-VOL***************************/
#define VOL_ADC_P_INPUT_PIN             MSIO_PIN_0
#define VOL_ADC_P_INPUT_PIN_MUX         APP_IO_MUX_7
#define VOL_ADC_N_INPUT_PIN             MSIO_PIN_1
#define VOL_ADC_N_INPUT_PIN_MUX         APP_IO_MUX_7
#define VOL_ADC_N_INPUT_SRC             ADC_INPUT_SRC_IO1
#define VOL_ADC_P_INPUT_SRC             ADC_INPUT_SRC_IO0
/*******ADC IO CONFIG-VOL-single***************************/
#define VOL_SINGLE_ADC_P_INPUT_PIN             MSIO_PIN_4
#define VOL_SINGLE_ADC_P_INPUT_PIN_MUX         APP_IO_MUX_7
#define VOL_SINGLE_ADC_N_INPUT_PIN             MSIO_PIN_4
#define VOL_SINGLE_ADC_N_INPUT_PIN_MUX         APP_IO_MUX_7
#define VOL_SINGLE_ADC_N_INPUT_SRC             ADC_INPUT_SRC_IO4
#define VOL_SINGLE_ADC_P_INPUT_SRC             ADC_INPUT_SRC_IO4
定时器中断
static void app_tim1_event_handler(app_tim_evt_t *p_evt)
{
    if (*p_evt == APP_TIM_EVT_DONE)
    {
			if(g_tim1_cnt >adc_collect_num)
			{
				app_tim_stop(APP_TIM_ID_0);
				app_tim_stop(APP_TIM_ID_1);
				vol_control_set(false);
				printf("vol_adc_data_single  vol_adc_data \n");
				for(int i=0;i<adc_collect_num/2;i++)
					printf("%f  %f \n",vol_adc_data_single[i],vol_adc_data[i]);
			}
			else
			{
				if(g_tim1_cnt%2)
					vol_adc_data[g_tim1_cnt/2]=vol_adc_recovery();
				else
				    vol_adc_data_single[g_tim1_cnt/2]=vol_adc_signal();
				g_tim1_cnt++;
			}
    }
}
ADC初始化及采集
app_adc_params_t vol_adc_params = {
    .pin_cfg = {
        .channel_p = {
            .type = APP_IO_TYPE_MSIO,
            .mux  = VOL_ADC_P_INPUT_PIN_MUX,
            .pin  = VOL_ADC_P_INPUT_PIN,
        },
        .channel_n = {
            .type = APP_IO_TYPE_MSIO,
            .mux  = VOL_ADC_N_INPUT_PIN_MUX,
            .pin  = VOL_ADC_N_INPUT_PIN,
        },
    },
    .dma_cfg = {
        .dma_instance = DMA0,
        .dma_channel  = DMA_Channel1,
    },
    .init = {
        .channel_p  = VOL_ADC_P_INPUT_SRC,
        .channel_n  = VOL_ADC_N_INPUT_SRC,
        .input_mode = ADC_INPUT_DIFFERENTIAL,//ADC_INPUT_SINGLE,
        .ref_source = ADC_REF_SRC_BUF_INT,
        .ref_value  = ADC_REF_VALUE_1P6,
        .clock      = ADC_CLK_8M,
    },
};
app_adc_params_t vol_adc_params_single = {
    .pin_cfg = {
        .channel_p = {
            .type = APP_IO_TYPE_MSIO,
            .mux  = VOL_SINGLE_ADC_P_INPUT_PIN_MUX,
            .pin  = VOL_SINGLE_ADC_P_INPUT_PIN,
        },
        .channel_n = {
            .type = APP_IO_TYPE_MSIO,
            .mux  = VOL_SINGLE_ADC_N_INPUT_PIN_MUX,
            .pin  = VOL_SINGLE_ADC_N_INPUT_PIN,
        },
    },
    .dma_cfg = {
        .dma_instance = DMA0,
        .dma_channel  = DMA_Channel2,
    },
    .init = {
        .channel_p  = VOL_SINGLE_ADC_P_INPUT_SRC,
        .channel_n  = VOL_SINGLE_ADC_N_INPUT_SRC,
        .input_mode = ADC_INPUT_SINGLE,
        .ref_source = ADC_REF_SRC_BUF_INT,
        .ref_value  = ADC_REF_VALUE_1P2,
        .clock      = ADC_CLK_8M,
    },
};
/**********************************电压采集-信号*****************************************/
double vol_adc_signal(void)
{
	covn_done = 0;// 重置转换完成标志位
	uint16_t ret = APP_DRV_SUCCESS;//初始化返回函数0x0000
	double   voltage[TEST_CONV_LENGTH],vol = 0;//原始数据采集数组
	app_adc_deinit();
	ret = app_adc_init(&vol_adc_params_single, app_adc_evt_handler);//配置ADC-差分ADC
	if (ret != APP_DRV_SUCCESS)
	{
			printf("\r\nADC initial failed! Please check the input parameters-vol_adc_signal.\r\n");
			return 0;
	}
	app_adc_dma_deinit();
	ret = app_adc_dma_init(&vol_adc_params_single);
	if (ret != APP_DRV_SUCCESS)
	{
			printf("\r\nADC initial dma failed! Please check the input parameters-vol_adc_signal.\r\n");
			return 0;
	}
	memset(conversion, 0, sizeof(conversion)); // 将conversion数组的内存全部清零
	app_adc_conversion_async(conversion, TEST_CONV_LENGTH);
//	app_adc_dma_conversion_async(conversion, TEST_CONV_LENGTH);// 启动异步ADC转换(使用DMA)
	while(covn_done == 0);// 等待转换完成(covn_done会在转换完成后被置位)
	adc_close();
	app_adc_voltage_intern(conversion, voltage, TEST_CONV_LENGTH);// 将原始ADC值转换为电压值
	for(uint32_t i = 0; i < TEST_CONV_LENGTH; i++)// 累加所有采样值
	{
			vol += voltage[i];
	}
	return vol/TEST_CONV_LENGTH;// 返回平均值
}
/**********************************电压采集-回采*****************************************/
extern volatile int g_tim1_cnt;
double vol_adc_recovery(void)
{
	covn_done = 0;
	uint16_t ret = APP_DRV_SUCCESS;//初始化返回函数0x0000
	double   voltage[TEST_CONV_LENGTH],vol_single = 0;//原始数据采集数组
	app_adc_deinit();
	ret = app_adc_init(&vol_adc_params, app_adc_evt_handler);//配置ADC-差分ADC
	if (ret != APP_DRV_SUCCESS)
	{
			printf("\r\nADC initial failed! Please check the input parameters-vol_adc_recovery.\r\n");
			return 0;
	}
	app_adc_dma_deinit();
	ret = app_adc_dma_init(&vol_adc_params);
	if (ret != APP_DRV_SUCCESS)
	{
			printf("\r\nADC initial dma failed! Please check the input parameters-vol_adc_recovery.\r\n");
			return 0;
	}
	memset(conversion, 0, sizeof(conversion));
	app_adc_conversion_async(conversion, TEST_CONV_LENGTH);
//	app_adc_dma_conversion_async(conversion, TEST_CONV_LENGTH);
	while(covn_done == 0);
	adc_close();
	app_adc_voltage_intern(conversion, voltage, TEST_CONV_LENGTH);
	for(uint32_t i = 0; i < TEST_CONV_LENGTH; i++)
	{
			vol_single += voltage[i];
			vol_adc_recovery_data[g_tim1_cnt][i] = voltage[i];
	}
	return vol_single/TEST_CONV_LENGTH;
}

返回数据为

0收藏

0赞成

登录后可回答问题,请 注册

我们时刻倾听您的声音
联系销售

扫描关注公众号

打开微信,使用“扫一扫”即可关注