狂奔的蜗牛JJ 发表于 2025-5-4 19:04

GD32F527 ADC DMA 双缓冲 buffer不转换

#define BUFFER_SIZE   512
#define ADC_CHANNEL_CNT 3
#define DMA_BUFFER_SIZE   (ADC_CHANNEL_CNT * BUFFER_SIZE)
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_HTF);
    nvic_irq_enable(DMA1_Channel0_IRQn, 1, 0);
}

void TIMER1_IRQHandler(void)
{
    if (SET == timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_UP)) {
       // __disable_irq();

      uint16_t *active_buffer = (dma_current_buffer == 0) ? adc_buffer1 : adc_buffer0;

      if (sample_Flag == 0) {
            sample_Flag = 1;
            sample_count = 0;
      }

      if (sample_Flag == 1 && buffer_ready_flag) {
            buffer_ready_flag = 0;

            for (int i = 0; i < BUFFER_SIZE; i++) {
                adc_table.CurVol.cur = active_buffer - active_buffer;
                adc_table.CurVol.vol = active_buffer - active_buffer;
                sample_count++;
            }

            if (sample_count >= 512) {
                sample_Flag = 2;// 表示采集完了
                sample_count = 0;
            }
      }

       // __enable_irq();
      T_counts++;
      timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_UP);
    }
}
void DMA1_Channel0_IRQHandler(void)
{
    if (dma_interrupt_flag_get(DMA1, DMA_CH0, DMA_INT_FLAG_HTF)==SET) {
      dma_interrupt_flag_clear(DMA1, DMA_CH0, DMA_INT_FLAG_HTF);
      dma_current_buffer = (dma_current_buffer == 0) ? 1 : 0;
      buffer_ready_flag = 1;
    }
}

能不能不要删帖子了,为什么adc_buffer0值可以更新,buffer1值不能更新?

powerantone 发表于 2025-5-9 12:46

本帖最后由 powerantone 于 2025-5-9 12:48 编辑

可能是DMA中断标志配置错误。

stormwind123 发表于 2025-5-9 14:00

检查是否已正确配置触发源,并确认触发使能位已设置。

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

可能未正确配置双缓冲模式下的存储区指针,或未启用双缓冲模式,导致数据无法在两个缓冲区之间切换。

stormwind123 发表于 2025-5-9 17:00

DMA的传输方向配置错误,或数据对齐方式与实际数据格式不匹配,都可能导致传输失败。

classroom 发表于 2025-5-9 17:23

检查中断服务程序的处理逻辑,在中断发生时能正确处理数据并更新缓冲区指针。

probedog 发表于 2025-5-9 21:00

ADC的触发源配置错误,或DMA的传输时序与ADC的转换完成信号不同步,也可能导致数据无法正确传输。

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

你代码里没有看到dma_current_buffer的初始化,务必确认初始化为0或1,且初值要与你DMA硬件的当前缓冲区一致。
页: [1]
查看完整版本: GD32F527 ADC DMA 双缓冲 buffer不转换