You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GD32F303R8T6的TIMER_0互补PWM配置异常求助

GD32F303R8T6高级定时器TIMER0 PWM输出异常排查

我是一名固件开发工程师,正在使用GD32F303R8T6微控制器控制无刷电机,计划通过高级定时器TIMER_0生成3组共6路(含互补信号)中心对齐PWM,参数要求如下:

  • 系统时钟(SYS_CLK):72MHz
  • PWM频率:8kHz
  • PWM模式:中心对齐

我分别采用直接操作寄存器和调用官方库函数两种方式配置TIMER_0,GPIO配置保持一致,但示波器仅能检测到CH0、CH2通道的有效PWM信号,CH1及所有互补通道(CH0N、CH1N、CH2N)均无输出。以下是相关配置代码、引脚定义及参考文档信息,恳请协助排查配置中的问题:

寄存器直接配置代码

// cleaning control registers
CLEAR_REG(TIMER_CTL0(TIMER0));
CLEAR_REG(TIMER_CTL1(TIMER0));

// [ CLT0: 0x00000075 ]
WRITE_REG(TIMER_CTL0(TIMER0),   TIMER_CTL0_UPS          |  
                TIMER_CTL0_CAM_0    |
                TIMER_CTL0_CAM_1    |
                0);
    
// [ CLT1: 0x00000070 ]
WRITE_REG(TIMER_CTL1(TIMER0),   TIMER_CTL1_MMC          | 
                0);

// [ DMAINTEN: 0x00000001 ]
WRITE_REG(TIMER_DMAINTEN(TIMER0), TIMER_DMAINTEN_UPIE);

// [ CHCTL0: 0x00006868 ]
WRITE_REG(TIMER_CHCTL0(TIMER0), TIMER_CHCTL0_CH0COMSEN          |
                TIMER_CHCTL0_CH0COMCTL_PWM0 |
                TIMER_CHCTL0_CH1COMSEN      |
                    TIMER_CHCTL0_CH1COMCTL_PWM0 |
                0);
// [ CHCTL1: 0x00006868 ]
WRITE_REG(TIMER_CHCTL1(TIMER0), TIMER_CHCTL1_CH2COMSEN          |
                TIMER_CHCTL1_CH2COMCTL_PWM0 |
                TIMER_CHCTL1_CH3COMSEN      |
                TIMER_CHCTL1_CH3COMCTL_PWM0 |
                0);

// enable of the 3 + 3 channels 
// [ CHCTL2: 0x00001555 ]
WRITE_REG(TIMER_CHCTL2(TIMER0), TIMER_CHCTL2_CH0EN      |
                TIMER_CHCTL2_CH0NEN |
                TIMER_CHCTL2_CH1EN  |
                TIMER_CHCTL2_CH1NEN |
                TIMER_CHCTL2_CH2EN  |
                TIMER_CHCTL2_CH2NEN |
                TIMER_CHCTL2_CH3EN  |
                0);

WRITE_REG(TIMER_PSC(TIMER0), 0);

// "autoreload register"
WRITE_REG(TIMER_CAR(TIMER0), 4500);

// set of Compare Value Registers
WRITE_REG(TIMER_CH0CV(TIMER0), 2250);
WRITE_REG(TIMER_CH1CV(TIMER0), 2250);
WRITE_REG(TIMER_CH2CV(TIMER0), 2250);
WRITE_REG(TIMER_CH3CV(TIMER0), 2250);

// [ CCHP: 0x00004088 ]
WRITE_REG(TIMER_CCHP(TIMER0),   TIMER_CCHP_OAEN     |
                //TIMER_CCHP_POEN   |
                //TIMER_CCHP_BRKEN  |
                //TIMER_CCHP_ROS    |
                TIMER_CCHP_DTCFG_88 |
                                0);
// enable counter (start PWM generation)
MODIFY_REG(TIMER_CTL0(TIMER0), TIMER_CTL0_CEN, TIMER_CTL0_CEN);

GPIO配置代码

// enable clock to GPIO A and B
    rcu_periph_clock_enable(RCU_GPIOA); 
rcu_periph_clock_enable(RCU_GPIOB);

// enable AF clock
rcu_periph_clock_enable(RCU_AF);

