GD32F470之ADC0+ADC2+DMA(不中断)+多通道采集+吐槽DMA的库和C++的兼容问题

先申明,本栏目用的都是GD32F470芯片240M,软件用的是keil,编写用的是C++(其实和C没有区别).,

吐槽的点:

1.因为我用的是C++,枚举类型是不能运算的。只能赋值。需要自己修改库函数
GD32F470之ADC0+ADC2+DMA(不中断)+多通道采集+吐槽DMA的库和C++的兼容问题_第1张图片
这是我自己的改的:
GD32F470之ADC0+ADC2+DMA(不中断)+多通道采集+吐槽DMA的库和C++的兼容问题_第2张图片
2.
GD32的 2016-08-15, V1.0.0, firmware update for GD32F4xx的库,连__cplusplus都写错,后面的新版本就没有了。

GD32F470之ADC0+ADC2+DMA(不中断)+多通道采集+吐槽DMA的库和C++的兼容问题_第3张图片
3.
同时如果要用C++,那么就注释掉这句。因为重复编译了。
3.0.0版本的库就没有了这一句。
GD32F470之ADC0+ADC2+DMA(不中断)+多通道采集+吐槽DMA的库和C++的兼容问题_第4张图片

ADC0+DMA配置代码:

IO配置:

	  rcu_periph_clock_enable(RCU_GPIOA);
		rcu_periph_clock_enable(RCU_GPIOB);
		//A5 :A
		//A4 : B
		//B1 : C
		gpio_mode_set(GPIOA,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,GPIO_PIN_5|GPIO_PIN_4);
	
	
    gpio_mode_set(GPIOB,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,GPIO_PIN_1);

ADC0寄存器配置:

注意:打开了扫描模式。还要打开连续模式才会一直循环采样
通道号和GPIO引脚的复用功能有关,可以查看芯片手册。
例如
在这里插入图片描述

	rcu_periph_clock_enable(RCU_ADC0);
		   /* config ADC clock */ //120M /4
    adc_clock_config(ADC_ADCCK_PCLK2_DIV4);
	
	//IO初始化
		ADC0_Io_Config_Init();
		ADC0_DMA_Config_Init();
		
	/* ADC channel length config */
    adc_channel_length_config(ADC0,ADC_REGULAR_CHANNEL,ADC0_CHANNEL_NUM);
    /* ADC regular channel config */
  	adc_regular_channel_config(ADC0,0,ADC_CHANNEL_5,ADC_SAMPLETIME_28); //A
    adc_regular_channel_config(ADC0,1,ADC_CHANNEL_4,ADC_SAMPLETIME_28);//B
    adc_regular_channel_config(ADC0,2,ADC_CHANNEL_9,ADC_SAMPLETIME_28);//C

    /* ADC external trigger enable */
    adc_external_trigger_config(ADC0,ADC_REGULAR_CHANNEL,EXTERNAL_TRIGGER_DISABLE);
    /* ADC data alignment config */
    adc_data_alignment_config(ADC0,ADC_DATAALIGN_RIGHT);
    
    /* enable ADC interface */
    adc_enable(ADC0);
		delay_1ms(1);
    /* ADC calibration and reset calibration */
    adc_calibration_enable(ADC0);
    
    /* ADC DMA function enable */
    adc_dma_mode_enable(ADC0);
    adc_dma_request_after_last_enable(ADC0);
    /* ADC contineous function enable */
		//打开了扫描模式。还要打开连续模式才会一直循环采样
    adc_special_function_config(ADC0,ADC_CONTINUOUS_MODE,ENABLE); 
		adc_special_function_config(ADC0,ADC_SCAN_MODE,ENABLE);
    /* ADC software trigger enable */
  //  adc_software_trigger_enable(ADC0,ADC_REGULAR_CHANNEL);

ADC0的DMA配置(不中断):

