1. 项目概述:基于STM32的三相SPWM逆变器控制系统
这个项目是我在工业电力电子领域的一次实践探索,目标是开发一个基于STM32微控制器的三相SPWM逆变器控制系统。作为一名电力电子工程师,我深知在工业应用中,稳定可靠的三相逆变控制是多么关键。这个系统采用了STM32F10x系列MCU作为主控芯片,通过精确的正弦脉宽调制(SPWM)技术,实现了0-100Hz范围内的变频控制和电压调节功能。
系统最核心的价值在于它完整实现了三相逆变器的关键控制算法,并且通过外接按键提供了友好的人机交互界面。整个项目采用C语言开发,基于ARM的CMSIS标准外设库,确保了代码的可移植性和稳定性。在实际测试中,这套系统表现出了良好的动态响应特性和输出波形质量,完全可以满足工业级逆变器、电机驱动等应用场景的需求。
2. 系统架构与核心组件解析
2.1 硬件平台选型与配置
选择STM32F10x系列作为主控芯片是经过多方面考虑的。这个系列的MCU具有以下优势:
- 72MHz的主频提供了足够的计算能力来处理SPWM算法
- 丰富的高级定时器资源(TIM1/TIM8)完美适配三相PWM生成需求
- 内置的DMA控制器可以大幅减轻CPU负担
- 多种封装和存储容量选项(从32KB Flash的"低密度"型号到512KB Flash的"高密度"型号)提供了灵活的性价比选择
在实际项目中,我使用的是STM32F103C8T6这款中密度型号,它具备64KB Flash和20KB RAM,完全能够满足我们的需求。硬件设计时特别注意了以下几点:
- 功率驱动部分采用光耦隔离,确保控制信号与功率部分的电气隔离
- 为每个桥臂配置了独立的电流检测电路
- 系统时钟配置为外部8MHz晶振+PLL倍频到72MHz
- PWM输出引脚都配置了适当的推挽输出模式
2.2 软件架构设计
整个软件系统采用分层设计,主要分为以下几个层次:
-
CMSIS核心层:提供与Cortex-M3内核的直接接口,包括:
- 异常和中断管理(NVIC配置)
- 系统时钟和定时器配置
- 处理器特殊功能寄存器访问
-
硬件抽象层(HAL):封装了STM32标准外设库,提供统一的设备驱动接口
-
应用层:实现SPWM算法核心逻辑和系统控制功能
这种分层设计使得代码具有很好的可移植性,当需要更换MCU型号时,只需修改底层的硬件抽象层即可。
3. SPWM核心技术实现细节
3.1 SPWM调制原理与实现
正弦脉宽调制(SPWM)是逆变器控制的核心技术。其基本原理是通过比较正弦波(调制波)和三角波(载波)来生成PWM信号。在本项目中,我们采用对称规则采样法来实现SPWM,这种方法计算量适中,适合在STM32上实时运行。
具体实现步骤如下:
- 载波生成:使用TIM1的中央对齐模式生成对称三角波
c复制// 定时器配置示例
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = PWM_PERIOD; // 设置PWM周期
TIM_TimeBaseStructure.TIM_Prescaler = 0; // 不分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
- 正弦表生成:预先计算三相正弦波采样值并存储在数组中
c复制#define SINE_TABLE_SIZE 256
uint16_t SineTable_U[SINE_TABLE_SIZE];
uint16_t SineTable_V[SINE_TABLE_SIZE];
uint16_t SineTable_W[SINE_TABLE_SIZE];
void GenerateSineTable(void) {
for(int i=0; i<SINE_TABLE_SIZE; i++) {
float angle = 2 * PI * i / SINE_TABLE_SIZE;
SineTable_U[i] = (uint16_t)((sin(angle) + 1) * PWM_PERIOD / 2);
SineTable_V[i] = (uint16_t)((sin(angle + 2*PI/3) + 1) * PWM_PERIOD / 2);
SineTable_W[i] = (uint16_t)((sin(angle + 4*PI/3) + 1) * PWM_PERIOD / 2);
}
}
- PWM更新:在定时器中断中更新比较寄存器值
c复制void TIM1_UP_IRQHandler(void) {
static uint16_t index = 0;
// 更新三相PWM占空比
TIM_SetCompare1(TIM1, SineTable_U[index]);
TIM_SetCompare2(TIM1, SineTable_V[index]);
TIM_SetCompare3(TIM1, SineTable_W[index]);
index = (index + 1) % SINE_TABLE_SIZE;
TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
}
3.2 变频控制实现
变频功能是通过动态调整正弦表的更新速度实现的。我们使用一个辅助定时器来触发正弦表索引的更新,通过改变这个定时器的周期就可以实现输出频率的调节。
具体实现逻辑:
- 用户通过按键设置目标频率(0-100Hz)
- 系统根据目标频率计算正弦表更新间隔:
c复制// 计算定时器ARR值 // F_UPDATE = 输出频率 * 正弦表大小 // ARR = (定时器时钟频率 / F_UPDATE) - 1 uint32_t arr = (SystemCoreClock / (target_freq * SINE_TABLE_SIZE)) - 1; TIM_SetAutoreload(TIM2, arr); - 定时器配置为触发DMA传输,自动更新正弦表索引
3.3 变压控制实现
变压控制是通过调整调制比(输出电压幅值与直流母线电压的比值)来实现的。我们采用以下方法:
- 在生成正弦表时引入幅度系数:
c复制float modulation_index = 0.8f; // 调制比,0-1可调 SineTable_U[i] = (uint16_t)((sin(angle) * modulation_index + 1) * PWM_PERIOD / 2); - 通过按键可以实时调整modulation_index的值
- 为防止过调制(modulation_index >1),在代码中加入限制:
c复制if(modulation_index > 1.0f) modulation_index = 1.0f; if(modulation_index < 0.0f) modulation_index = 0.0f;
4. 关键外设配置与优化技巧
4.1 高级定时器配置
三相PWM生成使用的是STM32的高级定时器TIM1,其配置要点如下:
-
时基配置:
- 计数模式:中央对齐模式1(先递增后递减)
- 预分频器:0(72MHz直接驱动)
- 自动重装载值:根据开关频率设置(如10kHz时设为7200-1)
-
PWM通道配置:
- PWM模式1
- 互补输出使能(用于驱动上下桥臂)
- 死区时间插入(防止上下管直通)
-
刹车功能配置:
- 使能刹车输入
- 配置为高电平有效
- 刹车时所有输出强制为无效电平
完整配置示例:
c复制void TIM1_Configuration(void) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
// 时基配置
TIM_TimeBaseStructure.TIM_Period = PWM_PERIOD - 1;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
// PWM通道配置
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OC2Init(TIM1, &TIM_OCInitStructure);
TIM_OC3Init(TIM1, &TIM_OCInitStructure);
// 死区时间配置(约1us)
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
TIM_BDTRInitStructure.TIM_DeadTime = 72; // 72MHz时钟下对应1us
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
TIM_Cmd(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
}
4.2 DMA优化技巧
为了减轻CPU负担,我们使用DMA来实现正弦表数据的自动传输。具体实现方法:
- 配置DMA通道为内存到外设传输
- 设置传输数据宽度为半字(16位)
- 使能循环模式
- 配置触发源为定时器更新事件
关键代码:
c复制void DMA_Configuration(void) {
DMA_InitTypeDef DMA_InitStructure;
// 使能DMA时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
// 配置DMA通道
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&TIM1->CCR1;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SineTable_U;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = SINE_TABLE_SIZE;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
// 使能DMA
DMA_Cmd(DMA1_Channel5, ENABLE);
// 配置DMA请求
TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE);
}
5. 系统保护机制实现
5.1 硬件保护电路
在功率电子系统中,保护电路至关重要。我们在硬件上实现了以下保护措施:
-
过流保护:
- 每个桥臂配置电流传感器
- 通过比较器实现硬件过流检测
- 触发MCU的刹车输入引脚
-
过压/欠压保护:
- 直流母线电压分压采样
- 窗口比较器检测电压异常
- 触发系统关机
-
温度保护:
- 功率器件散热片安装温度传感器
- 超过阈值温度时降低输出功率或关闭系统
5.2 软件保护策略
除了硬件保护外,软件层面也实现了多重保护:
-
PWM占空比限制:
c复制// 在更新PWM占空比时加入限制 void SetPWM(uint16_t duty) { if(duty > MAX_DUTY) duty = MAX_DUTY; if(duty < MIN_DUTY) duty = MIN_DUTY; TIM_SetCompare1(TIM1, duty); } -
故障检测中断:
c复制void NMI_Handler(void) { // 硬件故障处理 TIM_CtrlPWMOutputs(TIM1, DISABLE); EmergencyShutdown(); } -
看门狗定时器:
c复制void IWDG_Configuration(void) { IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); IWDG_SetPrescaler(IWDG_Prescaler_32); // 约1ms/tick IWDG_SetReload(1000); // 约1s超时 IWDG_ReloadCounter(); IWDG_Enable(); }
6. 人机交互接口实现
6.1 按键控制设计
系统通过4个按键实现用户交互:
- 频率增加键
- 频率减少键
- 电压增加键
- 电压减少键
按键处理采用中断+消抖的方式实现:
c复制void EXTI0_IRQHandler(void) {
static uint32_t last_time = 0;
uint32_t current_time = GetSystemTick();
// 消抖处理(20ms)
if(current_time - last_time > 20) {
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0) {
// 频率增加处理
target_freq += 1.0f;
if(target_freq > 100.0f) target_freq = 100.0f;
UpdateFrequency();
}
}
last_time = current_time;
EXTI_ClearITPendingBit(EXTI_Line0);
}
6.2 状态指示设计
系统状态通过LED指示灯显示:
- 电源指示灯(常亮)
- 运行指示灯(闪烁频率与输出频率同步)
- 故障指示灯(红色,故障时点亮)
LED控制代码:
c复制void UpdateStatusLED(void) {
static uint32_t counter = 0;
if(fault_flag) {
GPIO_SetBits(GPIOB, GPIO_Pin_1); // 点亮故障灯
} else {
counter++;
if(counter >= (100 / target_freq)) {
GPIO_ToggleBits(GPIOB, GPIO_Pin_0); // 切换运行灯
counter = 0;
}
}
}
7. 系统调试与性能优化
7.1 调试技巧与工具
在开发过程中,以下几个调试方法非常有用:
-
PWM波形观测:
- 使用示波器观察各相PWM输出
- 检查死区时间是否合适
- 验证开关频率是否正确
-
电流波形分析:
- 使用电流探头观测各相电流
- 检查电流波形是否正弦度良好
- 观察过零点的平滑度
-
软件调试工具:
- 使用ST-Link进行在线调试
- 通过SWD接口读取关键变量
- 利用断点分析程序流程
7.2 性能优化经验
经过多次测试和优化,总结出以下几点经验:
-
中断优化:
- 将高频中断(如PWM更新)处理函数尽可能简化
- 把非实时性任务移到主循环中处理
- 合理设置中断优先级
-
算法优化:
- 使用查表法代替实时计算正弦值
- 采用定点数运算代替浮点运算
- 优化三相正弦表的存储方式(可以只存储1/4周期数据)
-
电源质量改善:
- 增加输出LC滤波器参数优化
- 采用三次谐波注入技术提高直流电压利用率
- 实现闭环控制改善动态响应
8. 实际应用测试结果
在完成系统开发后,我们进行了全面的性能测试:
-
输出波形质量测试:
- 空载时输出电压THD < 3%
- 带额定负载时THD < 5%
- 三相电压不平衡度 < 1%
-
动态响应测试:
- 频率阶跃响应时间 < 100ms
- 电压调整响应时间 < 50ms
- 负载突变时的恢复时间 < 200ms
-
效率测试:
- 系统整体效率 > 92%(额定负载下)
- 待机功耗 < 5W
测试结果表明,该系统完全达到了工业应用的要求,性能稳定可靠。
9. 二次开发建议与扩展方向
这个项目提供了很好的基础平台,可以根据实际需求进行多种扩展:
-
通信接口扩展:
- 添加RS485接口实现远程监控
- 支持Modbus RTU协议
- 增加CAN总线接口用于工业网络
-
高级控制算法:
- 实现空间矢量调制(SVPWM)提高电压利用率
- 加入闭环电压/电流控制
- 开发矢量控制算法用于电机驱动
-
功能扩展:
- 增加电池管理功能用于UPS应用
- 开发太阳能MPPT算法
- 实现并网逆变器功能
-
人机界面增强:
- 添加LCD显示屏显示系统状态
- 支持参数存储与调用
- 开发手机APP通过蓝牙/WiFi监控
在实际项目中,我曾基于这个平台开发过一款工业电机驱动器,通过添加上述部分功能,成功应用于自动化生产线,运行稳定可靠。