WRITE_REG(GPIO_CTL1(GPIOA),     GPIO_CTL1_MD8_1     |
                GPIO_CTL1_CTL8_2    |

                GPIO_CTL1_MD9_1     |
                GPIO_CTL1_CTL9_2    |

                GPIO_CTL1_MD10_1    |
                GPIO_CTL1_CTL10_2   |

                GPIO_CTL1_MD13_1    |
                GPIO_CTL1_CTL13_2   |

                GPIO_CTL1_MD14_1    |
                GPIO_CTL1_CTL14_2   |

                GPIO_CTL1_MD15_1    |
                GPIO_CTL1_CTL15_2   |
                0); 

TIMER_0 PWM引脚定义

  • PA8 [ CH0 ]
  • PA9 [ CH1 ]
  • PA10 [ CH2 ]
  • PB13 [ CH0N ]
  • PB14 [ CH1N ]
  • PB15 [ CH2N ]

库函数配置代码

/* -----------------------------------------------------------------------
TIMER0 configuration:
generate 3 complementary PWM signal.
TIMER0CLK is fixed to systemcoreclock, the TIMER0 prescaler is equal to 119 
so the TIMER0 counter clock used is 1MHz.
insert a dead time equal to 200/systemcoreclock =1.67us 
configure the break feature, active at low level, and using the automatic
output enable feature.
use the locking parameters level 0.
----------------------------------------------------------------------- */
timer_oc_parameter_struct timer_ocintpara;
timer_parameter_struct timer_initpara;
timer_break_parameter_struct timer_breakpara;

//rcu_periph_clock_enable(RCU_TIMER0);

timer_deinit(TIMER0);

/* TIMER0 configuration */
timer_initpara.prescaler         = 0;
timer_initpara.alignedmode       = TIMER_COUNTER_CENTER_BOTH;
timer_initpara.counterdirection  = TIMER_COUNTER_UP;
timer_initpara.period            = 4499;
timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER0,&timer_initpara);

/* CH0/CH0N,CH1/CH1N and CH2/CH2N configuration in timing mode */
timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
timer_ocintpara.outputnstate = TIMER_CCXN_ENABLE;
timer_ocintpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;
timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_HIGH;
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_HIGH;

timer_channel_output_config(TIMER0,TIMER_CH_0,&timer_ocintpara);
timer_channel_output_config(TIMER0,TIMER_CH_1,&timer_ocintpara);
timer_channel_output_config(TIMER0,TIMER_CH_2,&timer_ocintpara);

timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_0,2249);
timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(TIMER0,TIMER_CH_0,TIMER_OC_SHADOW_ENABLE);

timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_1,2249);
timer_channel_output_mode_config(TIMER0,TIMER_CH_1,TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(TIMER0,TIMER_CH_1,TIMER_OC_SHADOW_ENABLE);

timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_2,2249);
timer_channel_output_mode_config(TIMER0,TIMER_CH_2,TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(TIMER0,TIMER_CH_2,TIMER_OC_SHADOW_ENABLE);


/* automatic output enable, break, dead time and lock configuration*/
timer_breakpara.runoffstate      = TIMER_ROS_STATE_ENABLE;
timer_breakpara.ideloffstate     = TIMER_IOS_STATE_ENABLE ;
timer_breakpara.deadtime         = 164;
timer_breakpara.breakpolarity    = TIMER_BREAK_POLARITY_LOW;
timer_breakpara.outputautostate  = TIMER_OUTAUTO_ENABLE;
timer_breakpara.protectmode      = TIMER_CCHP_PROT_OFF;
timer_breakpara.breakstate       = TIMER_BREAK_DISABLE;
timer_break_config(TIMER0,&timer_breakpara);

/* TIMER0 primary output function enable */
timer_primary_output_config(TIMER0,ENABLE);

/* TIMER0 channel control update interrupt enable */
timer_interrupt_enable(TIMER0,TIMER_INT_CMT);
/* TIMER0 break interrupt disable */
timer_interrupt_disable(TIMER0,TIMER_INT_BRK);

/* TIMER0 counter enable */
timer_enable(TIMER0);

参考文档

  • GD32F30x用户手册
  • GD32F303xx数据手册
  • GigaDevice固件配置仓库内容

内容的提问来源于stack exchange,提问作者Aristide

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 17:45:55