GD32F103使用DMA方式实现ADC0数据循环采集

  1. 选择合适的DMA通道
    ADC0使用ch0
    在这里插入图片描述
/*!
    \brief      configure the DMA peripheral
    \param[in]  none
    \param[out] none
    \retval     none
*/
void dma_config(void)
{
    /* ADC_DMA_channel configuration */
    dma_parameter_struct dma_data_parameter;
 
    /* enable DMA0 clock */
    rcu_periph_clock_enable(RCU_DMA0);  
  
    /* ADC DMA_channel configuration */
    dma_deinit(DMA0, DMA_CH0);
    
    /* initialize DMA data mode */
    dma_data_parameter.periph_addr  = (uint32_t)(&ADC_RDATA(ADC0));
    dma_data_parameter.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
    dma_data_parameter.memory_addr  = (uint32_t)(&adc_value);
    dma_data_parameter.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
    dma_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
    dma_data_parameter.memory_width = DMA_MEMORY_WIDTH_16BIT;  
    dma_data_parameter.direction    = DMA_PERIPHERAL_TO_MEMORY;
    dma_data_parameter.number       = 100;		
    dma_data_parameter.priority     = DMA_PRIORITY_ULTRA_HIGH;
    dma_init(DMA0, DMA_CH0, &dma_data_parameter);

    dma_circulation_enable(DMA0, DMA_CH0);	//采集完100个之后,循环
    
    /* enable DMA transfer complete interrupt */
    dma_interrupt_enable(DMA0, DMA_CH0, DMA_INT_FTF);	//打开全部完成中断
    dma_interrupt_enable(DMA0, DMA_CH0, DMA_INT_HTF);	//打开一半完成中断
  
    /* enable DMA channel */
    dma_channel_enable(DMA0, DMA_CH0);
    
    nvic_irq_enable(DMA0_Channel0_IRQn, 0, 0);
}

/*!
    \brief      configure the TIMER peripheral
    \param[in]  none
    \param[out] none
    \retval     none
*/
void timer1_config(void)	//1ms采集一次
{
    timer_oc_parameter_struct timer_ocintpara;
    timer_parameter_struct timer_initpara;

    /* enable timer1 clock */
    rcu_periph_clock_enable(RCU_TIMER1);
  
    /* TIMER1 configuration */
    timer_initpara.prescaler         = 107;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 999;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(TIMER1,&timer_initpara);

    /* CH0 configuration in PWM mode1 */
    timer_ocintpara.ocpolarity  = TIMER_OC_POLARITY_HIGH;
    timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
    timer_channel_output_config(TIMER1, TIMER_CH_1, &timer_ocintpara);

    timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_1, 499);
    timer_channel_output_mode_config(TIMER1, TIMER_CH_1, TIMER_OC_MODE_PWM1);
    timer_channel_output_shadow_config(TIMER1, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE);
}

/*!
    \brief      configure the ADC peripheral
    \param[in]  none
    \param[out] none
    \retval     none
*/
void adc_config(void)
{
    /* enable ADC0 clock */
    rcu_periph_clock_enable(RCU_ADC0);
   /* reset ADC */
    adc_deinit(ADC0);
    /* ADC mode config */
    adc_mode_config(ADC_MODE_FREE); 
    /* ADC continous function enable */
    adc_special_function_config(ADC0, ADC_SCAN_MODE, DISABLE); 
 
    /* ADC data alignment config */
    adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
    /* ADC channel length config */
    adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1);
  
  
    /* ADC regular channel config */
    adc_regular_channel_config(ADC0, 0, AD0_CH, ADC_SAMPLETIME_55POINT5);

    /* ADC trigger config */
    adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_EXTTRIG_REGULAR_T1_CH1);
        /* ADC external trigger enable */
    adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);

    /* 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);
}

/*!
    \brief      this function handles DMA_Channel3_IRQHandler interrupt
    \param[in]  none
    \param[out] none
    \retval     none
*/
void DMA0_Channel0_IRQHandler(void)
{
  if(dma_interrupt_flag_get(DMA0, DMA_CH0, DMA_INT_FLAG_FTF))
  {     
    dma_interrupt_flag_clear(DMA0, DMA_CH0, DMA_INT_FLAG_FTF);
//    dma_interrupt_flag_clear(DMA0, DMA_CH0, DMA_INT_FLAG_G);
   
  }
  else if(dma_interrupt_flag_get(DMA0, DMA_CH0, DMA_INT_FLAG_HTF))
  {
    dma_interrupt_flag_clear(DMA0, DMA_CH0, DMA_INT_FLAG_HTF);
//    dma_interrupt_flag_clear(DMA0, DMA_CH0, DMA_INT_FLAG_G);
    dmaHalfIntCnt ++;
//    uart_dma_start();

  }
}

void dma_start(void)
{
  timer1_config();
  dma_config();
  adc_config();
  /* enable TIMER1 */
  timer_enable(TIMER1);

}

版权声明:本文为CSDN博主「lljss2020」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lljss1980/article/details/119833185

  1. 选择合适的DMA通道
    ADC0使用ch0
    在这里插入图片描述