DMA通道的对应关系可以查看手册
GD32F470之ADC0+ADC2+DMA(不中断)+多通道采集+吐槽DMA的库和C++的兼容问题_第5张图片

	rcu_periph_clock_enable(RCU_DMA1);
	    /* ADC_DMA_channel configuration */
    dma_single_data_parameter_struct dma_single_data_parameter_ado0;
    
    /* ADC DMA_channel configuration */
    dma_deinit(DMA1,DMA_CH0);
    
    /* initialize DMA single data mode */
    dma_single_data_parameter_ado0.periph_addr = (uint32_t)(&ADC_RDATA(ADC0));
    dma_single_data_parameter_ado0.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
    dma_single_data_parameter_ado0.memory0_addr = (uint32_t)(adc0_scr_data);
    dma_single_data_parameter_ado0.memory_inc = DMA_MEMORY_INCREASE_ENABLE;//内存自增
    dma_single_data_parameter_ado0.periph_memory_width = DMA_PERIPH_WIDTH_32BIT;//这位数要和你的adc_value的类型一致
    dma_single_data_parameter_ado0.circular_mode = DMA_CIRCULAR_MODE_ENABLE;
    dma_single_data_parameter_ado0.direction = DMA_PERIPH_TO_MEMORY;
    dma_single_data_parameter_ado0.number = ADC0_CONVERSION_NUM;
    dma_single_data_parameter_ado0.priority = DMA_PRIORITY_HIGH;
    dma_single_data_mode_init(DMA1,DMA_CH0,&dma_single_data_parameter_ado0);
		
		dma_channel_subperipheral_select(DMA1, DMA_CH0, DMA_SUBPERI0);
	
		#if DMA1_CH0_DONE_INT 
		nvic_irq_enable(DMA1_Channel0_IRQn, 0, 2);
		dma_interrupt_enable(DMA1,DMA_CH0,DMA_CHXCTL_FTFIE);
		#endif
    /* enable DMA channel */
    dma_channel_enable(DMA1,DMA_CH0);

中断函数:

extern "C"void DMA1_Channel0_IRQHandler()
{
		if(SET == dma_interrupt_flag_get(DMA1, DMA_CH0,DMA_INT_FLAG_FTF))
		{
				dma_interrupt_flag_clear(DMA1, DMA_CH0,DMA_INT_FLAG_FTF);
				
			//	adc0_DMA_done_flag=1;
	
				//printf("132131\r\n");
		}
}

ADC2+DMA配置代码:

io配置:

 rcu_periph_clock_enable(RCU_GPIOC);	
		 rcu_periph_clock_enable(RCU_GPIOF);	
		 gpio_mode_set(GPIOF,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,GPIO_PIN_3|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8);
	

		 gpio_mode_set(GPIOC,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,GPIO_PIN_0);

ADC2配置:

	rcu_periph_clock_enable(RCU_ADC2);
		   /* config ADC clock */
    adc_clock_config(ADC_ADCCK_PCLK2_DIV4);
		//IO初始化
		ADC2_Io_Config_Init();
		ADC2_DMA_Config_Init();

		    /* ADC channel length config */
    adc_channel_length_config(ADC2,ADC_REGULAR_CHANNEL,ADC2_CHANNEL_NUM);
    /* ADC regular channel config */

    adc_regular_channel_config(ADC2,0,ADC_CHANNEL_10,ADC_SAMPLETIME_28);

    adc_regular_channel_config(ADC2,1,ADC_CHANNEL_9,ADC_SAMPLETIME_28);//

    adc_regular_channel_config(ADC2,2,ADC_CHANNEL_15,ADC_SAMPLETIME_28);//

    adc_regular_channel_config(ADC2,3,ADC_CHANNEL_4,ADC_SAMPLETIME_28);//

    adc_regular_channel_config(ADC2,4,ADC_CHANNEL_5,ADC_SAMPLETIME_28);//
	
		adc_regular_channel_config(ADC2,5,ADC_CHANNEL_6,ADC_SAMPLETIME_28);//

    /* ADC external trigger enable */
    adc_external_trigger_config(ADC2,ADC_REGULAR_CHANNEL,EXTERNAL_TRIGGER_DISABLE);
    /* ADC data alignment config */
    adc_data_alignment_config(ADC2,ADC_DATAALIGN_RIGHT);
		
		
		 /* ADC contineous function enable */
		//打开了扫描模式。还要打开连续模式才会一直循环采样
    adc_special_function_config(ADC2,ADC_CONTINUOUS_MODE,ENABLE); 
		adc_special_function_config(ADC2,ADC_SCAN_MODE,ENABLE);
    /* enable ADC interface */
    adc_enable(ADC2);
		delay_1ms(1);
    /* ADC calibration and reset calibration */
    adc_calibration_enable(ADC2);
    
    /* ADC DMA function enable */
    adc_dma_mode_enable(ADC2);
    adc_dma_request_after_last_enable(ADC2);//1:当 DMA=1,在每个规则转换结束时 DMA 机制产生一个 DMA 请求。

    /* ADC software trigger enable */
  //  adc_software_trigger_enable(ADC1,ADC_REGULAR_CHANNEL);

