STM32F103定时器主从模式实战:5分钟生成带死区的H桥驱动PWM
在电机控制和电源转换领域,H桥电路的设计与实现一直是工程师们面临的常见挑战。如何高效生成两路精确互补且带有可调死区的PWM信号,直接关系到系统的可靠性和效率。传统方法往往需要复杂的软件干预或外部逻辑电路,而STM32F103系列内置的高级定时器功能,可以优雅地解决这一难题。
1. H桥驱动与死区时间的核心要义
任何使用MOSFET或IGBT构建的H桥电路,都面临一个基本安全要求:防止同一桥臂的上下管直通短路。以典型的全桥逆变电路为例:
- 上管S1和下管S4组成左桥臂
- 上管S2和下管S3组成右桥臂
- 理想状态下,S1/S4和S2/S3应交替导通
实际应用中必须考虑开关管的关断延迟(Turn-off delay)特性。当PWM信号从高电平变为低电平时,开关管不会立即关断,而是存在微秒级的延迟。如果互补信号切换时没有保护间隔,就会导致上下管短暂同时导通,形成直通电流。
死区时间设置需考虑器件规格:普通MOSFET约需500ns-1μs,IGBT可能需要2-3μs。具体值应查阅器件手册的Turn-off delay参数。
2. STM32定时器主从模式架构解析
STM32F103的TIM1和TIM2定时器组合,通过主从同步机制可完美实现互补PWM生成。其核心配置逻辑如下:
// 主定时器TIM1基础配置 TIM_TimeBaseStructure.TIM_Period = 999; // PWM周期=1000计数 TIM_TimeBaseStructure.TIM_Prescaler = 71; // 72MHz/(71+1)=1MHz TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); // 从定时器TIM2配置 TIM_TimeBaseStructure.TIM_Period = 999; // 与主定时器同步 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);关键寄存器配置要点:
| 寄存器 | 功能说明 | 典型值 |
|---|---|---|
| TIM1_CR2 | 主模式输出选择 | MMS=0x0100 |
| TIM2_SMCR | 从模式选择与触发源 | SMS=0x0100 |
| TIM1_CCMR1 | PWM模式设置 | OC1M=0x0110 |
| TIM1_BDTR | 死区时间配置 | DTG[7:0] |
3. 完整实现:从寄存器到波形验证
3.1 硬件连接与引脚配置
典型应用场景下,我们使用TIM1_CH1N和TIM1_CH2输出互补PWM:
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; // TIM1_CH1/CH2 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); // 死区时间计算示例(72MHz时钟): // DTG[7:0] = 0x18 → 死区=24*125ns=3μs TIM1->BDTR |= (0x18 << 0) | TIM_BDTR_MOE;3.2 主从定时器同步机制
实现相位精确控制的秘诀在于触发信号的合理利用:
- TIM1配置为PWM模式1,CH1输出主PWM
- TIM1_CH2配置为PWM模式2,比较值设为周期一半
- TIM1_CH2的REF信号作为TIM2的触发源
- TIM2工作在复位模式,实现相位锁定
// TIM1通道2配置为触发源 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_Pulse = 500; // 50%占空比 TIM_OC2Init(TIM1, &TIM_OCInitStructure); // TIM2从模式配置 TIM_SelectInputTrigger(TIM2, TIM_TS_ITR1); // 内部触发1→TIM13.3 逻辑分析仪验证技巧
使用PulseView或Saleae逻辑分析仪时,重点关注:
- 两路PWM的相位差是否稳定180°
- 死区时间是否与配置值一致
- 上升/下降沿是否有振荡(需优化PCB布局)
典型问题排查表:
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 死区时间不生效 | BDTR寄存器未使能MOE位 | 检查TIM1->BDTR配置 |
| 两路PWM不同步 | 触发源选择错误 | 确认TIM_TS_ITRx设置 |
| 波形畸变 | 引脚负载过大 | 增加栅极驱动电路 |
4. 高级应用与性能优化
4.1 动态调整死区时间
通过运行时修改BDTR寄存器,可适应不同工况:
void Adjust_DeadTime(uint8_t dtg_val) { TIM1->BDTR &= ~(0xFF << 0); // 清除DTG位 TIM1->BDTR |= (dtg_val << 0) | TIM_BDTR_MOE; }4.2 移相全桥的特殊处理
对于需要相位控制的移相全桥应用,可通过修改TIM2的比较值实现:
// 设置移相角度(0-360°) void Set_PhaseShift(float degree) { uint16_t shift = (uint16_t)(999 * degree / 360); TIM_SetCompare1(TIM2, shift); }实际项目中,建议将关键参数封装为结构体,便于管理:
typedef struct { uint32_t frequency; // PWM频率 uint16_t deadtime; // 死区时间ns float duty; // 占空比0-1 float phase; // 移相角度0-360 } PWM_Config_t;在电机驱动实践中,这套方案已经过验证可稳定驱动500W以下的BLDC电机。有个细节值得注意:当PWM频率超过20kHz时,建议启用定时器的预装载功能(TIM_ARRPreloadConfig),以避免修改参数时的波形抖动。