2. 三相逆变器工作原理

任务目标

搭建一个三相两电平逆变器的理想开关模型,通过控制六个开关管的通断组合,观察相电压与线电压的波形关系,并定量分析死区时间对输出电压波形畸变的影响。

核心原理与实现方案

三相逆变器由六个IGBT(Q1~Q6)组成三个半桥。同一桥臂上下管互补导通,禁止同时导通。采用SPWM调制时,载波与三相正弦调制波比较生成开关信号。死区时间是在上下管切换瞬间插入的延时,防止直通短路,但会造成输出电压基波幅值损失和低次谐波增加。

本仿真使用Python实现理想开关模型,忽略管压降与开关暂态,仅保留死区延时逻辑,以聚焦开关状态与电压关系。

环境依赖

numpy, matplotlib

关键完整代码

import numpy as np
import matplotlib.pyplot as plt

# 参数设置
fs = 10000          # 载波频率 10kHz
fc = 50             # 调制波频率 50Hz
Vdc = 300           # 直流母线电压
dt_dead = 5e-6      # 死区时间 5us
duration = 0.04     # 仿真时长 2个工频周期
Ts = 1e-7           # 仿真步长 100ns

t = np.arange(0, duration, Ts)
N = len(t)

# 三相调制波 (幅值0.8)
ma = 0.8
va = ma * np.sin(2*np.pi*fc*t)
vb = ma * np.sin(2*np.pi*fc*t - 2*np.pi/3)
vc = ma * np.sin(2*np.pi*fc*t + 2*np.pi/3)

# 三角载波 (0~1)
carrier = 2 * (t*fs % 1) - 1  # 双极性载波 -1~1

# 理想SPWM比较 (无死区)
def spwm_ideal(mod):
    return mod > carrier

# 加入死区后的开关信号
def spwm_dead(mod, prev_state):
    """prev_state: 上一时刻上管状态, 返回当前上管状态"""
    raw = mod > carrier
    # 上管关断沿插入死区
    if prev_state == 1 and raw == 0:
        # 需要死区延时,但步长远小于死区,用计数实现
        return 0  # 立即关断,下管延时开通由下管逻辑处理
    elif prev_state == 0 and raw == 1:
        # 上管开通需等待死区
        return 0
    else:
        return raw

# 向量化实现死区(使用状态机简化:逐点判断)
def apply_deadtime(raw_upper, dt_samples):
    """raw_upper: 理想上管信号, dt_samples: 死区对应采样点数"""
    n = len(raw_upper)
    upper = np.zeros(n, dtype=int)
    lower = np.zeros(n, dtype=int)
    # 记录上次切换时刻
    last_switch = -dt_samples*2
    for i in range(n):
        if raw_upper[i] == 1:
            # 上管导通:检查是否已过死区
            if i - last_switch >= dt_samples:
                upper[i] = 1
                lower[i] = 0
            else:
                upper[i] = 0
                lower[i] = 0  # 死区内全关
        else:
            # 上管关断:下管导通需死区延时
            if i - last_switch >= dt_samples:
                upper[i] = 0
                lower[i] = 1
            else:
                upper[i] = 0
                lower[i] = 0
        if upper[i] != raw_upper[i] or (i>0 and upper[i]!=upper[i-1]):
            last_switch = i
    return upper, lower

dt_samples = int(dt_dead / Ts)

# 生成三相理想与死区信号
upper_a_ideal = (va > carrier).astype(int)
upper_b_ideal = (vb > carrier).astype(int)
upper_c_ideal = (vc > carrier).astype(int)

ua_d, la_d = apply_deadtime(upper_a_ideal, dt_samples)
ub_d, lb_d = apply_deadtime(upper_b_ideal, dt_samples)
uc_d, lc_d = apply_deadtime(upper_c_ideal, dt_samples)

# 相电压计算 (中性点N为虚拟直流中点)
def phase_voltage(upper, lower):
    # 上管导通接+Vdc/2,下管导通接-Vdc/2,全关时悬空(取前一状态)
    v = np.zeros(len(upper))
    prev = 0
    for i in range(len(upper)):
        if upper[i] == 1:
            v[i] = Vdc/2
            prev = Vdc/2
        elif lower[i] == 1:
            v[i] = -Vdc/2
            prev = -Vdc/2
        else:
            v[i] = prev  # 死区保持
    return v

