1. 项目概述:从芯片选型到三相逆变
最近在电力电子领域折腾STM32F103系列实现SPWM三相逆变,发现这颗性价比爆表的Cortex-M3芯片在电机控制领域确实有不少玩法。以STM32F103C6T6/C8T6为例,虽然它们只是64/128KB Flash的入门款,但配合定时器和DMA,完全能实现高精度的正弦脉宽调制(SPWM)输出。
三相逆变本质上是通过六路PWM波控制三个桥臂的开关管,将直流电转换为相位差120°的三相交流电。而SPWM技术通过调制正弦波与三角载波的比较值,让PWM脉冲宽度按正弦规律变化,最终经LC滤波后输出近似正弦的电压波形。这种方案在变频器、UPS、新能源发电等场景应用广泛。
2. 硬件设计关键点解析
2.1 主控芯片选型对比
STM32F103C6T6和C8T6的主要差异在于Flash容量(64KB vs 128KB)和GPIO数量。对于三相逆变应用:
- C6T6:48引脚封装,3个通用定时器(TIM2/3/4)+1个高级定时器(TIM1),PWM通道足够驱动单相全桥
- C8T6:同样封装但资源更充裕,适合需要复杂保护算法的场景
实测发现,在72MHz主频下,两者PWM分辨率都能达到纳秒级,但C8T6的额外Flash空间更适合存储多组SPWM波形表或加入故障检测代码。
2.2 功率电路设计要点
典型的三相全桥拓扑需要:
- 6个MOSFET/IGBT(如IRF540N)
- 3路隔离驱动(常用IR2101S)
- 直流母线电容(1000μF电解电容并联104瓷片电容)
- LC滤波器(电感约2.2mH,电容4.7μF)
特别注意:
死区时间必须设置合理(通常300-500ns),否则会导致上下管直通烧毁MOSFET。可通过TIMx_BDTR寄存器的DTG位配置。
3. 软件实现核心逻辑
3.1 SPWM波形生成方案
有两种主流实现方式:
-
查表法:
- 预计算正弦波采样值存入数组
- 通过定时器触发DMA自动搬运到CCR寄存器
- 优点:CPU占用率低,波形失真小
- 示例代码:
c复制uint16_t sin_table[360]; // 1°分辨率 HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_1, (uint32_t*)sin_table, 360);
-
实时计算法:
- 在定时器中断中动态计算CCR值
- 优点:可实时调整频率和幅值
- 关键公式:
math复制其中M为调制比(0~1),f为输出频率CCR = (PWM_PERIOD / 2) * (1 + M * sin(2πft))
3.2 三相互锁实现
要生成相位差120°的三相波形:
- 创建三个相位偏移的正弦表
- 使用TIM1的CH1/CH2/CH3输出主相位
- 通过TIM1的刹车功能(BRK)实现硬件互锁
- 配置TIM1的重复计数器实现载波周期同步
关键寄存器配置:
c复制TIM1->CCMR1 |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1; // PWM模式1
TIM1->BDTR |= TIM_BDTR_MOE | TIM_BDTR_OSSR; // 主输出使能
4. 实测问题与优化方案
4.1 波形失真改善
初期测试发现的典型问题:
- 三次谐波:由于中性点浮动导致,可通过注入三次谐波补偿
- 死区效应:引入非线性失真,需软件预补偿
- 载波比过低:建议载波频率≥10kHz(72MHz主频下分频值设为72-1)
优化后的SPWM参数:
c复制htim1.Init.Prescaler = 71; // 1MHz计数器
htim1.Init.Period = 100; // 10kHz载波
4.2 保护机制实现
必须添加的硬件保护:
- 过流检测(比较器+GPIO中断)
- 母线欠压锁定(ADC监测)
- 温度保护(NTC电阻)
对应的软件处理流程:
mermaid复制graph TD
A[故障信号] --> B{故障类型}
B -->|过流| C[立即关闭PWM]
B -->|过温| D[降频运行]
B -->|欠压| E[软关机]
5. 进阶玩法与性能提升
5.1 加入闭环控制
在开环SPWM基础上增加:
- 电压电流双环PID控制
- 空间矢量调制(SVPWM)算法
- 无传感器FOC观测器
代码结构示例:
c复制void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim == &htim3) { // 10kHz控制周期
Clarke_Transform(&iab, &iαβ);
Park_Transform(&iαβ, &idq);
PID_Calc(&pid_id, idq.d);
PID_Calc(&pid_iq, idq.q);
SVPWM_Generate(vd, vq);
}
}
5.2 使用HRTIM提升性能
对于STM32F3/G4系列的高级定时器:
- 分辨率可达184ps
- 支持带死区的互补输出
- 硬件故障自动响应
配置示例:
c复制HRTIM1->sTimerxRegs[0].CMP1xR = 500; // 比较值1
HRTIM1->sTimerxRegs[0].SETx1R = HRTIM_SETxR_SST; // 软件启动
6. 工程文件结构建议
规范的工程目录应包含:
code复制/Drivers
/STM32F1xx_HAL_Driver
/CMSIS
/App
/spwm_generator.c
/protections.c
/pid_controller.c
/Inc
/config.h
/sin_table.h
关键头文件配置示例:
c复制// config.h
#define PWM_FREQ 10000 // 10kHz载波
#define DEAD_TIME_NS 400 // 死区时间
#define MODULATION 0.9f // 调制比
7. 实测数据与波形分析
使用示波器捕获的典型波形参数:
| 测试项 | 空载值 | 带载1A | 带载3A |
|---|---|---|---|
| 输出电压THD | 2.1% | 3.8% | 5.2% |
| 效率(220V/50Hz) | - | 92% | 89% |
| 温升(环境25℃) | +8℃ | +22℃ | +35℃ |
波形优化前后对比:
- 优化前:明显台阶状失真,THD>10%
- 优化后:光滑正弦波,THD<5%
8. 开发调试实用技巧
-
安全上电顺序:
- 先供3.3V给MCU
- 再供15V给驱动芯片
- 最后上高压直流
-
示波器抓波技巧:
- 探头接地线要尽量短
- 使用差分探头测量相电压
- 触发模式设为正常(非自动)
-
代码调试方法:
c复制// 在关键位置插入调试输出 printf("CCR1=%d, CCR2=%d, CCR3=%d\n", TIM1->CCR1, TIM1->CCR2, TIM1->CCR3); -
常见故障速查表:
| 现象 | 可能原因 | 解决方法 |
|---|---|---|
| 输出波形不对称 | 死区时间设置不当 | 调整BDTR寄存器DTG值 |
| 某相无输出 | GPIO配置错误 | 检查AFIO重映射 |
| 高频啸叫 | LC谐振频率接近载波频率 | 调整电感或电容值 |
| MOSFET发热严重 | 开关损耗过大 | 降低载波频率或换低Qg管 |
这个项目最让我意外的是STM32F103的DMA性能——在72MHz主频下,DMA搬运波形表数据几乎不占用CPU资源,配合定时器的触发功能,可以实现多路SPWM的精确同步输出。不过要注意的是,当调制比接近1时,需要特别处理过调制情况,否则会导致波形顶部削平。
