基于STM32F3/F4的完整光伏逆变器控制程序框架,包含MPPT算法、逆变控制、并网同步、保护逻辑等核心模块。这是一个单相全桥逆变器的实用实现。
一、系统架构
光伏组件 → DC/DC Boost(MPPT) → 直流母线 → DC/AC 逆变 → 电网/负载
↓ ↓ ↓
PV电压/电流采样 母线电压 交流电压/电流
↓ ↓ ↓
STM32F3/F4(ADC+DSP+高级定时器)
↓
MPPT算法 + SVPWM/SPWM
↓
PWM驱动信号
↓
IGBT/MOSFET功率模块
二、核心模块概览
| 模块 | 功能 | 关键技术 |
|---|---|---|
| ADC采样 | 电压电流实时采样 | 同步采样、DMA |
| MPPT算法 | 最大功率点跟踪 | 扰动观察法/电导增量法 |
| DC/DC控制 | Boost升压稳压 | PID控制、PWM生成 |
| DC/AC控制 | 逆变并网控制 | SPWM/SVPWM、锁相环 |
| 保护模块 | 过压/过流/孤岛 | 硬件比较器、软件保护 |
| 通讯模块 | 远程监控 | Modbus/RS485/CAN |
三、硬件配置(STM32F334/F4)
1. 主控选型
- 推荐型号:STM32F334(高分辨率定时器)或 STM32F407(带FPU)
- ADC:16位高分辨率,3Msps
- 定时器:高级定时器(TIM1/TIM8)用于PWM
- 比较器:内置快速比较器用于过流保护
2. 功率部分
前级Boost:
MOSFET: 2-4个(根据功率)
电感: 定制(几百uH-mH)
输出电容: 470-1000uF/450V
后级逆变:
IGBT/MOSFET: 4个(全桥)
LC滤波器: L=2-5mH, C=4.7-10uF
四、完整程序架构
1. 主文件结构
Photovoltaic_Inverter/
├── Inc/
│ ├── main.h
│ ├── adc_handler.h
│ ├── mppt.h
│ ├── inverter.h
│ ├── pll.h
│ ├── protection.h
│ └── communication.h
├── Src/
│ ├── main.c
│ ├── adc_handler.c
│ ├── mppt.c
│ ├── inverter.c
│ ├── pll.c
│ ├── protection.c
│ └── communication.c
└── Drivers/
├── STM32F4xx_HAL_Driver/
└── CMSIS/
2. 主程序(main.c)
c
#include "main.h"
#include "adc_handler.h"
#include "mppt.h"
#include "inverter.h"
#include "pll.h"
#include "protection.h"
#include "communication.h"
// 全局系统变量
System_State_t system_state = STATE_INIT;
PV_Data_t pv_data = {0};
Grid_Data_t grid_data = {0};
Control_Params_t ctrl_params = {0};
int main(void)
{
// 1. 硬件初始化
HAL_Init();
SystemClock_Config();
// 2. 外设初始化
MX_GPIO_Init();
MX_ADC1_Init(); // PV电压电流采样
MX_ADC2_Init(); // 母线电压、交流采样
MX_ADC3_Init(); // 温度采样
MX_TIM1_Init(); // 逆变PWM
MX_TIM8_Init(); // Boost PWM
MX_COMP1_Init(); // 快速过流保护
MX_USART1_UART_Init(); // 调试串口
MX_USART2_UART_Init(); // Modbus
MX_CAN1_Init(); // CAN通讯
// 3. 软件模块初始化
ADC_Handler_Init();
MPPT_Init();
Inverter_Init();
PLL_Init();
Protection_Init();
Communication_Init();
// 4. 启动PWM和ADC
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4);
HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_1);
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc1_buffer, 4);
HAL_ADC_Start_DMA(&hadc2, (uint32_t*)adc2_buffer, 4);
// 5. 启动保护比较器
HAL_COMP_Start(&hcomp1);
// 6. 主循环
while (1)
{
// 状态机处理
System_State_Machine();
// 通讯处理
Communication_Process();
// 保护检测
Protection_Check();
// 休眠(等待中断)
__WFI();
}
}
// 系统状态机
void System_State_Machine(void)
{
static uint32_t state_timer = 0;
switch (system_state)
{
case STATE_INIT:
// 自检完成,进入待机
if (Self_Test_OK()) {
system_state = STATE_STANDBY;
}
break;
case STATE_STANDBY:
// 等待启动命令
if (Start_Command_Received()) {
system_state = STATE_STARTUP;
state_timer = HAL_GetTick();
}
break;
case STATE_STARTUP:
// 软启动(2秒)
if (HAL_GetTick() - state_timer > 2000) {
system_state = STATE_MPPT;
}
Soft_Start_Sequence();
break;
case STATE_MPPT:
// 正常MPPT运行
MPPT_Process();
Inverter_Control();
// 检测故障
if (protection_status.fault) {
system_state = STATE_FAULT;
}
break;
case STATE_FAULT:
// 故障处理
Fault_Handler();
// 尝试自动恢复
if (Auto_Recovery_Condition()) {
system_state = STATE_STANDBY;
}
break;
case STATE_SHUTDOWN:
// 软关机
Soft_Shutdown_Sequence();
if (Shutdown_Complete()) {
system_state = STATE_STANDBY;
}
break;
}
}
3. ADC采样处理
c
// adc_handler.h
#ifndef __ADC_HANDLER_H
#define __ADC_HANDLER_H
#include "stm32f4xx_hal.h"
// ADC通道定义
typedef enum {
ADC_CH_PV_VOLTAGE = 0,
ADC_CH_PV_CURRENT,
ADC_CH_BUS_VOLTAGE,
ADC_CH_BUS_CURRENT,
ADC_CH_AC_VOLTAGE,
ADC_CH_AC_CURRENT,
ADC_CH_TEMP_IGBT,
ADC_CH_TEMP_INDUCTOR
} ADC_Channel_t;
// 采样数据结构
typedef struct {
float pv_voltage; // PV电压 (V)
float pv_current; // PV电流 (A)
float pv_power; // PV功率 (W)
float bus_voltage; // 母线电压 (V)
float bus_current; // 母线电流 (A)
float ac_voltage; // 交流电压 (V)
float ac_current; // 交流电流 (A)
float ac_frequency; // 交流频率 (Hz)
float temp_igbt; // IGBT温度 (°C)
float temp_inductor; // 电感温度 (°C)
} PV_Data_t;
// 函数声明
void ADC_Handler_Init(void);
void ADC_DMA_Callback(void);
void ADC_Process_Data(void);
float ADC_Get_Value(ADC_Channel_t ch);
#endif
c
// adc_handler.c
#include "adc_handler.h"
#include "math.h"
// DMA缓冲区
volatile uint16_t adc1_buffer[8];
volatile uint16_t adc2_buffer[8];
volatile uint16_t adc3_buffer[2];
// 校准系数
#define PV_VOLTAGE_SCALE 0.1f // 100:1分压
#define PV_CURRENT_SCALE 0.01f // 100A:1V霍尔
#define BUS_VOLTAGE_SCALE 0.1f
#define AC_VOLTAGE_SCALE 0.01f
#define AC_CURRENT_SCALE 0.05f
// 初始化
void ADC_Handler_Init(void)
{
// 配置ADC触发为定时器触发(同步采样)
ADC_TriggerConfTypeDef sConfig = {0};
sConfig.TriggerSource = ADC_EXTERNALTRIGCONV_T1_TRGO;
sConfig.TriggerEdge = ADC_EXTERNALTRIG_EDGE_RISING;
sConfig.TriggerCount = 1;
HAL_ADCEx_RegularMultiModeConfig_AlignDM(&hadc1, &hadc2, &sConfig);
}
// DMA完成回调
void ADC_DMA_Callback(void)
{
// 计算PV侧
pv_data.pv_voltage = adc1_buffer[ADC_CH_PV_VOLTAGE] * PV_VOLTAGE_SCALE;
pv_data.pv_current = adc1_buffer[ADC_CH_PV_CURRENT] * PV_CURRENT_SCALE;
pv_data.pv_power = pv_data.pv_voltage * pv_data.pv_current;
// 计算直流母线
pv_data.bus_voltage = adc1_buffer[ADC_CH_BUS_VOLTAGE] * BUS_VOLTAGE_SCALE;
pv_data.bus_current = adc1_buffer[ADC_CH_BUS_CURRENT] * PV_CURRENT_SCALE;
// 计算交流侧
pv_data.ac_voltage = adc2_buffer[ADC_CH_AC_VOLTAGE] * AC_VOLTAGE_SCALE;
pv_data.ac_current = adc2_buffer[ADC_CH_AC_CURRENT] * AC_CURRENT_SCALE;
// 计算温度
pv_data.temp_igbt = (adc3_buffer[0] * 3.3f / 4095.0f - 0.76f) / 0.0025f + 25.0f;
pv_data.temp_inductor = (adc3_buffer[1] * 3.3f / 4095.0f - 0.76f) / 0.0025f + 25.0f;
}
// 获取交流电压有效值
float Get_AC_RMS_Voltage(void)
{
static float voltage_buffer[100];
static uint8_t index = 0;
float sum = 0;
// 存储瞬时值
voltage_buffer[index] = pv_data.ac_voltage;
index = (index + 1) % 100;
// 计算RMS
for (int i = 0; i < 100; i++) {
sum += voltage_buffer[i] * voltage_buffer[i];
}
return sqrtf(sum / 100.0f);
}
4. MPPT算法(电导增量法)
c
// mppt.h
#ifndef __MPPT_H
#define __MPPT_H
#include "main.h"
// MPPT算法类型
typedef enum {
MPPT_PERTURB_OBSERVE = 0, // 扰动观察法
MPPT_INC_COND, // 电导增量法
MPPT_FUZZY_LOGIC, // 模糊逻辑
MPPT_ANN // 神经网络
} MPPT_Algorithm_t;
// MPPT结构体
typedef struct {
MPPT_Algorithm_t algorithm;
float v_step; // 电压步长
float v_ref; // 参考电压
float v_old; // 旧电压
float p_old; // 旧功率
float duty; // Boost占空比
float duty_max; // 最大占空比
float duty_min; // 最小占空比
uint8_t enable; // 使能标志
} MPPT_Controller_t;
// 函数声明
void MPPT_Init(void);
void MPPT_Process(void);
void MPPT_Incremental_Conductance(void);
void MPPT_Perturb_Observe(void);
float MPPT_Get_Duty(void);
void MPPT_Set_Duty_Limit(float min, float max);
#endif
c
// mppt.c
#include "mppt.h"
#include "math.h"
MPPT_Controller_t mppt = {0};
// 初始化
void MPPT_Init(void)
{
mppt.algorithm = MPPT_INC_COND;
mppt.v_step = 0.5f; // 0.5V步长
mppt.duty = 0.5f; // 初始占空比50%
mppt.duty_max = 0.9f; // 最大90%
mppt.duty_min = 0.1f; // 最小10%
mppt.enable = 1;
}
// MPPT主处理函数
void MPPT_Process(void)
{
if (!mppt.enable) return;
switch (mppt.algorithm) {
case MPPT_PERTURB_OBSERVE:
MPPT_Perturb_Observe();
break;
case MPPT_INC_COND:
MPPT_Incremental_Conductance();
break;
default:
MPPT_Incremental_Conductance();
break;
}
}
// 电导增量法(推荐)
void MPPT_Incremental_Conductance(void)
{
float delta_v, delta_i, delta_p;
float conductance, inc_conductance;
// 计算变化量
delta_v = pv_data.pv_voltage - mppt.v_old;
delta_i = pv_data.pv_current - mppt.p_old;
delta_p = pv_data.pv_power - mppt.p_old;
if (fabsf(delta_v) < 0.01f) { // 电压变化很小
if (fabsf(delta_i) < 0.01f) {
// 保持当前工作点
} else if (delta_i > 0) {
mppt.duty -= mppt.v_step;
} else {
mppt.duty += mppt.v_step;
}
} else {
// 计算电导和电导增量
conductance = pv_data.pv_current / pv_data.pv_voltage;
inc_conductance = delta_i / delta_v;
if (fabsf(conductance + inc_conductance) < 0.01f) {
// 处于MPP,保持
} else if (conductance + inc_conductance > 0) {
mppt.duty -= mppt.v_step; // 在MPP左侧
} else {
mppt.duty += mppt.v_step; // 在MPP右侧
}
}
// 限制占空比
if (mppt.duty > mppt.duty_max) mppt.duty = mppt.duty_max;
if (mppt.duty < mppt.duty_min) mppt.duty = mppt.duty_min;
// 更新PWM
__HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_1,
(uint32_t)(mppt.duty * htim8.Init.Period));
// 保存当前值
mppt.v_old = pv_data.pv_voltage;
mppt.p_old = pv_data.pv_power;
}
// 扰动观察法
void MPPT_Perturb_Observe(void)
{
float delta_p = pv_data.pv_power - mppt.p_old;
if (delta_p > 0) {
// 功率增加,保持扰动方向
if (pv_data.pv_voltage > mppt.v_old) {
mppt.duty -= mppt.v_step; // 增加电压
} else {
mppt.duty += mppt.v_step; // 减小电压
}
} else {
// 功率减少,改变扰动方向
if (pv_data.pv_voltage > mppt.v_old) {
mppt.duty += mppt.v_step; // 减小电压
} else {
mppt.duty -= mppt.v_step; // 增加电压
}
}
// 限制占空比
if (mppt.duty > mppt.duty_max) mppt.duty = mppt.duty_max;
if (mppt.duty < mppt.duty_min) mppt.duty = mppt.duty_min;
// 更新PWM
__HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_1,
(uint32_t)(mppt.duty * htim8.Init.Period));
// 保存当前值
mppt.v_old = pv_data.pv_voltage;
mppt.p_old = pv_data.pv_power;
}
5. 逆变控制(SPWM + 电压电流双环)
c
// inverter.h
#ifndef __INVERTER_H
#define __INVERTER_H
#include "main.h"
// 逆变模式
typedef enum {
MODE_STANDBY = 0,
MODE_GRID_TIE, // 并网模式
MODE_OFF_GRID, // 离网模式
MODE_FAULT
} Inverter_Mode_t;
// 控制结构体
typedef struct {
Inverter_Mode_t mode;
float v_ref; // 参考电压
float i_ref; // 参考电流
float v_out; // 输出电压
float i_out; // 输出电流
float freq; // 输出频率
float phase; // 相位
float modulation; // 调制比
float duty_a; // A相占空比
float duty_b; // B相占空比
} Inverter_Controller_t;
// 函数声明
void Inverter_Init(void);
void Inverter_Control(void);
void Inverter_Grid_Tie_Control(void);
void Inverter_Off_Grid_Control(void);
void SPWM_Generate(float angle, float modulation);
void Voltage_Current_Dual_Loop(void);
#endif
c
// inverter.c
#include "inverter.h"
#include "pll.h"
#include "math.h"
Inverter_Controller_t inverter = {0};
float sin_table[360]; // 正弦表
// 初始化
void Inverter_Init(void)
{
inverter.mode = MODE_STANDBY;
inverter.freq = 50.0f; // 50Hz
inverter.modulation = 0.5f; // 初始调制比50%
// 生成正弦表
for (int i = 0; i < 360; i++) {
sin_table[i] = sinf(i * 3.1415926f / 180.0f);
}
}
// 逆变控制主函数
void Inverter_Control(void)
{
switch (inverter.mode) {
case MODE_GRID_TIE:
Inverter_Grid_Tie_Control();
break;
case MODE_OFF_GRID:
Inverter_Off_Grid_Control();
break;
default:
// 停止PWM输出
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 0);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, 0);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, 0);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_4, 0);
break;
}
}
// 并网控制
void Inverter_Grid_Tie_Control(void)
{
static float angle = 0;
float grid_angle, error;
// 获取电网角度
grid_angle = PLL_Get_Angle();
// 锁相环同步
error = grid_angle - angle;
if (error > 3.14159f) error -= 6.28318f;
if (error < -3.14159f) error += 6.28318f;
// PI调节器同步频率
static float int_error = 0;
float kp = 0.1f, ki = 0.01f;
angle += inverter.freq * 0.00002f * 6.28318f; // 20kHz控制周期
angle += kp * error + ki * int_error;
if (angle > 6.28318f) angle -= 6.28318f;
int_error += error;
// 电流环控制
Voltage_Current_Dual_Loop();
// 生成SPWM
SPWM_Generate(angle, inverter.modulation);
}
// 离网控制
void Inverter_Off_Grid_Control(void)
{
static float angle = 0;
// 更新角度
angle += inverter.freq * 0.00002f * 6.28318f; // 20kHz控制周期
if (angle > 6.28318f) angle -= 6.28318f;
// 电压环控制
Voltage_Current_Dual_Loop();
// 生成SPWM
SPWM_Generate(angle, inverter.modulation);
}
// 电压电流双环控制
void Voltage_Current_Dual_Loop(void)
{
static float v_err_int = 0, i_err_int = 0;
float v_err, i_err;
float v_kp = 0.5f, v_ki = 0.1f;
float i_kp = 2.0f, i_ki = 0.5f;
// 电压外环
v_err = inverter.v_ref - pv_data.ac_voltage;
v_err_int += v_err;
// 电流内环参考
inverter.i_ref = v_kp * v_err + v_ki * v_err_int;
// 电流内环
i_err = inverter.i_ref - pv_data.ac_current;
i_err_int += i_err;
// 计算调制比
inverter.modulation = i_kp * i_err + i_ki * i_err_int;
// 限制调制比
if (inverter.modulation > 0.95f) inverter.modulation = 0.95f;
if (inverter.modulation < 0.0f) inverter.modulation = 0.0f;
}
// 生成SPWM
void SPWM_Generate(float angle, float modulation)
{
float sin_val, cos_val;
uint32_t period = htim1.Init.Period;
// 计算正弦值
int idx = (int)(angle * 180.0f / 3.14159f) % 360;
sin_val = sin_table[idx];
cos_val = sin_table[(idx + 90) % 360];
// 计算占空比
inverter.duty_a = 0.5f + 0.5f * modulation * sin_val; // A相
inverter.duty_b = 0.5f + 0.5f * modulation * cos_val; // B相(移相90度)
// 更新PWM
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1,
(uint32_t)(inverter.duty_a * period));
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2,
(uint32_t)((1.0f - inverter.duty_a) * period));
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3,
(uint32_t)(inverter.duty_b * period));
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_4,
(uint32_t)((1.0f - inverter.duty_b) * period));
}
6. 锁相环(PLL)
c
// pll.h
#ifndef __PLL_H
#define __PLL_H
#include "main.h"
// PLL结构体
typedef struct {
float grid_freq; // 电网频率
float grid_angle; // 电网角度
float grid_amp; // 电网幅值
float phase_error; // 相位误差
uint8_t locked; // 锁相状态
} PLL_Controller_t;
// 函数声明
void PLL_Init(void);
void PLL_Process(void);
float PLL_Get_Angle(void);
float PLL_Get_Frequency(void);
uint8_t PLL_Is_Locked(void);
#endif
c
// pll.c
#include "pll.h"
#include "math.h"
PLL_Controller_t pll = {0};
float pll_integral = 0;
// 初始化
void PLL_Init(void)
{
pll.grid_freq = 50.0f;
pll.grid_angle = 0;
pll.locked = 0;
}
// PLL处理函数
void PLL_Process(void)
{
static float v_old = 0;
static float v_alpha = 0, v_beta = 0;
static float v_d = 0, v_q = 0;
static float sin_angle = 0, cos_angle = 0;
float v_inst = pv_data.ac_voltage; // 瞬时电压
// Clark变换
v_alpha = v_inst;
v_beta = v_old;
v_old = v_inst;
// Park变换
v_d = v_alpha * cos_angle + v_beta * sin_angle;
v_q = v_beta * cos_angle - v_alpha * sin_angle;
// PI控制器
float kp = 0.5f, ki = 0.1f;
float error = v_q; // 我们希望v_q=0
pll_integral += error;
float freq_adjust = kp * error + ki * pll_integral;
// 更新频率和角度
pll.grid_freq = 50.0f + freq_adjust;
pll.grid_angle += pll.grid_freq * 0.00002f * 6.28318f; // 20kHz
if (pll.grid_angle > 6.28318f) pll.grid_angle -= 6.28318f;
// 更新正弦/余弦值
sin_angle = sinf(pll.grid_angle);
cos_angle = cosf(pll.grid_angle);
// 检查锁相状态
if (fabsf(error) < 0.01f && fabsf(pll.grid_freq - 50.0f) < 0.5f) {
pll.locked = 1;
} else {
pll.locked = 0;
}
}
7. 保护模块
c
// protection.h
#ifndef __PROTECTION_H
#define __PROTECTION_H
#include "main.h"
// 保护类型
typedef enum {
PROT_NONE = 0,
PROT_OVERVOLTAGE, // 过压
PROT_OVERCURRENT, // 过流
PROT_OVERTEMP, // 过温
PROT_SHORT_CIRCUIT, // 短路
PROT_ISLANDING, // 孤岛
PROT_GRID_FAULT // 电网故障
} Protection_Type_t;
// 保护结构体
typedef struct {
Protection_Type_t fault_type;
uint8_t fault_active;
uint32_t fault_timer;
float v_over_threshold; // 过压阈值
float i_over_threshold; // 过流阈值
float temp_threshold; // 过温阈值
} Protection_Controller_t;
// 函数声明
void Protection_Init(void);
void Protection_Check(void);
void Protection_Trip(void);
void Protection_Clear(void);
uint8_t Protection_Is_Fault(void);
#endif
c
// protection.c
#include "protection.h"
Protection_Controller_t protection = {0};
// 初始化
void Protection_Init(void)
{
protection.v_over_threshold = 450.0f; // 450V
protection.i_over_threshold = 20.0f; // 20A
protection.temp_threshold = 85.0f; // 85°C
protection.fault_active = 0;
}
// 保护检测
void Protection_Check(void)
{
// 1. 过压保护
if (pv_data.bus_voltage > protection.v_over_threshold) {
protection.fault_type = PROT_OVERVOLTAGE;
protection.fault_active = 1;
Protection_Trip();
return;
}
// 2. 过流保护
if (pv_data.ac_current > protection.i_over_threshold) {
protection.fault_type = PROT_OVERCURRENT;
protection.fault_active = 1;
Protection_Trip();
return;
}
// 3. 过温保护
if (pv_data.temp_igbt > protection.temp_threshold) {
protection.fault_type = PROT_OVERTEMP;
protection.fault_active = 1;
Protection_Trip();
return;
}
// 4. 短路保护(通过硬件比较器)
if (HAL_COMP_GetOutputLevel(&hcomp1) == COMP_OUTPUT_LEVEL_HIGH) {
protection.fault_type = PROT_SHORT_CIRCUIT;
protection.fault_active = 1;
Protection_Trip();
return;
}
// 5. 孤岛保护
if (Islanding_Detected()) {
protection.fault_type = PROT_ISLANDING;
protection.fault_active = 1;
Protection_Trip();
return;
}
// 6. 电网故障
if (Grid_Fault_Detected()) {
protection.fault_type = PROT_GRID_FAULT;
protection.fault_active = 1;
Protection_Trip();
return;
}
}
// 保护动作
void Protection_Trip(void)
{
// 立即关闭所有PWM
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 0);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, 0);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, 0);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_4, 0);
__HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_1, 0);
// 断开继电器
HAL_GPIO_WritePin(RELAY_GPIO_Port, RELAY_Pin, GPIO_PIN_RESET);
// 记录故障时间
protection.fault_timer = HAL_GetTick();
// 发送故障信号
Fault_LED_On();
Send_Fault_Message();
}
// 孤岛检测
uint8_t Islanding_Detected(void)
{
static float freq_buffer[10];
static uint8_t idx = 0;
static float sum = 0;
// 记录频率
freq_buffer[idx] = pll.grid_freq;
idx = (idx + 1) % 10;
// 计算频率变化
if (idx == 0) {
float avg = sum / 10.0f;
if (fabsf(avg - 50.0f) > 0.5f) { // 频率偏移超过0.5Hz
return 1;
}
sum = 0;
}
sum += pll.grid_freq;
return 0;
}
8. 通信模块(Modbus)
c
// communication.h
#ifndef __COMMUNICATION_H
#define __COMMUNICATION_H
#include "main.h"
// Modbus寄存器映射
typedef enum {
// 只读寄存器(输入)
REG_PV_VOLTAGE = 0,
REG_PV_CURRENT = 1,
REG_PV_POWER = 2,
REG_BUS_VOLTAGE = 3,
REG_AC_VOLTAGE = 4,
REG_AC_CURRENT = 5,
REG_AC_POWER = 6,
REG_FREQUENCY = 7,
REG_TEMP_IGBT = 8,
REG_ENERGY_TODAY = 9,
REG_ENERGY_TOTAL = 10,
// 读写寄存器(保持)
REG_MPPT_ENABLE = 100,
REG_MPPT_MODE = 101,
REG_OUTPUT_POWER_SET = 102,
REG_FAULT_CODE = 103,
REG_SYSTEM_STATE = 104
} Modbus_Registers_t;
// 函数声明
void Communication_Init(void);
void Communication_Process(void);
void Modbus_Process_Request(void);
void CAN_Process_Message(void);
#endif
c
// communication.c
#include "communication.h"
#include "modbus.h"
uint16_t modbus_holding_regs[256];
uint16_t modbus_input_regs[256];
// 初始化
void Communication_Init(void)
{
// 初始化寄存器
modbus_holding_regs[REG_MPPT_ENABLE] = 1;
modbus_holding_regs[REG_MPPT_MODE] = 1; // 电导增量法
modbus_holding_regs[REG_OUTPUT_POWER_SET] = 3000; // 3kW
// 启动Modbus
Modbus_Slave_Init(0x01, 9600);
}
// 通讯处理
void Communication_Process(void)
{
// Modbus处理
Modbus_Process_Request();
// CAN处理
CAN_Process_Message();
}
// 更新输入寄存器
void Update_Input_Registers(void)
{
modbus_input_regs[REG_PV_VOLTAGE] = (uint16_t)(pv_data.pv_voltage * 10);
modbus_input_regs[REG_PV_CURRENT] = (uint16_t)(pv_data.pv_current * 100);
modbus_input_regs[REG_PV_POWER] = (uint16_t)(pv_data.pv_power);
modbus_input_regs[REG_BUS_VOLTAGE] = (uint16_t)(pv_data.bus_voltage * 10);
modbus_input_regs[REG_AC_VOLTAGE] = (uint16_t)(pv_data.ac_voltage * 10);
modbus_input_regs[REG_AC_CURRENT] = (uint16_t)(pv_data.ac_current * 100);
modbus_input_regs[REG_FREQUENCY] = (uint16_t)(pll.grid_freq * 100);
modbus_input_regs[REG_TEMP_IGBT] = (uint16_t)(pv_data.temp_igbt * 10);
modbus_input_regs[REG_SYSTEM_STATE] = system_state;
modbus_input_regs[REG_FAULT_CODE] = protection.fault_type;
}
五、定时器中断处理
c
// stm32f4xx_it.c
#include "stm32f4xx_it.h"
#include "main.h"
#include "adc_handler.h"
#include "mppt.h"
#include "inverter.h"
#include "pll.h"
#include "protection.h"
// 定时器1中断(20kHz PWM更新)
void TIM1_UP_TIM10_IRQHandler(void)
{
if (__HAL_TIM_GET_FLAG(&htim1, TIM_FLAG_UPDATE) != RESET) {
__HAL_TIM_CLEAR_FLAG(&htim1, TIM_FLAG_UPDATE);
// 执行控制算法
MPPT_Process();
Inverter_Control();
PLL_Process();
Protection_Check();
}
}
// 定时器8中断(50kHz Boost PWM)
void TIM8_UP_TIM13_IRQHandler(void)
{
if (__HAL_TIM_GET_FLAG(&htim8, TIM_FLAG_UPDATE) != RESET) {
__HAL_TIM_CLEAR_FLAG(&htim8, TIM_FLAG_UPDATE);
// 更新Boost PWM
__HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_1,
(uint32_t)(mppt.duty * htim8.Init.Period));
}
}
// ADC DMA完成中断
void DMA2_Stream0_IRQHandler(void)
{
if (__HAL_DMA_GET_FLAG(&hdma_adc1, DMA_FLAG_TCIF0_4)) {
__HAL_DMA_CLEAR_FLAG(&hdma_adc1, DMA_FLAG_TCIF0_4);
// 处理ADC数据
ADC_DMA_Callback();
}
}
六、关键参数配置
1. 系统参数
c
// system_params.h
#define SYSTEM_FREQ_HZ 50000 // PWM频率
#define CONTROL_FREQ_HZ 20000 // 控制频率
#define ADC_SAMPLE_FREQ_HZ 20000 // ADC采样频率
#define GRID_VOLTAGE_RMS 220.0f // 电网电压
#define GRID_FREQUENCY 50.0f // 电网频率
#define BUS_VOLTAGE_REF 400.0f // 母线电压参考
#define MAX_OUTPUT_POWER 3000.0f // 最大输出功率
2. 保护阈值
c
#define OV_THRESHOLD 450.0f // 过压保护
#define OC_THRESHOLD 20.0f // 过流保护
#define OT_THRESHOLD 85.0f // 过温保护
#define UV_THRESHOLD 200.0f // 欠压保护
#define OF_THRESHOLD 52.0f // 过频保护
#define UF_THRESHOLD 48.0f // 欠频保护
参考代码 光伏逆变器整套控制程序 www.youwenfan.com/contentcsu/69990.html
七、调试与测试
1. 调试接口
c
void Debug_Print_Status(void)
{
printf("PV: %.1fV %.1fA %.0fW\n",
pv_data.pv_voltage, pv_data.pv_current, pv_data.pv_power);
printf("Bus: %.1fV AC: %.1fV %.1fA\n",
pv_data.bus_voltage, pv_data.ac_voltage, pv_data.ac_current);
printf("Freq: %.2fHz Mod: %.2f Duty: %.2f\n",
pll.grid_freq, inverter.modulation, mppt.duty);
printf("MPPT: %s PLL: %s State: %d\n",
mppt.enable ? "ON" : "OFF",
pll.locked ? "LOCKED" : "UNLOCKED",
system_state);
}
2. 保护测试
c
void Protection_Test(void)
{
// 过压测试
pv_data.bus_voltage = 460.0f;
Protection_Check();
// 过流测试
pv_data.ac_current = 25.0f;
Protection_Check();
// 过温测试
pv_data.temp_igbt = 90.0f;
Protection_Check();
}
八、硬件注意事项
1. PCB布局要点
- 功率回路:尽量短而宽,减少寄生电感
- 信号回路:与功率回路分离,单点接地
- 采样电路:靠近采样点,使用屏蔽线
- 驱动电路:就近驱动IGBT,使用光耦隔离
2. EMI/EMC设计
- 输入输出加共模/差模电感
- 关键信号加磁珠滤波
- 金属外壳接地良好
- 开关频率避开敏感频段