小型离线风光互补式发电系统(基于STM32)
一、系统总体架构
小型离线风光互补发电系统是一种独立运行的微电网系统,它将风能和太阳能这两种清洁能源结合起来,弥补单一能源受天气影响大的缺点,为偏远地区、家庭、基站或户外设备提供稳定可靠的电力。STM32凭借其强大的运算能力和丰富的外设(ADC、高级定时器、DMA),是此类系统最理想的核心控制器。
1.1 系统能量拓扑结构
┌─────────────────────────────┐
│ 能量流向与管理系统 │
┌─────────┐ ┌───┐ ┌─────────┐ ┌───┐ ┌─────────┐
│ 风力发电 │ │整流│ │ │ │逆变│ │ 交流负载 │
│ 机组 ├─┤桥堆├──┤ STM32 ├──┤器 │ │ (照明/电器)│
└─────────┘ └───┘ │ 智能 │ └───┘ └─────────┘
│ 控制器 │ │
│ (F407/ │ │
┌─────────┐ ┌───┐ │ F334) │ ┌───┐ ┌─────────┐
│ 太阳能 │ │MPPT│ │ ├───┤DC/DC│ │ 直流负载 │
│ 光伏板 ├──┤升降压│────┤ ├───┤变换│ │ (LED/监控)│
└─────────┘ └───┘ │ │ └───┘ └─────────┘
│ │
└────┬────┘
│
┌────▼────┐
│ 储能系统 │
│ (铅酸/ │
│ 磷酸铁锂) │
└─────────┘
1.2 核心运行逻辑
- 发电端:风机发出不稳定的交流电,经整流桥变为直流电;光伏板发出直流电。两者汇合接入STM32控制的 MPPT(最大功率点跟踪)升压电路。
- 储能端:电能经过MPPT后,送入蓄电池组。STM32实时监测电池电压/电流,执行智能充电管理(防过充)。
- 用电端:当负载需要时,蓄电池的直流电经过STM32控制的 逆变电路(SPWM调制) 转变为纯净的正弦交流电,或者直接供给直流负载。
二、硬件核心设计
2.1 关键元器件选型表
| 模块分类 | 推荐型号/参数 | 数量 | 功能说明 |
|---|---|---|---|
| 主控芯片 | STM32F334 / STM32F407 | 1 | 拥有高速ADC、高级定时器(适合做逆变SPWM)和运算放大器 |
| 风力发电机 | 300W / 12V 永磁同步风机 | 1 | 离网型,通常自带尾翼 |
| 光伏板 | 100W / 18V 单晶硅 | 1-2块 | 需根据当地平均日照配置 |
| 整流桥 | KBPC3510 (35A/1000V) | 1 | 将风机三相/单相交流电整流为直流电 |
| 功率电感 | 铁硅铝磁环电感 220uH / 20A | 1 | MPPT升压电路核心储能元件 |
| 功率MOS管 | IRF3205 (55V/110A) | 4-6个 | 分别用于MPPT升压和全桥逆变 |
| 蓄电池 | 12V 100Ah 铅酸 / 磷酸铁锂 | 1组 | 系统的能量缓冲池 |
| 采样电阻 | 康铜丝/锰铜丝 5mΩ / 10A | 2个 | 串联在母线中,用于STM32进行电流采样 |
2.2 功率电路拓扑
- MPPT升压电路:采用 同步Buck-Boost拓扑 或 Boost拓扑。STM32通过调整PWM占空比,调节光伏板和风机输出阻抗,使其始终工作在最大功率点。
- 全桥逆变电路:采用 H桥拓扑(4个MOS管组成)。STM32的高级定时器(TIM1/TIM8)输出互补的SPWM波形,经过驱动芯片(如IR2110)放大后驱动MOS管。
- 采样电路:利用运放(如LM358/INA240)将几十安培的电流转化为0-3.3V的电压信号,送入STM32的ADC引脚。
三、软件控制系统设计(基于标准库)
3.1 系统数据结构定义
/* 风光互补发电系统数据结构 */
#include "stm32f10x.h"
#include "stm32f10x_adc.h"
#include "stm32f10x_tim.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "misc.h"
#include <stdio.h>
#include <math.h>
// 系统运行状态
typedef enum {
SYS_INIT = 0, // 系统初始化
SYS_CHARGING = 1, // 正常充电中
SYS_FULL = 2, // 电池充满
SYS_DISCHARGING = 3, // 电池放电
SYS_FAULT = 4, // 系统故障(过压/过流/短路)
SYS_STANDBY = 5 // 待机模式(夜间/无风无光)
} SystemState;
// 能量数据类型
typedef struct {
float pv_voltage; // 光伏板电压 (V)
float pv_current; // 光伏板电流 (A)
float pv_power; // 光伏板功率 (W)
float wind_voltage; // 风机整流后电压 (V)
float wind_current; // 风机电流 (A)
float wind_power; // 风机功率 (W)
float battery_voltage; // 蓄电池电压 (V)
float battery_current; // 电池充放电电流 (A) 正为充,负为放
float battery_soc; // 电池剩余电量 (SOC, 0-100%)
float ambient_temp; // 环境温度 (°C)
} EnergyData;
// 控制参数
typedef struct {
float mppt_target_voltage; // MPPT目标电压
float charge_current_limit; // 充电限流 (A)
uint16_t inverter_duty; // 逆变器PWM占空比
uint8_t ac_output_enable; // 交流输出使能
} ControlParam;
// 全局变量
EnergyData energy_data;
ControlParam ctrl_param;
SystemState sys_state = SYS_INIT;
volatile uint32_t system_tick = 0;
3.2 数据采集系统(ADC)
/* ADC数据采集与滤波 */
// 定义ADC通道对应的电压电流
// PA0 - 光伏电压, PA1 - 光伏电流, PA2 - 风电电压
// PA3 - 风电电流, PA4 - 电池电压, PA5 - 电池电流
#define ADC_VOLTAGE_REF 3.3f // ADC参考电压
#define ADC_RESOLUTION 4096.0f // 12位ADC精度
#define VOLT_DIV_RATIO 11.0f // 电压分压比 (100k & 10k)
#define CURR_SENSE_RES 0.005f // 采样电阻阻值 (5毫欧)
#define CURR_AMP_GAIN 20.0f // 电流放大倍数
/* 滑动平均滤波 */
float moving_average_filter(float new_value, float *buffer, uint8_t size) {
static uint8_t index = 0;
static float sum = 0;
sum -= buffer[index]; // 减去旧值
buffer[index] = new_value; // 放入新值
sum += new_value; // 加上新值
index = (index + 1) % size;
return sum / size;
}
/* 读取并更新能量数据 */
void update_energy_data(void) {
uint16_t adc_raw[6];
float adc_voltages[6];
// 读取ADC原始数据(假设已通过DMA或轮询获取)
// adc_raw[0] -> PV Voltage, adc_raw[1] -> PV Current, etc.
// 转换为实际物理电压
for (uint8_t i = 0; i < 6; i++) {
adc_voltages[i] = (adc_raw[i] / ADC_RESOLUTION) * ADC_VOLTAGE_REF;
}
// 还原真实物理量
energy_data.pv_voltage = adc_voltages[0] * VOLT_DIV_RATIO;
energy_data.pv_current = (adc_voltages[1] / CURR_AMP_GAIN) / CURR_SENSE_RES;
energy_data.pv_power = energy_data.pv_voltage * energy_data.pv_current;
energy_data.wind_voltage = adc_voltages[2] * VOLT_DIV_RATIO;
energy_data.wind_current = (adc_voltages[3] / CURR_AMP_GAIN) / CURR_SENSE_RES;
energy_data.wind_power = energy_data.wind_voltage * energy_data.wind_current;
energy_data.battery_voltage = adc_voltages[4] * VOLT_DIV_RATIO;
energy_data.battery_current = (adc_voltages[5] / CURR_AMP_GAIN) / CURR_SENSE_RES;
// 防止数据异常跳动
if (energy_data.pv_current < 0) energy_data.pv_current = 0;
if (energy_data.wind_current < 0) energy_data.wind_current = 0;
}
3.3 MPPT控制算法(扰动观察法)
/* MPPT最大功率点跟踪 */
typedef struct {
float prev_power; // 上一时刻的功率
float prev_voltage; // 上一时刻的电压
uint8_t perturb_dir; // 扰动方向:0减小占空比,1增大占空比
uint16_t mppt_duty; // 当前MPPT占空比
} MPPT_State;
MPPT_State mppt_solar; // 光伏MPPT状态机
MPPT_State mppt_wind; // 风机MPPT状态机
/* 扰动观察法核心逻辑 */
uint16_t MPPT_Perturb_Observe(MPPT_State *mppt, float curr_power, float curr_voltage) {
float delta_power = curr_power - mppt->prev_power;
float delta_voltage = curr_voltage - mppt->prev_voltage;
// 1. 判断功率变化方向
if (delta_power > 0) {
// 功率增加,继续沿原方向扰动
if (mppt->perturb_dir == 0) {
mppt->mppt_duty -= 5; // 减小占空比 -> 升高母线电压
} else {
mppt->mppt_duty += 5; // 增大占空比 -> 降低母线电压
}
} else {
// 功率减小,反转扰动方向
if (mppt->perturb_dir == 0) {
mppt->mppt_duty += 5;
mppt->perturb_dir = 1;
} else {
mppt->mppt_duty -= 5;
mppt->perturb_dir = 0;
}
}
// 限制占空比范围 (例如 10% ~ 90%)
if (mppt->mppt_duty < 100) mppt->mppt_duty = 100;
if (mppt->mppt_duty > 900) mppt->mppt_duty = 900;
// 更新历史数据
mppt->prev_power = curr_power;
mppt->prev_voltage = curr_voltage;
return mppt->mppt_duty;
}
/* MPPT控制任务 */
void mppt_control_task(void) {
// 只有当光照和风力达到一定阈值时才启动MPPT
if (energy_data.pv_voltage > 15.0f) { // 光伏有光照
uint16_t solar_duty = MPPT_Perturb_Observe(
&mppt_solar,
energy_data.pv_power,
energy_data.pv_voltage
);
// 将新的占空比写入PWM寄存器
TIM_SetCompare1(TIM1, solar_duty);
}
if (energy_data.wind_voltage > 12.0f) { // 风机在转动
uint16_t wind_duty = MPPT_Perturb_Observe(
&mppt_wind,
energy_data.wind_power,
energy_data.wind_voltage
);
// 将新的占空比写入PWM寄存器
TIM_SetCompare2(TIM1, wind_duty);
}
}
3.4 蓄电池智能充电策略(三段式)
/* 蓄电池充放电管理 */
typedef enum {
CHARGE_STAGE_CC = 0, // 恒流充电阶段
CHARGE_STAGE_CV = 1, // 恒压充电阶段
CHARGE_STAGE_FLOAT = 2, // 浮充/涓流充电阶段
DISCHARGE_NORMAL = 3, // 正常放电
DISCHARGE_CUTOFF = 4 // 欠压截止
} BatteryStage;
BatteryStage bat_stage = CHARGE_STAGE_CC;
/* 12V铅酸电池三段式充电参数 */
#define BAT_BULK_VOLTAGE 14.4f // 恒压阶段电压上限
#define BAT_FLOAT_VOLTAGE 13.6f // 浮充电压
#define BAT_CUTOFF_VOLTAGE 10.8f // 欠压保护电压
#define BAT_CHARGE_CURRENT_MAX 20.0f // 最大充电电流
/* 电池状态机管理 */
void battery_management_task(void) {
// 1. 欠压保护(最高优先级)
if (energy_data.battery_voltage < BAT_CUTOFF_VOLTAGE) {
bat_stage = DISCHARGE_CUTOFF;
sys_state = SYS_FAULT;
printf("WARNING: Battery Undervoltage Cutoff!\n");
// 强制关闭逆变器,防止电池损坏
ctrl_param.ac_output_enable = 0;
return;
}
// 2. 根据电压判断充电阶段
switch (bat_stage) {
case CHARGE_STAGE_CC: // 恒流阶段:电流达到最大值,电压缓慢上升
if (energy_data.battery_voltage >= BAT_BULK_VOLTAGE) {
bat_stage = CHARGE_STAGE_CV; // 切换到恒压阶段
printf("Switch to Constant Voltage stage.\n");
}
// 控制充电电流不超过最大限值
if (energy_data.battery_current > BAT_CHARGE_CURRENT_MAX) {
// 减小MPPT输出功率
mppt_solar.mppt_duty += 10;
}
break;
case CHARGE_STAGE_CV: // 恒压阶段:电压恒定,电流逐渐下降
if (energy_data.battery_current < 1.0f) { // 电流降到很小
bat_stage = CHARGE_STAGE_FLOAT;
printf("Switch to Float Charge stage.\n");
}
break;
case CHARGE_STAGE_FLOAT: // 浮充阶段:维持满电状态
if (energy_data.battery_voltage > BAT_FLOAT_VOLTAGE + 0.2f) {
// 稍微过充,减小输入
mppt_solar.mppt_duty += 5;
}
break;
}
// 更新SOC估算(简单的电压法,实际应用可用库仑计法)
energy_data.battery_soc = (energy_data.battery_voltage - 10.5f) / (14.4f - 10.5f) * 100.0f;
if (energy_data.battery_soc > 100) energy_data.battery_soc = 100;
if (energy_data.battery_soc < 0) energy_data.battery_soc = 0;
}
3.5 离网正弦波逆变器(SPWM)
/* SPWM正弦波逆变器控制 */
// 正弦波查找表 (50Hz, 10kHz载波,200个采样点)
const uint16_t sin_table[200] = {
512, 544, 575, 607, 638, 669, 699, 729, 758, 786,
// ... 中间省略 180 个数据点 ...
758, 729, 699, 669, 638, 607, 575, 544, 512
};
volatile uint16_t spwm_index = 0;
/* 定时器1更新中断 - 生成SPWM */
void TIM1_UP_TIM16_IRQHandler(void) {
if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET) {
if (ctrl_param.ac_output_enable) {
// 取正弦表的值作为占空比
uint16_t target_duty = sin_table[spwm_index];
// 更新PWM比较寄存器,产生正弦调制波
TIM_SetCompare1(TIM1, target_duty); // 通道1 输出正弦+
TIM_SetCompare2(TIM1, target_duty); // 通道2 输出正弦- (需经死区及反向逻辑处理)
// 指向下一个采样点
spwm_index++;
if (spwm_index >= 200) {
spwm_index = 0;
}
} else {
// 关闭输出,占空比置零
TIM_SetCompare1(TIM1, 0);
TIM_SetCompare2(TIM1, 0);
}
TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
}
}
参考资料 小型离线风光互补式发电系统 www.youwenfan.com/contentcnt/133229.html
四、系统能量调度策略
4.1 智能调度逻辑
/* 系统能量调度与状态管理 */
void system_energy_scheduler(void) {
float total_input_power = energy_data.pv_power + energy_data.wind_power;
float total_load_power = 0.0f; // 假设从负载电流采样计算得到
switch (sys_state) {
case SYS_INIT:
if (energy_data.battery_voltage > 11.0f) {
sys_state = SYS_STANDBY;
printf("System Boot Complete.\n");
}
break;
case SYS_STANDBY:
// 只要有风或有光,就转入充电模式
if (total_input_power > 10.0f) {
sys_state = SYS_CHARGING;
}
// 如果有负载请求且电池足够,转入放电
if (total_load_power > 5.0f && energy_data.battery_soc > 30) {
sys_state = SYS_DISCHARGING;
ctrl_param.ac_output_enable = 1;
}
break;
case SYS_CHARGING:
// 如果充电已满,转入浮充或待机
if (bat_stage == CHARGE_STAGE_FLOAT) {
sys_state = SYS_FULL;
}
// 如果无风无光且电池未满(防止电池饿死)
if (total_input_power < 1.0f) {
sys_state = SYS_STANDBY;
}
break;
case SYS_FULL:
// 电池满了,多余的电能可以接入假负载(泄放电阻)或者直接停机
if (total_input_power > 50.0f) {
// 启用卸荷电路(控制一个MOS管接通水泥电阻)
GPIO_SetBits(GPIOB, GPIO_Pin_12);
}
break;
case SYS_DISCHARGING:
// 电池放电过低
if (energy_data.battery_soc < 20) {
sys_state = SYS_STANDBY;
ctrl_param.ac_output_enable = 0; // 切断输出保护电池
}
break;
}
}
五、主程序与系统集成
5.1 主程序框架
/* 主程序:风光互补发电系统 */
#include "stm32f10x.h"
#include "system_stm32f10x.h"
// 系统时钟滴答
void SysTick_Init(void) {
SysTick_Config(SystemCoreClock / 1000); // 1ms中断
}
void SysTick_Handler(void) {
system_tick++;
}
uint32_t Get_SystemTick(void) {
return system_tick;
}
int main(void) {
// 1. 底层硬件初始化
SystemInit();
SysTick_Init();
// 2. 外设初始化
USART1_Init(115200); // 用于电脑监控/调试
ADC_DMA_Init(); // 模拟量采集 (电流、电压)
PWM_MPPT_Init(); // MPPT升压电路 PWM (e.g., TIM1 CH1/CH2)
PWM_Inverter_Init(); // 逆变器 SPWM (e.g., TIM8 CH1/CH2)
Relay_Init(); // 继电器/卸荷控制
printf("\r\n==== Small Wind-Solar Hybrid Power System ====\r\n");
printf("System Version 1.0\r\n");
// 3. 系统参数初始化
mppt_solar.prev_power = 0;
mppt_solar.mppt_duty = 500; // 初始占空比 50%
energy_data.battery_soc = 50.0f; // 假定初始半电
sys_state = SYS_INIT;
printf("System Ready. Entering Main Loop...\r\n");
// 4. 主循环
while (1) {
// --- 10ms 快速控制任务 ---
// 1. 数据采集与滤波
update_energy_data();
// 2. MPPT追踪(每100ms运行一次即可,这里为了演示)
static uint32_t last_mppt_time = 0;
if (Get_SystemTick() - last_mppt_time >= 100) {
mppt_control_task();
last_mppt_time = Get_SystemTick();
}
// 3. 电池充放电管理
battery_management_task();
// --- 1s 慢速调度与监控任务 ---
static uint32_t last_second_time = 0;
if (Get_SystemTick() - last_second_time >= 1000) {
// 4. 能量调度状态机
system_energy_scheduler();
// 5. 状态上报
printf("PV: %.1fW | Wind: %.1fW | Bat: %.1fV (SOC:%d%%) | State: %d\r\n",
energy_data.pv_power,
energy_data.wind_power,
energy_data.battery_voltage,
(uint8_t)energy_data.battery_soc,
sys_state);
last_second_time = Get_SystemTick();
}
// 延时,防止主循环空转过快
for (volatile uint32_t i = 0; i < 5000; i++);
}
}
六、总结
基于STM32的小型离线风光互补发电系统是一个集电力电子、嵌入式控制和新能源技术于一体的综合性项目。