狂奔的蜗牛JJ 发表于 2025-5-4 16:08

GD32F527 ADC DMA双缓冲存储

我进行adc电压电流采样,想用双缓冲进行配置,目前adc_buffer0 里面数据实时更新,但是进不去中断,把初始化的DMA_INT_FLAG_FTF改成DMA_INT_FLAG_HTF 又可以进入中断了。这是为什么?
#define BUFFER_SIZE   512
#define ADC_CHANNEL_CNT 3
#define DMA_BUFFER_SIZE   (ADC_CHANNEL_CNT * BUFFER_SIZE)
void User_ADC_Init(void)
{
    /* ADC mode config */
    adc_sync_mode_config(ADC_SYNC_MODE_INDEPENDENT);
    /* ADC contineous function disable */
    adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, ENABLE);
    /* ADC scan mode disable */
    adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);
    /* ADC data alignment config */
    adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
   
    /* ADC channel length config */
    adc_channel_length_config(ADC0, ADC_ROUTINE_CHANNEL, 3);
    /* ADC regular channel config */
    adc_routine_channel_config(ADC0, 0, ADC_CHANNEL_13, ADC_SAMPLETIME_15);/* 电流采样 */
    adc_routine_channel_config(ADC0, 1, ADC_CHANNEL_11, ADC_SAMPLETIME_15);/* 电压采样 */
    adc_routine_channel_config(ADC0, 2, ADC_CHANNEL_12, ADC_SAMPLETIME_15);/* 参考电压1.65V采样 */
    /* ADC trigger config */
    adc_external_trigger_source_config(ADC0, ADC_ROUTINE_CHANNEL, ADC_EXTTRIG_ROUTINE_T0_CH0); ////////ADC_EXTTRIG_ROUTINE_T0_CH0
    adc_external_trigger_config(ADC0, ADC_ROUTINE_CHANNEL, EXTERNAL_TRIGGER_DISABLE);///////
   
    /* ADC DMA function enable */
    adc_dma_request_after_last_enable(ADC0);
    adc_dma_mode_enable(ADC0);
   
    /* enable ADC interface */
    adc_enable(ADC0);
    /* wait for ADC stability */
    delay1ms(2);
    /* ADC calibration and reset calibration */
    adc_calibration_enable(ADC0);
   
    /* enable ADC software trigger */
    adc_software_trigger_enable(ADC0, ADC_ROUTINE_CHANNEL);
}
uint16_t adc_buffer0;
uint16_t adc_buffer1;
void User_DMA_Init(void)
{
    dma_single_data_parameter_struct dma_init_struct;

        dma_deinit(DMA1, DMA_CH0);

    dma_init_struct.periph_addr= (uint32_t)&ADC_RDATA(ADC0);
    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.memory0_addr = (uint32_t)&adc_buffer0;
    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
    dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_16BIT;
    dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
    dma_init_struct.number = ADC_CHANNEL_CNT * BUFFER_SIZE;
    dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
    dma_single_data_mode_init(DMA1, DMA_CH0, &dma_init_struct);
    dma_channel_subperipheral_select(DMA1, DMA_CH0, DMA_SUBPERI0);

    /* 启用双缓冲 */
        dma_memory_address_config(DMA1, DMA_CH0, (uint32_t)&adc_buffer1, DMA_MEMORY_1);
        dma_switch_buffer_mode_enable(DMA1, DMA_CH0, ENABLE);

    dma_circulation_disable(DMA1, DMA_CH0);
    dma_channel_enable(DMA1, DMA_CH0);

    /* 开启DMA传输完成中断 */
    dma_interrupt_enable(DMA1, DMA_CH0, DMA_INT_FLAG_FTF);
    nvic_irq_enable(DMA1_Channel0_IRQn, 1, 0);
}
void DMA1_Channel0_IRQHandler(void)
{
    if (dma_interrupt_flag_get(DMA1, DMA_CH0, DMA_INT_FLAG_FTF)==SET) {
      dma_interrupt_flag_clear(DMA1, DMA_CH0, DMA_INT_FLAG_FTF);
      dma_current_buffer = (dma_current_buffer == 0) ? 1 : 0;
      buffer_ready_flag = 1;
    }
}

classroom 发表于 2025-5-9 12:54

DMA传输配置问题或者是中断处理逻辑问题

flycamelaaa 发表于 2025-5-9 18:00

选择正确的中断标志。

kepe 发表于 2025-5-31 01:52

你调用了 dma_circulation_disable(DMA1, DMA_CH0); 禁用了循环模式,导致DMA只传输一次,且双缓冲工作方式不正常,可能也影响中断触发。

w2nme1ai7 发表于 2025-6-8 13:58

在使用DMA(直接内存访问)进行ADC采样时,双缓冲技术可以有效地提高数据采集的效率,并减少CPU的负担。

q1d0mnx 发表于 2025-6-8 15:10

在GD32系列微控制器中,DMA的中断标志配置对数据传输过程至关重要。你遇到的问题可能与DMA中断标志的选择和触发条件有关

lix1yr 发表于 2025-6-8 16:04

DMA_INT_FLAG_FTF表示DMA传输完成中断标志,即整个缓冲区传输完成时触发中断。DMA_INT_FLAG_HTF表示DMA半传输完成中断标志,即缓冲区的一半传输完成时触发中断。

b5z1giu 发表于 2025-6-8 17:10

如果使用双缓冲技术,通常需要在缓冲区的一半传输完成时触发中断,以便及时处理数据并准备下一个缓冲区。

kaif2n9j 发表于 2025-6-8 18:12

确保DMA配置为循环模式,这样可以实现数据的连续传输,而不需要手动重新启动DMA传输。

d1ng2x 发表于 2025-6-8 19:22

如果DMA没有配置为循环模式,可能在一次传输完成后停止,导致无法触发中断。

y1n9an 发表于 2025-6-8 20:27

保证中断服务程序正确处理DMA中断标志,并在中断中清除标志,以避免重复进入中断

p0gon9y 发表于 2025-6-9 08:43

检查DMA配置:保DMA通道配置为循环模式。保DMA的中断标志配置正确。对于双缓冲技术,通常需要使用DMA_INT_FLAG_HTF来在缓冲区的一半传输完成时触发中断。

cen9ce 发表于 2025-6-9 10:25

在中断服务程序中,确保正确清除DMA中断标志。在中断中切换缓冲区,以便在下一个传输周期中使用另一个缓冲区。

l1uyn9b 发表于 2025-6-9 13:17

使用调试工具(如J-Link、ST-Link等)逐步调试,观察DMA传输的状态和中断触发情况。
页: [1]
查看完整版本: GD32F527 ADC DMA双缓冲存储