先申明,本栏目用的都是GD32F470芯片240M,软件用的是keil,编写用的是C++(其实和C没有区别).,
1.因为我用的是C++,枚举类型是不能运算的。只能赋值。需要自己修改库函数
这是我自己的改的:
2.
GD32的 2016-08-15, V1.0.0, firmware update for GD32F4xx的库,连__cplusplus都写错,后面的新版本就没有了。
3.
同时如果要用C++,那么就注释掉这句。因为重复编译了。
3.0.0版本的库就没有了这一句。
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配置(不中断):
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");
}
}
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);
}