/*!
    \brief      configure the DMA peripheral
    \param[in]  none
    \param[out] none
    \retval     none
*/
void dma_config(void)
{
    /* ADC_DMA_channel configuration */
    dma_parameter_struct dma_data_parameter;
 
    /* enable DMA0 clock */
    rcu_periph_clock_enable(RCU_DMA0);  
  
    /* ADC DMA_channel configuration */
    dma_deinit(DMA0, DMA_CH0);
    
    /* initialize DMA data mode */
    dma_data_parameter.periph_addr  = (uint32_t)(&ADC_RDATA(ADC0));
    dma_data_parameter.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
    dma_data_parameter.memory_addr  = (uint32_t)(&adc_value);
    dma_data_parameter.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
    dma_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
    dma_data_parameter.memory_width = DMA_MEMORY_WIDTH_16BIT;  
    dma_data_parameter.direction    = DMA_PERIPHERAL_TO_MEMORY;
    dma_data_parameter.number       = 100;		
    dma_data_parameter.priority     = DMA_PRIORITY_ULTRA_HIGH;
    dma_init(DMA0, DMA_CH0, &dma_data_parameter);

    dma_circulation_enable(DMA0, DMA_CH0);	//采集完100个之后,循环
    
    /* enable DMA transfer complete interrupt */
    dma_interrupt_enable(DMA0, DMA_CH0, DMA_INT_FTF);	//打开全部完成中断
    dma_interrupt_enable(DMA0, DMA_CH0, DMA_INT_HTF);	//打开一半完成中断
  
    /* enable DMA channel */
    dma_channel_enable(DMA0, DMA_CH0);
    
    nvic_irq_enable(DMA0_Channel0_IRQn, 0, 0);
}

/*!
    \brief      configure the TIMER peripheral
    \param[in]  none
    \param[out] none
    \retval     none
*/
void timer1_config(void)	//1ms采集一次
{
    timer_oc_parameter_struct timer_ocintpara;
    timer_parameter_struct timer_initpara;

    /* enable timer1 clock */
    rcu_periph_clock_enable(RCU_TIMER1);
  
    /* TIMER1 configuration */
    timer_initpara.prescaler         = 107;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 999;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(TIMER1,&timer_initpara);

    /* CH0 configuration in PWM mode1 */
    timer_ocintpara.ocpolarity  = TIMER_OC_POLARITY_HIGH;
    timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
    timer_channel_output_config(TIMER1, TIMER_CH_1, &timer_ocintpara);

    timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_1, 499);
    timer_channel_output_mode_config(TIMER1, TIMER_CH_1, TIMER_OC_MODE_PWM1);
    timer_channel_output_shadow_config(TIMER1, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE);
}

/*!
    \brief      configure the ADC peripheral
    \param[in]  none
    \param[out] none
    \retval     none
*/
void adc_config(void)
{
    /* enable ADC0 clock */
    rcu_periph_clock_enable(RCU_ADC0);
   /* reset ADC */
    adc_deinit(ADC0);
    /* ADC mode config */
    adc_mode_config(ADC_MODE_FREE); 
    /* ADC continous function enable */
    adc_special_function_config(ADC0, ADC_SCAN_MODE, DISABLE); 
 
    /* ADC data alignment config */
    adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
    /* ADC channel length config */
    adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1);
  
  
    /* ADC regular channel config */
    adc_regular_channel_config(ADC0, 0, AD0_CH, ADC_SAMPLETIME_55POINT5);

    /* ADC trigger config */
    adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_EXTTRIG_REGULAR_T1_CH1);
        /* ADC external trigger enable */
    adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);

    /* 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);
}

/*!
    \brief      this function handles DMA_Channel3_IRQHandler interrupt
    \param[in]  none
    \param[out] none
    \retval     none
*/
void DMA0_Channel0_IRQHandler(void)
{
  if(dma_interrupt_flag_get(DMA0, DMA_CH0, DMA_INT_FLAG_FTF))
  {     
    dma_interrupt_flag_clear(DMA0, DMA_CH0, DMA_INT_FLAG_FTF);
//    dma_interrupt_flag_clear(DMA0, DMA_CH0, DMA_INT_FLAG_G);
   
  }
  else if(dma_interrupt_flag_get(DMA0, DMA_CH0, DMA_INT_FLAG_HTF))
  {
    dma_interrupt_flag_clear(DMA0, DMA_CH0, DMA_INT_FLAG_HTF);
//    dma_interrupt_flag_clear(DMA0, DMA_CH0, DMA_INT_FLAG_G);
    dmaHalfIntCnt ++;
//    uart_dma_start();

  }
}

void dma_start(void)
{
  timer1_config();
  dma_config();
  adc_config();
  /* enable TIMER1 */
  timer_enable(TIMER1);

}

版权声明:本文为CSDN博主「lljss2020」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lljss1980/article/details/119833185

生成海报
点赞 0

lljss2020

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

GD32的Keil环境搭建简述

以GD32F30x为例 从GD官网下载开发文件: GD32F30x_AddOn_V2.1.0.rar包含Keil所需的gd32相关芯片的pack: GD32F30x_Demo_Suites_V2.3.0.rar包

GD32F103基础教程—教程简介(一)

随着ST公司芯片的价格越来越高,许多公司开始寻求国产芯片进行替换,但是大部分人用习惯了ST的单片机,突然更换国产芯片,很多产品的性能需要重新测试,对于资历比较深的嵌入式工程师

GD32F103快速替换STM32F103

注:本文档仅针对GD32F103系列替代STM32F103系列 版权:威尔健科技有限公司 主营业务:GD MCU代理与方案开发,中科微定位模块或芯片,美格通讯模块等。 联系方