GD32F527 ADC DMA 双缓冲 buffer不转换

[复制链接]
 楼主| 狂奔的蜗牛JJ 发表于 2025-5-4 19:04 | 显示全部楼层 |阅读模式
  1. #define BUFFER_SIZE     512
  2. #define ADC_CHANNEL_CNT 3
  3. #define DMA_BUFFER_SIZE   (ADC_CHANNEL_CNT * BUFFER_SIZE)
  4. uint16_t adc_buffer0[DMA_BUFFER_SIZE];
  5. uint16_t adc_buffer1[DMA_BUFFER_SIZE];
  6. void User_DMA_Init(void)
  7. {
  8.     dma_single_data_parameter_struct dma_init_struct;

  9.         dma_deinit(DMA1, DMA_CH0);

  10.     dma_init_struct.periph_addr  = (uint32_t)&ADC_RDATA(ADC0);
  11.     dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
  12.     dma_init_struct.memory0_addr = (uint32_t)&adc_buffer0[0];
  13.     dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
  14.     dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_16BIT;
  15.     dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
  16.     dma_init_struct.number = ADC_CHANNEL_CNT * BUFFER_SIZE;
  17.     dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
  18.     dma_single_data_mode_init(DMA1, DMA_CH0, &dma_init_struct);
  19.     dma_channel_subperipheral_select(DMA1, DMA_CH0, DMA_SUBPERI0);

  20.     /* 启用双缓冲 */
  21.         dma_memory_address_config(DMA1, DMA_CH0, (uint32_t)&adc_buffer1[0], DMA_MEMORY_1);
  22.         dma_switch_buffer_mode_enable(DMA1, DMA_CH0, ENABLE);

  23.     dma_circulation_disable(DMA1, DMA_CH0);
  24.     dma_channel_enable(DMA1, DMA_CH0);

  25.     /* 开启DMA传输完成中断 */
  26.     dma_interrupt_enable(DMA1, DMA_CH0, DMA_INT_HTF);
  27.     nvic_irq_enable(DMA1_Channel0_IRQn, 1, 0);
  28. }

  29. void TIMER1_IRQHandler(void)
  30. {
  31.     if (SET == timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_UP)) {
  32.        // __disable_irq();

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

  34.         if (sample_Flag == 0) {
  35.             sample_Flag = 1;
  36.             sample_count = 0;
  37.         }

  38.         if (sample_Flag == 1 && buffer_ready_flag) {
  39.             buffer_ready_flag = 0;

  40.             for (int i = 0; i < BUFFER_SIZE; i++) {
  41.                 adc_table.CurVol[sample_count].cur = active_buffer[i * 3 + 0] - active_buffer[i * 3 + 2];
  42.                 adc_table.CurVol[sample_count].vol = active_buffer[i * 3 + 1] - active_buffer[i * 3 + 2];
  43.                 sample_count++;
  44.             }

  45.             if (sample_count >= 512) {
  46.                 sample_Flag = 2;  // 表示采集完了
  47.                 sample_count = 0;
  48.             }
  49.         }

  50.        // __enable_irq();
  51.         T_counts++;
  52.         timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_UP);
  53.     }
  54. }
  55. void DMA1_Channel0_IRQHandler(void)
  56. {
  57.     if (dma_interrupt_flag_get(DMA1, DMA_CH0, DMA_INT_FLAG_HTF)==SET) {
  58.         dma_interrupt_flag_clear(DMA1, DMA_CH0, DMA_INT_FLAG_HTF);
  59.         dma_current_buffer = (dma_current_buffer == 0) ? 1 : 0;
  60.         buffer_ready_flag = 1;
  61.     }
  62. }

能不能不要删帖子了,为什么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硬件的当前缓冲区一致。
carlchendtyd 发表于 2025-7-1 15:19 | 显示全部楼层
大佬,我用GD32F470也不能buff1有数据,问题解决了吗?
carlchendtyd 发表于 2025-7-1 15:46 | 显示全部楼层
dma_memory_address_config()。第3个参数和第4个参数反了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

2

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

2

主题

2

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部