GD32F103C8 ADC 外部触发(TIM1_TRGO)无法触发中断,软件触发正常的问题, 急急😭😭

[复制链接]
96|2
aademac 发表于 2025-10-4 07:13 | 显示全部楼层 |阅读模式
本帖最后由 aademac 于 2025-10-4 07:38 编辑

各位坛友,大家好!
我在使用 GD32F103C8 的 ADC 模块时遇到一个问题,想向大家请教一下。
问题描述我尝试使用 TIM1 的 TRGO 信号作为 ADC0 注入通道的外部触发源,但始终无法触发 ADC 中断。然而,当我改用软件触发 ADC 注入通道时,一切工作正常,中断能够正常响应并正确读取转换结果。
相关代码以下是使用 TIM1_TRGO 作为外部触发源的代码:
  1. volatile float vbat = 0.0f;             // 获取当前电池电量   

  2. static void TIM1_TRGO_Init(void);
  3. static void ADC0_Init(void);

  4. //
  5. // @简介:对电池电压检测模块进行初始化
  6. //
  7. void App_Bat_init(void)
  8. {
  9.     TIM1_TRGO_Init();
  10.     ADC0_Init();
  11. }

  12. static void TIM1_TRGO_Init(void)
  13. {
  14.     // #1. 初始化TIM1_TRGO,每10ms产生一个脉冲
  15.     rcu_periph_clock_enable(RCU_TIMER1);
  16.    
  17.     timer_deinit(TIMER1);
  18.    
  19.     timer_parameter_struct timer_initpara;
  20.    
  21.     timer_initpara.prescaler     = 71;
  22.     timer_initpara.period        = 9999;
  23.     timer_initpara.counterdirection   = TIMER_COUNTER_UP;
  24.     timer_initpara.repetitioncounter  = 0;
  25.     timer_init(TIMER1, &timer_initpara);
  26.    
  27.     timer_auto_reload_shadow_enable(TIMER1);
  28.     timer_master_slave_mode_config(TIMER1, TIMER_MASTER_SLAVE_MODE_ENABLE);
  29.    
  30.     // 选择主机模式为update模式
  31.     timer_master_output_trigger_source_select(TIMER1, TIMER_TRI_OUT_SRC_UPDATE);
  32.    
  33.     // 闭合时基单元的开关
  34.     timer_enable(TIMER1);
  35. }

  36. static void ADC0_Init(void)
  37. {
  38.     // #1. 初始化PB0引脚,模拟模式
  39.     rcu_periph_clock_enable(RCU_GPIOB);
  40.     gpio_init(GPIOB, GPIO_MODE_AIN, GPIO_OSPEED_2MHZ, GPIO_PIN_0);
  41.    
  42.     // #2. 配置ADC模块的时钟
  43.     rcu_periph_clock_enable(RCU_ADC0);    // 使能ADC0的时钟
  44.     rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV6); // 设置分频器的分频系数(6分频)  72 / 6 = 12
  45.    
  46.     // #3. 初始化ADC的基本参数
  47.     adc_mode_config(ADC_MODE_FREE);      // 只使用一个ADC,属于独立模式
  48.     adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);   // 结果转换右对齐
  49.     adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, DISABLE);     // 关闭连续转换模式
  50.     adc_special_function_config(ADC0, ADC_SCAN_MODE, DISABLE);           // 关闭扫描模式
  51.    

  52.     adc_channel_length_config(ADC0, ADC_INSERTED_CHANNEL, 1);
  53.     adc_external_trigger_source_config(ADC0, ADC_INSERTED_CHANNEL, ADC0_1_EXTTRIG_INSERTED_T1_TRGO);   
  54.     adc_external_trigger_config(ADC0, ADC_INSERTED_CHANNEL, ENABLE);
  55.    
  56.     adc_inserted_channel_config(ADC0, 0, ADC_CHANNEL_8, ADC_SAMPLETIME_1POINT5);
  57.    
  58.     adc_enable(ADC0);
  59.     adc_calibration_enable(ADC0);
  60.    
  61.     adc_interrupt_enable(ADC0, ADC_INT_EOIC);
  62.     nvic_irq_enable(ADC0_1_IRQn, 0, 0);
  63. }

  64. void ADC0_1_IRQHandler(void)
  65. {
  66.     if (adc_interrupt_flag_get(ADC0, ADC_INT_FLAG_EOIC) == SET)
  67.     {
  68.         adc_interrupt_flag_clear(ADC0, ADC_INT_FLAG_EOIC);
  69.         
  70.         uint16_t jdr1 = adc_inserted_data_read(ADC0, ADC_INSERTED_CHANNEL_0);
  71.         vbat = jdr1 / 4095.0f *3.3 * 8.4f / 3.3;
  72.         
  73.         printf("%.3f\n",vbat);
  74.     }
  75.    
  76. }

  77. int main()
  78. {
  79.     nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
  80.    
  81.     SysTickTimer2_Init();
  82.    
  83.     App_USART1_Init();
  84.     App_Bat_init();
  85.    
  86.     while(1)
  87.     {
  88.     }

  89. }

