打印
[研电赛技术支持]

GD32H759的ADC的DMA传输

[复制链接]
887|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ryan_jiang|  楼主 | 2025-3-11 16:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
GD32H759的ADC的DMA传输,DMA传输完成后进入传输完成中断后,ADC需要重新初始化才能正常采样。如果不开启传输完成中断,ADC可以一直采样传输。但是一使用传输完成中断,在传输完成中断中先关闭DMA通道,读取完数据后,在开启DMA通道后,要重新初始化ADC才能正常采样,否则ADC就无法采样数据完成DMA传输完成中断。ADC和DMA配置如下:

/*!
    \brief      configure the DMA peripheral
    \param[in]  none
    \param[out] none
    \retval     none
*/
void adc_dma_config(void)
{
    /* ADC_DMA_channel configuration */
    dma_single_data_parameter_struct dma_single_data_parameter;


nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
    nvic_irq_enable(DMA0_Channel0_IRQn, 2, 0);

        rcu_periph_clock_enable(RCU_DMA0);
    rcu_periph_clock_enable(RCU_DMAMUX);
        nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
    nvic_irq_enable(DMA0_Channel0_IRQn, 1, 0);
       
        SCB_CleanDCache_by_Addr((uint32_t*)WindADC_Buf, WIND_ADCBUF_SIZE*2);

    /* ADC DMA_channel configuration */
    dma_deinit(DMA0, DMA_CH0);
       
       

    /* initialize DMA single data mode */
    dma_single_data_parameter.request = DMA_REQUEST_ADC2;
    dma_single_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA(ADC2));
    dma_single_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
    dma_single_data_parameter.memory0_addr = (uint32_t)(&WindADC_Buf);
    dma_single_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
    dma_single_data_parameter.periph_memory_width = DMA_PERIPH_WIDTH_16BIT;
    dma_single_data_parameter.direction = DMA_PERIPH_TO_MEMORY;
    dma_single_data_parameter.number = WIND_ADCBUF_SIZE;
    dma_single_data_parameter.priority = DMA_PRIORITY_HIGH;
        dma_single_data_parameter.circular_mode = DMA_CIRCULAR_MODE_ENABLE;
    dma_single_data_mode_init(DMA0, DMA_CH0, &dma_single_data_parameter);

    /* enable DMA circulation mode */
    dma_circulation_enable(DMA0, DMA_CH0);
       
        dma_interrupt_enable(DMA0, DMA_CH0, DMA_INT_FTF);

    /* enable DMA channel */
    dma_channel_enable(DMA0, DMA_CH0);
       
}


void adc_config(void)
{
        rcu_periph_clock_enable(RCU_GPIOC);

    rcu_periph_clock_enable(RCU_ADC0);
       
        rcu_periph_clock_enable(RCU_GPIOC);     // 使能GPIOC时钟
        rcu_periph_clock_enable(RCU_ADC2);      // 使能ADC2时钟
        syscfg_analog_switch_enable(SYSCFG_PC2_ANALOG_SWITCH);
        syscfg_analog_switch_enable(SYSCFG_PC3_ANALOG_SWITCH);
    /* reset ADC */
    adc_deinit(WIND_ADC);
    /* ADC clock config */

    adc_clock_config(WIND_ADC, ADC_CLK_SYNC_HCLK_DIV6);
    /* ADC contineous function enable */
    adc_special_function_config(WIND_ADC, ADC_CONTINUOUS_MODE, ENABLE);
    /* ADC scan mode enable */
    adc_special_function_config(WIND_ADC, ADC_SCAN_MODE, ENABLE);
    /* ADC resolution config */
    adc_resolution_config(WIND_ADC, ADC_RESOLUTION_12B);
    /* ADC data alignment config */
    adc_data_alignment_config(WIND_ADC, ADC_DATAALIGN_RIGHT);

    /* ADC channel length config */
    adc_channel_length_config(WIND_ADC, ADC_REGULAR_CHANNEL, 1);

    /* ADC regular channel config */
    adc_regular_channel_config(WIND_ADC, 0, WIND_ADC_DP_CHANNEL, 0);

        adc_channel_differential_mode_config(WIND_ADC, ADC_DIFFERENTIAL_MODE_CHANNEL_0, ENABLE);

    /* ADC trigger config */
    adc_external_trigger_config(WIND_ADC, ADC_REGULAR_CHANNEL, EXTERNAL_TRIGGER_DISABLE);

    /* ADC DMA function enable */
    adc_dma_request_after_last_enable(WIND_ADC);
    adc_dma_mode_enable(WIND_ADC);

    /* enable ADC interface */
    adc_enable(WIND_ADC);
    /* wait for ADC stability */
    delay_ms(1);
    /* ADC calibration mode config */
    adc_calibration_mode_config(WIND_ADC, ADC_CALIBRATION_OFFSET);
    /* ADC calibration number config */
    adc_calibration_number(WIND_ADC, ADC_CALIBRATION_NUM1);
    /* ADC calibration and reset calibration */
    adc_calibration_enable(WIND_ADC);

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



void DMA0_Channel0_IRQHandler(void)
{
        if(RESET != dma_interrupt_flag_get(DMA0, DMA_CH0, DMA_INT_FLAG_FTF))
        {
        dma_interrupt_flag_clear(DMA0, DMA_CH0, DMA_INT_FLAG_FTF);
                dma_channel_disable(DMA0, DMA_CH0);
                SCB_InvalidateDCache_by_Addr((uint32_t*)WindADC_Buf, WIND_ADCBUF_SIZE*2);
                memset(WindADC_Buf,0,WIND_ADCBUF_SIZE*2);
                LED0_TOGGLE();

    }
}



int main(void)
{
     adc_dma_config();
    adc_config();



        while(1)
        {


                dma_channel_enable(DMA0, DMA_CH0);
               adc_software_trigger_enable(WIND_ADC, ADC_REGULAR_CHANNEL);
                delay_ms(100);

}


       
        return 0;
}



使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

23

帖子

1

粉丝