GD32F527 ADC DMA双缓冲存储

[复制链接]
 楼主| 狂奔的蜗牛JJ 发表于 2025-5-4 16:08 | 显示全部楼层 |阅读模式
GD32, DMA, ADC, ig, AN, TI
我进行adc电压电流采样,想用双缓冲进行配置,目前adc_buffer0 里面数据实时更新,但是进不去中断,把初始化的DMA_INT_FLAG_FTF改成DMA_INT_FLAG_HTF 又可以进入中断了。这是为什么?
  1. #define BUFFER_SIZE     512
  2. #define ADC_CHANNEL_CNT 3
  3. #define DMA_BUFFER_SIZE   (ADC_CHANNEL_CNT * BUFFER_SIZE)
  4. void User_ADC_Init(void)
  5. {
  6.     /* ADC mode config */
  7.     adc_sync_mode_config(ADC_SYNC_MODE_INDEPENDENT);
  8.     /* ADC contineous function disable */
  9.     adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, ENABLE);
  10.     /* ADC scan mode disable */
  11.     adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);
  12.     /* ADC data alignment config */
  13.     adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
  14.    
  15.     /* ADC channel length config */
  16.     adc_channel_length_config(ADC0, ADC_ROUTINE_CHANNEL, 3);
  17.     /* ADC regular channel config */
  18.     adc_routine_channel_config(ADC0, 0, ADC_CHANNEL_13, ADC_SAMPLETIME_15);/* 电流采样 */
  19.     adc_routine_channel_config(ADC0, 1, ADC_CHANNEL_11, ADC_SAMPLETIME_15);/* 电压采样 */
  20.     adc_routine_channel_config(ADC0, 2, ADC_CHANNEL_12, ADC_SAMPLETIME_15);/* 参考电压1.65V采样 */
  21.     /* ADC trigger config */
  22.     adc_external_trigger_source_config(ADC0, ADC_ROUTINE_CHANNEL, ADC_EXTTRIG_ROUTINE_T0_CH0); ////////ADC_EXTTRIG_ROUTINE_T0_CH0
  23.     adc_external_trigger_config(ADC0, ADC_ROUTINE_CHANNEL, EXTERNAL_TRIGGER_DISABLE);///////
  24.    
  25.     /* ADC DMA function enable */
  26.     adc_dma_request_after_last_enable(ADC0);
  27.     adc_dma_mode_enable(ADC0);
  28.    
  29.     /* enable ADC interface */
  30.     adc_enable(ADC0);
  31.     /* wait for ADC stability */
  32.     delay1ms(2);
  33.     /* ADC calibration and reset calibration */
  34.     adc_calibration_enable(ADC0);
  35.    
  36.     /* enable ADC software trigger */
  37.     adc_software_trigger_enable(ADC0, ADC_ROUTINE_CHANNEL);
  38. }
  39. uint16_t adc_buffer0[DMA_BUFFER_SIZE];
  40. uint16_t adc_buffer1[DMA_BUFFER_SIZE];
  41. void User_DMA_Init(void)
  42. {
  43.     dma_single_data_parameter_struct dma_init_struct;

  44.         dma_deinit(DMA1, DMA_CH0);

  45.     dma_init_struct.periph_addr  = (uint32_t)&ADC_RDATA(ADC0);
  46.     dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
  47.     dma_init_struct.memory0_addr = (uint32_t)&adc_buffer0[0];
  48.     dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
  49.     dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_16BIT;
  50.     dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
  51.     dma_init_struct.number = ADC_CHANNEL_CNT * BUFFER_SIZE;
  52.     dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
  53.     dma_single_data_mode_init(DMA1, DMA_CH0, &dma_init_struct);
  54.     dma_channel_subperipheral_select(DMA1, DMA_CH0, DMA_SUBPERI0);

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

  58.     dma_circulation_disable(DMA1, DMA_CH0);
  59.     dma_channel_enable(DMA1, DMA_CH0);

  60.     /* 开启DMA传输完成中断 */
  61.     dma_interrupt_enable(DMA1, DMA_CH0, DMA_INT_FLAG_FTF);
  62.     nvic_irq_enable(DMA1_Channel0_IRQn, 1, 0);
  63. }
  64. void DMA1_Channel0_IRQHandler(void)
  65. {
  66.     if (dma_interrupt_flag_get(DMA1, DMA_CH0, DMA_INT_FLAG_FTF)==SET) {
  67.         dma_interrupt_flag_clear(DMA1, DMA_CH0, DMA_INT_FLAG_FTF);
  68.         dma_current_buffer = (dma_current_buffer == 0) ? 1 : 0;
  69.         buffer_ready_flag = 1;
  70.     }
  71. }
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传输的状态和中断触发情况。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

2

帖子

0

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

2

主题

2

帖子

0

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