改用软件触发后能正常工作的代码:
  1. volatile float vbat = 0.0f;             // 获取当前电池电量   

  2. static void TIM1_TRGO_Init(void);
  3. static void ADC0_Init(void);

  4. //
  5. // @简介:对电池电压检测模块进行初始化
  6. //
  7. void App_Bat_init(void)
  8. {
  9.     ADC0_Init();
  10. }

  11. static void ADC0_Init(void)
  12. {
  13.     // #1. 初始化PB0引脚,模拟模式
  14.     rcu_periph_clock_enable(RCU_GPIOB);
  15.     gpio_init(GPIOB, GPIO_MODE_AIN, GPIO_OSPEED_2MHZ, GPIO_PIN_0);
  16.    
  17.     // #2. 配置ADC模块的时钟
  18.     rcu_periph_clock_enable(RCU_ADC0);    // 使能ADC0的时钟
  19.     rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV6); // 设置分频器的分频系数(6分频)  72 / 6 = 12
  20.    
  21.     // #3. 初始化ADC的基本参数
  22.     adc_mode_config(ADC_MODE_FREE);      // 只使用一个ADC,属于独立模式
  23.     adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);   // 结果转换右对齐
  24.     adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, DISABLE);     // 关闭连续转换模式
  25.     adc_special_function_config(ADC0, ADC_SCAN_MODE, DISABLE);           // 关闭扫描模式
  26.    

  27.     adc_channel_length_config(ADC0, ADC_INSERTED_CHANNEL, 1);
  28.     adc_external_trigger_source_config(ADC0, ADC_INSERTED_CHANNEL, ADC0_1_2_EXTTRIG_INSERTED_NONE);
  29.     adc_external_trigger_config(ADC0, ADC_INSERTED_CHANNEL, ENABLE);
  30.    
  31.     adc_inserted_channel_config(ADC0, 0, ADC_CHANNEL_8, ADC_SAMPLETIME_1POINT5);
  32.    
  33.     adc_enable(ADC0);
  34.     adc_calibration_enable(ADC0);
  35.    
  36.     adc_interrupt_enable(ADC0, ADC_INT_EOIC);
  37.     nvic_irq_enable(ADC0_1_IRQn, 0, 0);
  38. }

  39. void ADC0_1_IRQHandler(void)
  40. {
  41.     if (adc_interrupt_flag_get(ADC0, ADC_INT_FLAG_EOIC) == SET)
  42.     {
  43.         adc_interrupt_flag_clear(ADC0, ADC_INT_FLAG_EOIC);
  44.         
  45.         uint16_t jdr1 = adc_inserted_data_read(ADC0, ADC_INSERTED_CHANNEL_0);
  46.         vbat = jdr1 / 4095.0f *3.3 * 8.4f / 3.3;
  47.         
  48.         printf("%.3f\n",vbat);
  49.     }
  50.    
  51. }

  52. int main()
  53. {
  54.     nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
  55.    
  56.     SysTickTimer2_Init();
  57.    
  58.     App_USART1_Init();
  59.     App_Bat_init();
  60.    
  61.     while(1)
  62.     {
  63.         uint32_t now = GetTick();        // 获取系统当前时间 毫秒级
  64.         if (now - last_time > 10)        // 10毫秒触发一次   
  65.         {
  66.             last_time = now;
  67.             adc_software_trigger_enable(ADC0, ADC_INSERTED_CHANNEL);        // 通过软件启动的方式发送脉冲
  68.         }
  69.     }

  70. }

  • 方库文件gd32f10x_adc.c,确认 ADC0 的注入通道支持 TIM1_TRGO 作为触发源(ADC0_1_EXTTRIG_INSERTED_T1_TRGO)。
  • 软件触发工作正常,说明 ADC 的基本配置、通道选择、中断配置应该是正确的。
  • TIM1 的配置看起来正确,应该能产生 TRGO 信号。
请问各位,可能是什么原因导致外部触发无法工作呢?是否有什么配置细节我忽略了?
感谢大家的帮助!


 楼主| aademac 发表于 2025-10-4 07:17 | 显示全部楼层
本帖最后由 aademac 于 2025-10-4 07:26 编辑

但我查阅了
  1. Drivers\GD32F10x_standard_peripheral\Source\gd32f10x_adc.c