DMA配置(不中断):

	 /* ADC_DMA_channel configuration */
    dma_single_data_parameter_struct dma_single_data_parameter_ado1;
     rcu_periph_clock_enable(RCU_DMA1);
    /* ADC DMA_channel configuration */
    dma_deinit(DMA1,DMA_CH1);
    
    /* initialize DMA single data mode */
    dma_single_data_parameter_ado1.periph_addr = (uint32_t)(&ADC_RDATA(ADC2));
    dma_single_data_parameter_ado1.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
    dma_single_data_parameter_ado1.memory0_addr = (uint32_t)(adc2_scr_data);
    dma_single_data_parameter_ado1.memory_inc = DMA_MEMORY_INCREASE_ENABLE;//内存自增
    dma_single_data_parameter_ado1.periph_memory_width = DMA_PERIPH_WIDTH_32BIT;//这位数要和你的adc_value的类型一致
    dma_single_data_parameter_ado1.circular_mode = DMA_CIRCULAR_MODE_ENABLE;
    dma_single_data_parameter_ado1.direction = DMA_PERIPH_TO_MEMORY;
    dma_single_data_parameter_ado1.number = ADC2_CONVERSION_NUM;
    dma_single_data_parameter_ado1.priority = DMA_PRIORITY_HIGH;
    dma_single_data_mode_init(DMA1,DMA_CH1,&dma_single_data_parameter_ado1);
		
		//用这个来选择外设
		dma_channel_subperipheral_select(DMA1, DMA_CH1, DMA_SUBPERI2);
	
		#if  DMA1_CH1_DONE_INT 
			nvic_irq_enable(DMA1_Channel1_IRQn, 0, 2);
			dma_interrupt_enable(DMA1,DMA_CH1,DMA_CHXCTL_FTFIE);
		#endif
    /* enable DMA channel */
    dma_channel_enable(DMA1,DMA_CH1);

中断函数:


extern "C"void DMA1_Channel1_IRQHandler()
{
		if(SET == dma_interrupt_flag_get(DMA1, DMA_CH1,DMA_INT_FLAG_FTF))
		{
				dma_interrupt_flag_clear(DMA1, DMA_CH1,DMA_INT_FLAG_FTF);
				
			//	adc2_DMA_done_flag=1;
	
				//printf("132131\r\n");
		}
}

结束:

由于没有cache,所以需要取数据的时候就直接读取adcx_scr_data就好就好了。
adcx_scr_data就是adc0_scr_data和adc2_scr_data

if(dma_flag_get(DMA1,DMA_CH1,DMA_INTF_FTFIF))
			{
		
					dma_flag_clear(DMA1,DMA_CH1,DMA_INTC_FTFIFC);
					}

你可能感兴趣的:(GD32F470,c++,单片机,stm32)