使用GD32E230,ADC+DMA,在FLASH编程时出现adc数据错位的解决办法

发现问题后,搞了半天还是解决不了,突然发现了这篇文章: 

http://t.csdn.cn/D79FAicon-default.png?t=N3I4http://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];
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值