GD32E230C8T6定时器输出比较中断触发与比较值不符!

[复制链接]
 楼主| MrZZS 发表于 2021-8-20 18:43 | 显示全部楼层 |阅读模式
在使用GD32E230这款芯片的时候,遇到了点问题,问题表现为:高级定时器timer0的非互补通道3的输出比较中断触发情况不正常,timer0的计数周期为1499,有效电平为高电平,输出比较模式为PWM2,在设置通道3比较器值为0的时候不进入比较中断,在设置比较器值为1-1499,大于1499都会触发该比较中断,如下是我的配置:
  1. void timer0_gpio_config(void)
  2. {
  3.     rcu_periph_clock_enable(RCU_GPIOA);
  4.     rcu_periph_clock_enable(RCU_GPIOB);

  5.     /*configure PA8/PA9/PA10(TIMER0/CH0/CH1/CH2) as alternate function*/
  6.     gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8);
  7.     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_8);

  8.     gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9);
  9.     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_9);

  10.     gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10);
  11.     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_10);
  12.        
  13.         gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11);
  14.   gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_11);

  15.     gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_8);
  16.     gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_9);
  17.     gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_10);
  18.         gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_11);

  19.     /*configure PB13/PB14/PB15(TIMER0/CH0N/CH1N/CH2N) as alternate function*/
  20.     gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13);
  21.     gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_13);

  22.     gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_14);
  23.     gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_14);

  24.     gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_15);
  25.     gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_15);

  26.     gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_13);
  27.     gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_14);
  28.     gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_15);

  29.     /*configure PB12(TIMER0 BKIN) as alternate function*/
  30.     gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12);
  31.     gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_12);
  32.     gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_12);
  33. }

  34. void timer0_config(void)
  35. {
  36.     /* -----------------------------------------------------------------------
  37.     TIMER0 configuration:
  38.     generate 3 complementary PWM signal.
  39.     TIMER0CLK is fixed to systemcoreclock, the TIMER0 prescaler is equal to 1
  40.     so the TIMER0 counter clock used is 72MHz.
  41.     insert a dead time equal to 164/systemcoreclock = 2.28us
  42.     configure the break feature, active at low level, and using the automatic
  43.     output enable feature.
  44.     use the locking parameters level 0.
  45.     ----------------------------------------------------------------------- */
  46.     timer_oc_parameter_struct timer_ocinitpara;
  47.     timer_parameter_struct timer_initpara;
  48.     timer_break_parameter_struct timer_breakpara;
  49.           /* enable the TIMER clock */
  50.     rcu_periph_clock_enable(RCU_TIMER0);
  51.                 /* deinit a TIMER */
  52.     timer_deinit(TIMER0);
  53.     /* initialize TIMER init parameter struct */
  54.     timer_struct_para_init(&timer_initpara);
  55.     /* TIMER0 configuration */
  56.     timer_initpara.prescaler         = 72 - 1;
  57.     timer_initpara.alignedmode       = TIMER_COUNTER_CENTER_UP;
  58.     timer_initpara.counterdirection  = TIMER_COUNTER_UP;
  59.     timer_initpara.period            = 1500 - 1;
  60.     timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
  61.     timer_initpara.repetitioncounter = 0;
  62.     timer_init(TIMER0, &timer_initpara);

  63.     /* initialize TIMER channel output parameter struct */
  64.     timer_channel_output_struct_para_init(&timer_ocinitpara);
  65.     /* CH0/CH0N, CH1/CH1N and CH2/CH2N configuration in timing mode */
  66.     timer_ocinitpara.outputstate  = TIMER_CCX_ENABLE;
  67.     timer_ocinitpara.outputnstate = TIMER_CCXN_ENABLE;
  68.     timer_ocinitpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;
  69.     timer_ocinitpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
  70.     timer_ocinitpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
  71.     timer_ocinitpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;

  72.     timer_channel_output_config(TIMER0, TIMER_CH_0, &timer_ocinitpara);
  73.     timer_channel_output_config(TIMER0, TIMER_CH_1, &timer_ocinitpara);
  74.     timer_channel_output_config(TIMER0, TIMER_CH_2, &timer_ocinitpara);
  75.                
  76.                 timer_ocinitpara.outputnstate = TIMER_CCXN_DISABLE;
  77.                 timer_channel_output_config(TIMER0, TIMER_CH_3, &timer_ocinitpara);

  78.     /* configure TIMER channel 0 */
  79.     timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_0, TIM0_DUTY_INIT - 1);
  80.     timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM1);                //PWM输出模式1
  81.     timer_channel_output_shadow_config(TIMER0, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE);
  82.    
  83.     /* configure TIMER channel 1 */
  84.     timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_1, TIM0_DUTY_INIT - 1);
  85.     timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM1);
  86.     timer_channel_output_shadow_config(TIMER0, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE);

  87.     /* configure TIMER channel 2 */
  88.     timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_2, TIM0_DUTY_INIT - 1);
  89.     timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_PWM1);
  90.     timer_channel_output_shadow_config(TIMER0, TIMER_CH_2, TIMER_OC_SHADOW_DISABLE);
  91.        
  92.                 /* configure TIMER channel 3 */
  93.     timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_3, 4000);
  94.     timer_channel_output_mode_config(TIMER0, TIMER_CH_3, TIMER_OC_MODE_PWM1);
  95.     timer_channel_output_shadow_config(TIMER0, TIMER_CH_3, TIMER_OC_SHADOW_DISABLE);

  96.     /* initialize TIMER break parameter struct */
  97.     timer_break_struct_para_init(&timer_breakpara);
  98.     /* automatic output enable, break, dead time and lock configuration*/
  99.     timer_breakpara.runoffstate      = TIMER_ROS_STATE_ENABLE;
  100.     timer_breakpara.ideloffstate     = TIMER_IOS_STATE_ENABLE;
  101.     timer_breakpara.deadtime         = DEAD_TIME;
  102.     timer_breakpara.breakpolarity    = TIMER_BREAK_POLARITY_LOW;
  103.     timer_breakpara.outputautostate  = TIMER_OUTAUTO_ENABLE;
  104.     timer_breakpara.protectmode      = TIMER_CCHP_PROT_OFF;      //互补寄存器写保护模式
  105.     timer_breakpara.breakstate       = TIMER_BREAK_ENABLE;
  106.     timer_break_config(TIMER0, &timer_breakpara);
  107.    
  108.     /* TIMER0 primary output function enable */
  109.     timer_primary_output_config(TIMER0, ENABLE);

  110.     /* TIMER0 break/channel interrupt enable */
  111.                 timer_interrupt_flag_clear(TIMER0, TIMER_INT_FLAG_BRK);
  112.                 timer_interrupt_flag_clear(TIMER0, TIMER_INT_FLAG_CH3);
  113.                 timer_interrupt_flag_clear(TIMER0, TIMER_INT_FLAG_UP);
  114.     timer_interrupt_enable(TIMER0, TIMER_INT_BRK);
  115.                 timer_interrupt_enable(TIMER0, TIMER_INT_CH3);
  116.                 timer_interrupt_enable(TIMER0, TIMER_INT_UP);
  117.                
  118.     /* TIMER0 counter enable */
  119.     timer_enable(TIMER0)
  120. }
