GD32定时器级联与PWM生成,多路电机控制的捕获比较单元配置实例
一、程序原理说明
GD32系列MCU的定时器体系按功能复杂度分为三类:高级定时器(TIMER0/TIMER7)、通用定时器(TIMER1~TIMER4)和基础定时器(TIMER5/TIMER6)。三者共享相同的底层时钟树结构,但外围功能逐级增强。高级定时器在通用定时器基础上集成了互补PWM输出、死区插入、刹车机制和重复计数器,专为三相电机FOC控制设计。
定时器级联原理:GD32的定时器之间通过触发输出(TRGO)和触发输入(TRGI)信号链路实现硬件级同步。主定时器(Master)在特定事件(如更新事件、比较匹配事件)发生时,通过TRGO信号触发从定时器(Slave),从定时器可配置为"复位模式"——收到触发信号后计数器归零并重新开始计数。这种机制确保多个定时器的计数起点严格对齐,消除软件中断同步带来的抖动。在GD32F470等较新型号中,定时器之间还可以通过内部触发互联(ITI0~ITI3)实现更灵活的同步拓扑,部分型号还集成了事件互联单元(EVIC),可将定时器的通道事件路由到任意目标定时器,实现"一个时基同步全部TIMER"的硬件级同步方案。
PWM生成原理:PWM的核心是计数器CNT与捕获/比较寄存器CHxCV的比较机制。在PWM模式0下,当CNT < CHxCV时输出有效电平,CNT ≥ CHxCV时输出无效电平。PWM频率由自动重装载寄存器(CAR)决定:f_PWM = F_timer / ((PSC+1) × (CAR+1)),占空比由CHxCV/CAR的比值决定。 在中央对齐模式下,计数器先递增后递减,PWM频率为边沿对齐模式的一半,但谐波分布更优,适合电机控制。
多路电机控制的核心挑战:以三相无刷电机为例,需要3对互补PWM信号(6路输出),每对信号的占空比独立可调,且必须插入死区时间防止上下桥臂直通。高级定时器的3个通道(CH0/CH1/CH2)恰好对应三相(U/V/W),每通道输出一对互补PWM(CHx + CHxN),死区时间由timer_deadtime_config()统一配置。
二、程序框架
整个多路电机PWM驱动采用四层架构:
时钟与GPIO层:使能定时器时钟,配置PWM输出引脚为复用推挽模式,配置互补输出引脚和刹车引脚。
时基层:配置高级定时器的预分频器(PSC)、自动重装载值(CAR)、中央对齐模式和重复计数器,确定PWM频率和更新节奏。
输出比较层:为每个通道配置PWM模式、极性、死区时间和初始占空比,使能互补输出和主输出。
应用控制层:封装占空比动态修改接口,结合输入捕获实现编码器反馈和过零检测,形成闭环控制。
三、具体程序实现
以下基于GD32F303(120MHz主频),以TIMER0驱动三相电机PWM为例,演示完整配置流程。
1. 时钟与GPIO初始化
#include "gd32f30x.h"
void motor_pwm_gpio_config(void)
{
/* 使能GPIO和定时器时钟 */
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_AF);
rcu_periph_clock_enable(RCU_TIMER0);
/* TIMER0_CH0/CH1/CH2 → PA8/PA9/PA10(复用推挽输出) */
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ,
GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10);
/* TIMER0_CH0N/CH1N/CH2N → PB13/PB14/PB15(互补输出) */
gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ,
GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
/* 刹车引脚 PB12(浮空输入) */
gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
}
2. 高级定时器时基配置——20kHz中央对齐PWM
void motor_pwm_timer_config(void)
{
timer_parameter_struct timer_initpara;
timer_struct_para_init(&timer_initpara);
timer_deinit(TIMER0);
/* 定时器时钟 = 120MHz(APB2分频系数≠1时自动×2)
* PSC = 0 → 不分频,计数时钟 = 120MHz
* CAR = 5999 → PWM频率 = 120MHz / (2 × 6000) = 10kHz(中央对齐)
* 若需20kHz,则CAR = 2999 */
timer_initpara.prescaler = 0;
timer_initpara.alignedmode = TIMER_COUNTER_CENTER; /* 中央对齐 */
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 2999; /* 20kHz */
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0; /* 每周期更新一次 */
timer_init(TIMER0, &timer_initpara);
}
3. 三路互补PWM通道配置与死区插入
void motor_pwm_channel_config(void)
{
timer_oc_parameter_struct oc_initpara;
/* 三相通道统一配置 */
for (uint16_t ch = TIMER_CH_0; ch <= TIMER_CH_2; ch++) {
timer_channel_output_struct_para_init(&oc_initpara);
oc_initpara.outputstate = TIMER_CCX_ENABLE; /* 使能主输出 */
oc_initpara.outputnstate = TIMER_CCXN_ENABLE; /* 使能互补输出 */
oc_initpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
oc_initpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
oc_initpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;
oc_initpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
timer_channel_output_config(TIMER0, ch, &oc_initpara);
/* 初始占空比50% */
timer_channel_output_pulse_value_config(TIMER0, ch, 1500);
timer_channel_output_mode_config(TIMER0, ch, TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(TIMER0, ch, TIMER_OC_SHADOW_ENABLE);
}
/* 死区时间 = DTG / 120MHz,DTG由寄存器配置
* 典型值1~2μs,防止上下桥臂直通 */
timer_deadtime_config(TIMER0, 120); /* 120/120MHz = 1μs */
/* 刹车功能:PB12低电平触发,立即关断所有PWM输出 */
timer_break_config(TIMER0, TIMER_BREAK_ENABLE,
TIMER_BREAK_POLARITY_LOW,
TIMER_BREAK_LOCK_OFF);
/* 使能主输出(高级定时器必须调用此函数) */
timer_primary_output_config(TIMER0, ENABLE);
timer_enable(TIMER0);
}
4. 定时器级联——主从同步配置
/* 将TIMER0配置为主定时器,更新事件触发TIMER2从定时器 */
void timer_cascade_config(void)
{
/* TIMER0主模式:更新事件产生TRGO */
timer_master_output_trigger_source_select(TIMER0, TIMER_TRI_OUT_SRC_UPDATE);
/* TIMER2从模式:接收TRGI,复位模式——收到触发后计数器归零 */
timer_slave_mode_select(TIMER2, TIMER_SLAVE_MODE_RESTART);
timer_input_trigger_source_select(TIMER2, TIMER_SMCFG_TRGSEL_ITI0);
/* ITI0 = TIMER0的内部触发输出 */
}
5. 输入捕获——编码器反馈接口
/* TIMER2_CH0输入捕获:测量编码器脉冲间隔 */
timer_ic_parameter_struct ic_initpara;
void encoder_capture_config(void)
{
rcu_periph_clock_enable(RCU_TIMER2);
/* PA0 → TIMER2_CH0(浮空输入) */
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_0);
timer_parameter_struct timer_initpara;
timer_struct_para_init(&timer_initpara);
timer_deinit(TIMER2);
timer_initpara.prescaler = 119; /* 120MHz/120 = 1MHz计数时钟 */
timer_initpara.period = 0xFFFF;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_init(TIMER2, &timer_initpara);
timer_channel_input_struct_para_init(&ic_initpara);
ic_initpara.icpolarity = TIMER_IC_POLARITY_RISING;
ic_initpara.icselection = TIMER_IC_SELECTION_DIRECTTI;
ic_initpara.icprescaler = TIMER_IC_PSC_DIV1;
ic_initpara.icfilter = 0x0F; /* 8个连续采样确认,抗干扰 */
timer_input_capture_config(TIMER2, TIMER_CH_0, &ic_initpara);
timer_interrupt_enable(TIMER2, TIMER_INT_CH0);
nvic_irq_enable(TIMER2_IRQn, 1, 0);
timer_enable(TIMER2);
}
/* 捕获中断:计算转速 */
volatile uint32_t capture_val1 = 0, capture_val2 = 0;
void TIMER2_IRQHandler(void)
{
if (timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_CH0) != RESET) {
capture_val2 = timer_channel_capture_value_register_read(TIMER2, TIMER_CH_0);
uint32_t interval = (capture_val2 >= capture_val1) ?
(capture_val2 - capture_val1) :
(0xFFFF - capture_val1 + capture_val2 + 1);
/* 转速 = 60 / (interval × 每转脉冲数) */
capture_val1 = capture_val2;
timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_CH0);
}
}
6. 运行时占空比动态修改
/* 设置三相占空比(0~10000对应0%~100%) */
void motor_set_duty(uint16_t duty_u, uint16_t duty_v, uint16_t duty_w)
{
timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_0, duty_u);
timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_1, duty_v);
timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_2, duty_w);
}
四、关键工程要点
影子寄存器机制:GD32的CHxCV和CAR寄存器均有影子寄存器。使能影子寄存器后(TIMER_OC_SHADOW_ENABLE),运行时修改占空比不会立即生效,而是在下一个更新事件(计数器溢出)时统一加载,避免PWM波形出现毛刺。对于电机控制,这一特性至关重要——它确保SVPWM算法计算的三相占空比在同一时刻同步更新。
死区时间的精确计算:死区时间由timer_deadtime_config()的DTG参数决定,计算公式与CKDIV分频因子相关。在CKDIV=1、定时器时钟120MHz时,DTG=120对应1μs死区。实际设计中需根据MOSFET/IGBT的开关特性(通常0.5~2μs)选择合适值,过小会导致直通,过大会降低有效占空比范围。
中央对齐模式的优势:相比边沿对齐,中央对齐模式下PWM谐波集中在开关频率的偶数倍附近,对电机绕组的电流纹波更小;同时计数器在峰值和谷值处各产生一次更新事件,为ADC采样和FOC计算提供了天然的对称采样点。
定时器级联的时序精度:硬件级联同步的精度可达1个定时器时钟周期(本例中约8.3ns),远优于软件中断同步(受中断延迟影响,抖动通常在数百纳秒级)。在多电机协同控制、交错并联电源等对相位关系有严格要求的场景中,定时器级联是不可替代的方案。
GD32的定时器体系通过"高级定时器PWM输出 + 定时器级联同步 + 输入捕获反馈"的三位一体架构,为多路电机控制提供了从信号生成到闭环反馈的完整硬件支撑。掌握时基配置、输出比较和级联同步三大核心环节,是构建高性能电机驱动系统的工程基石。