, 明明支持di。但我始终就无法成功,我也翻阅了代码库配套的示例,但没发现该用例使用的例程,求救求救
  1. /*!
  2.     \brief      configure ADC external trigger source
  3.     \param[in]  adc_periph: ADCx, x=0,1,2
  4.     \param[in]  adc_channel_group: select the channel group
  5.                 only one parameter can be selected which is shown as below:
  6.       \arg        ADC_REGULAR_CHANNEL: regular channel group
  7.       \arg        ADC_INSERTED_CHANNEL: inserted channel group
  8.     \param[in]  external_trigger_source: regular or inserted group trigger source
  9.                 only one parameter can be selected
  10.                 for regular channel:
  11.       \arg        ADC0_1_EXTTRIG_REGULAR_T0_CH0: TIMER0 CH0 event select
  12.       \arg        ADC0_1_EXTTRIG_REGULAR_T0_CH1: TIMER0 CH1 event select
  13.       \arg        ADC0_1_EXTTRIG_REGULAR_T0_CH2: TIMER0 CH2 event select
  14.       \arg        ADC0_1_EXTTRIG_REGULAR_T1_CH1: TIMER1 CH1 event select
  15.       \arg        ADC0_1_EXTTRIG_REGULAR_T2_TRGO: TIMER2 TRGO event select
  16.       \arg        ADC0_1_EXTTRIG_REGULAR_T3_CH3: TIMER3 CH3 event select
  17.       \arg        ADC0_1_EXTTRIG_REGULAR_T7_TRGO: TIMER7 TRGO event select
  18.       \arg        ADC0_1_EXTTRIG_REGULAR_EXTI_11: external interrupt line 11
  19.       \arg        ADC2_EXTTRIG_REGULAR_T2_CH0: TIMER2 CH0 event select
  20.       \arg        ADC2_EXTTRIG_REGULAR_T1_CH2: TIMER1 CH2 event select
  21.       \arg        ADC2_EXTTRIG_REGULAR_T0_CH2: TIMER0 CH2 event select
  22.       \arg        ADC2_EXTTRIG_REGULAR_T7_CH0: TIMER7 CH0 event select
  23.       \arg        ADC2_EXTTRIG_REGULAR_T7_TRGO: TIMER7 TRGO event select
  24.       \arg        ADC2_EXTTRIG_REGULAR_T4_CH0: TIMER4 CH0 event select
  25.       \arg        ADC2_EXTTRIG_REGULAR_T4_CH2: TIMER4 CH2 event select
  26.       \arg        ADC0_1_2_EXTTRIG_REGULAR_NONE: software trigger      
  27.                 for inserted channel:
  28.       \arg        ADC0_1_EXTTRIG_INSERTED_T0_TRGO: TIMER0 TRGO event select
  29.       \arg        ADC0_1_EXTTRIG_INSERTED_T0_CH3: TIMER0 CH3 event select
  30.       \arg        ADC0_1_EXTTRIG_INSERTED_T1_TRGO: TIMER1 TRGO event select
  31.       \arg        ADC0_1_EXTTRIG_INSERTED_T1_CH0: TIMER1 CH0 event select
  32.       \arg        ADC0_1_EXTTRIG_INSERTED_T2_CH3: TIMER2 CH3 event select
  33.       \arg        ADC0_1_EXTTRIG_INSERTED_T3_TRGO: TIMER3 TRGO event select
  34.       \arg        ADC0_1_EXTTRIG_INSERTED_EXTI_15: external interrupt line 15
  35.       \arg        ADC0_1_EXTTRIG_INSERTED_T7_CH3: TIMER7 CH3 event select
  36.       \arg        ADC2_EXTTRIG_INSERTED_T0_TRGO: TIMER0 TRGO event select
  37.       \arg        ADC2_EXTTRIG_INSERTED_T0_CH3: TIMER0 CH3 event select
  38.       \arg        ADC2_EXTTRIG_INSERTED_T3_CH2: TIMER3 CH2 event select
  39.       \arg        ADC2_EXTTRIG_INSERTED_T7_CH1: TIMER7 CH1 event select
  40.       \arg        ADC2_EXTTRIG_INSERTED_T7_CH3: TIMER7 CH3 event select
  41.       \arg        ADC2_EXTTRIG_INSERTED_T4_TRGO: TIMER4 TRGO event select
  42.       \arg        ADC2_EXTTRIG_INSERTED_T4_CH3: TIMER4 CH3 event select
  43.       \arg        ADC0_1_2_EXTTRIG_INSERTED_NONE: software trigger      
  44.     \param[out] none
  45.     \retval     none
  46. */
  47. void adc_external_trigger_source_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t external_trigger_source)
 楼主| aademac 发表于 2025-10-4 09:53 | 显示全部楼层
补充, 当前我使用的是
  1. GD32F10x_Firmware_Library_V2.5.0
版本 😭😭
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

7

帖子

0

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