配置通道3的比较器值为4000,大于计数周期1499,硬件Debug截图如下:

大图

大图

小图

小图

具体结果为:当通道3的比较器值设为4000,也会触发进入比较中断!且在调试句柄执行完标志清零语句后,通道中断标志位CH3IF仍然处于置位状态!!(可以参考图中红框标记)更改通道3的输出比较方式、有效电平极性产生的现象均相同!!只有在比较器值设为0的时候才不会进入中断!!!很迷惑,新人请教,希望大家帮帮忙解答!!!


 楼主| MrZZS 发表于 2021-8-20 18:46 | 显示全部楼层
该通道的中断服务函数如下:
  1. /****定时器中断服务函数************************************/
  2. void TIMER0_Channel_IRQHandler(void)
  3. {
  4. if(timer_interrupt_flag_get(TIMER0, TIMER_INT_FLAG_CH3) == SET)
  5. {
  6. timer0_flag_dir = (TIMER_CTL0(TIMER0) & (uint32_t)TIMER_CTL0_DIR) >> 4;
  7. timer_interrupt_flag_clear(TIMER0, TIMER_INT_FLAG_CH3);
  8. if(timer0_flag_dir == 0)
  9. {
  10. timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_0, buffer_ccr[0]);
  11. timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_1, buffer_ccr[1]);
  12. timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_2, buffer_ccr[2]);
  13. }
  14. else if(timer0_flag_dir == 1)
  15. {
  16. timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_0, buffer_ccr[3]);
  17. timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_1, buffer_ccr[4]);
  18. timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_2, buffer_ccr[5]);
  19. }
  20. }
  21. }


您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

2

帖子

0

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