va_ideal = phase_voltage(upper_a_ideal, 1-upper_a_ideal)
vb_ideal = phase_voltage(upper_b_ideal, 1-upper_b_ideal)
vc_ideal = phase_voltage(upper_c_ideal, 1-upper_c_ideal)

va_dead = phase_voltage(ua_d, la_d)
vb_dead = phase_voltage(ub_d, lb_d)
vc_dead = phase_voltage(uc_d, lc_d)

# 线电压
vab_ideal = va_ideal - vb_ideal
vab_dead = va_dead - vb_dead

# 绘图
plt.figure(figsize=(12, 8))
plt.subplot(3,1,1)
plt.plot(t*1000, va_ideal, label='A相理想', lw=0.8)
plt.plot(t*1000, va_dead, label='A相含死区', lw=0.8, alpha=0.7)
plt.ylabel('相电压(V)')
plt.legend()
plt.xlim(0, 40)

plt.subplot(3,1,2)
plt.plot(t*1000, vab_ideal, label='线电压理想', lw=0.8)
plt.plot(t*1000, vab_dead, label='线电压含死区', lw=0.8, alpha=0.7)
plt.ylabel('线电压(V)')
plt.legend()
plt.xlim(0, 40)

plt.subplot(3,1,3)
# 放大观察死区效应
mask = (t>0.02) & (t<0.0205)
plt.plot(t[mask]*1000, va_ideal[mask], label='理想', lw=1.5)
plt.plot(t[mask]*1000, va_dead[mask], '--', label='含死区', lw=1.5)
plt.xlabel('时间(ms)')
plt.ylabel('A相电压(V)')
plt.legend()
plt.title('死区引起的电压脉冲缺失')
plt.tight_layout()
plt.show()

# 计算基波幅值对比
def fundamental_amp(v, fc, t):
    # 用傅里叶系数计算基波幅值
    cos_comp = 2/len(t) * np.sum(v * np.cos(2*np.pi*fc*t))
    sin_comp = 2/len(t) * np.sum(v * np.sin(2*np.pi*fc*t))
    return np.sqrt(cos_comp**2 + sin_comp**2)

amp_ideal = fundamental_amp(va_ideal, fc, t)
amp_dead = fundamental_amp(va_dead, fc, t)
print(f"理想基波幅值: {amp_ideal:.2f}V")
print(f"含死区基波幅值: {amp_dead:.2f}V")
print(f"幅值损失: {amp_ideal-amp_dead:.2f}V ({(amp_ideal-amp_dead)/amp_ideal*100:.2f}%)")

运行与验证

运行方式:直接执行上述Python脚本,需已安装numpy和matplotlib。

预期输出:

  • 三幅波形图:相电压对比、线电压对比、局部放大图
  • 控制台输出基波幅值对比数据

通过判定标准:

  1. 理想相电压为六阶梯波(幅值±150V),线电压为±300V、±150V、0V三电平
  2. 含死区波形在电流换向处出现电压脉冲缺失,局部放大图中可见明显缺口
  3. 基波幅值损失约1%~3%(与死区时间占比相关),控制台输出的幅值损失百分比在合理范围
  4. 死区时间增大时(如改为20μs),电压损失比例应近似线性增加

死区影响定量分析

死区导致的电压误差与开关频率和死区时间成正比:ΔV ≈ f_sw × t_dead × Vdc。本仿真中f_sw=10kHz,t_dead=5μs,Vdc=300V,理论误差约15V,与仿真结果接近。死区还使输出电压出现3、5、7次等低次谐波,在电机驱动中会引起电流畸变和转矩脉动。

三相两电平逆变器拓扑与死区效应 +Vdc/2 -Vdc/2 Q1 Q4 A Q3 Q6 B Q5 Q2 C 理想PWM: 含死区: 死区(全关)

常见问题:若波形出现异常,检查载波频率与仿真步长关系,确保dt_samples至少为5个采样点;死区逻辑中"全关"状态会导致相电压悬空,本模型采用保持前一状态近似,实际电路中由续流二极管提供通路。