发现问题后,搞了半天还是解决不了,突然发现了这篇文章:
http://t.csdn.cn/D79FAhttp://t.csdn.cn/D79FA根据大佬介绍改完代码,运行完美!!!!感谢大佬!!!
下面把代码贴出,根据GD32E230固件库写的,我用的是GD32E230G8。
DMA初始化:
uint16_t adc_value[4];
void dma_config(void)
{
/* enable DMA clock 启用DMA时钟 */
rcu_periph_clock_enable(RCU_DMA);
/* ADC_DMA_channel configuration dma初始化结构体 */
dma_parameter_struct dma_data_parameter;
/* ADC DMA_channel configuration 复位DAM通道 */
dma_deinit(DMA_CH0);
/* initialize DMA single data mode */
dma_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA);//ADC_RDATA是读取adc数据的寄存器
dma_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
dma_data_parameter.memory_addr = (uint32_t)(adc_value);//adc_value 是存储adc数据的内存数组
dma_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;//内存地址自增1
dma_data_parameter.memory_width = DMA_MEMORY_WIDTH_16BIT;
dma_data_parameter.direction = DMA_PERIPHERAL_TO_MEMORY; //从外设到内存
//这里的4是设置dma搬运数据的个数即4个通道共读取4个数据,每个通道读取1个,完成后会触发中断
dma_data_parameter.number = 4U;
dma_data_parameter.priority = DMA_PRIORITY_HIGH;//设置通道优先级为高优先级
dma_init(DMA_CH0, &dma_data_parameter);
//循环模式开启,关闭是dma_circulation_disable
//ADC扫描模式时开启dma循环模式处理持续的外围请求
dma_circulation_enable(DMA_CH0);
dma_memory_to_memory_disable(DMA_CH0);
/* enable DMA channel 使能通道 */
dma_channel_enable(DMA_CH0);
}
ADC初始化:
void adc_config(void)
{
/* enable ADC clock 使能ADC时钟*/
rcu_periph_clock_enable(RCU_ADC);
rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6);
adc_deinit(); //复位ADC
//=========================================================
//打开扫描模式
adc_special_function_config(ADC_SCAN_MODE,ENABLE);
//连续转换开启,,,,!!!!!!这里不能开,开了在FLASH编程保存数据时会导致adc数据错位
//adc_special_function_config(ADC_CONTINUOUS_MODE,ENABLE);
/* ADC DMA function enable ADC DMA功能启用*/
adc_dma_mode_enable();
//=========================================================
/* ADC data alignment config ADC数据对齐配置,右对齐*/
adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
/* ADC分辨率 12B */
adc_resolution_config(ADC_RESOLUTION_12B);
//=========================================================
/* ADC channel length config ADC通道个数配置*/
adc_channel_length_config(ADC_REGULAR_CHANNEL, 4U);
/* ADC regular channel config ADC常规通道配置 配置ADC规则通道组。rank代表扫描顺序,channel要根据ADC通道与GPIO的映射关系表确定。*/
adc_regular_channel_config(0U, ADC_CHANNEL_1, ADC_SAMPLETIME_55POINT5);
adc_regular_channel_config(1U, ADC_CHANNEL_5, ADC_SAMPLETIME_55POINT5);
adc_regular_channel_config(2U, ADC_CHANNEL_7, ADC_SAMPLETIME_55POINT5);
adc_regular_channel_config(3U, ADC_CHANNEL_9, ADC_SAMPLETIME_55POINT5);
/* ADC trigger config ADC触发器配置 配置ADC通道组为常规通道组,外部触发源为软件触发*/
adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE);
//配置ADC外部触发 adc规则通道外部触发器
adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);
/* enable ADC interface 启用ADC接口*/
adc_enable();
delay_1ms(3U);
/* ADC calibration and reset calibration ADC校准和复位校准*/
adc_calibration_enable();
/* ADC software trigger enable ADC软件触发*/
adc_software_trigger_enable(ADC_REGULAR_CHANNEL);
}
获取ADC值,每次获取时触发一次转换,我这个是在定时器中断中调用的
//获得ADC值
u16 Get_Adc(u8 CH)
{
//!!!!!!上面ADC没开连续转换,在这里每次获取数据时触发一次
//不触发的话,ADC值就一直是adc初始化完时触发的那一次的值
/* ADC software trigger enable ADC软件触发*/
adc_software_trigger_enable(ADC_REGULAR_CHANNEL);
return adc_value[CH];
}