简易无中线三相保护器开发笔记

1. 项目背景

为什么需要三相保护器?

三相电机应用广泛应该,常见于压缩机等系统中。一般电机都有特定的驱动器,驱动器一定程度起到保护作用。但是在定频压缩机系统中,电机常直接接入三相电源,缺乏智能保护。

常见故障:

  • 缺相:电机虽能继续运转,但电流骤升,绕组迅速烧毁;
  • 错相:电机反转,压缩机等设备反转会导致无法回油,最终压缩机缺油磨损;
  • 过压、欠压:电机发热,启动困难等;

因此,低成本、可靠的三相保护器就有了需求。现在如果买一个三项保护器,国产的话目前也要几十上百的,算下来成本就太高啦。

本项目中采用的是无中线方案,传统的三项检测一般都带中线作为参考。无中线意味着:

  • 无法检测对地电压,自然没有欠压之类的保护功能。
  • 缺相时,缺失相会与另一项波形完全吻合同步(踩了坑)。检测需要特殊设计。
  • 便宜。

2. 核心原理

电路可以参考1,电路部分不是我画的,不好窃取他人成果,就不贴图了。

工作原理很简单,三相电通过限流电阻分别接入三个光耦的输入端。当某相电压处于正半周且超过光耦导通阈值(约1.2V)时,该相光耦导通;负半周时光耦截止。

光耦输出端采用上拉电阻接VCC,并连接到MCU的GPIO引脚。光耦导通时,输出端被拉低至GND,GPIO检测到低电平;光耦截止时,输出端被上拉至VCC,GPIO检测到高电平。

由于三相电相位互差120°,三个GPIO会输出相位差120°的方波信号。通过检测这些方波的边沿和时序关系,即可判断是否缺相或错相。

在无中线电路中,缺相时,该相的输入会被其他相通过负载回路耦合,即会有两相的边沿始终同时出现。简单来说就是缺W相时,W相输入端没电,但因为电机绕组连着,V相的电压会”串”到W相上,导致W相的光耦被V相”带着”一起导通。

正常情况(每相互差120°):
    U: ────┐    ┌────┐    ┌────
           └────┘    └────┘
    V:  ┌────┐    ┌────┐    ┌──
       ─┘    └────┘    └────┘
    W:     ┌────┐    ┌────┐
       ────┘    └────┘    └────

缺W相(W与V同步):
    U: ────┐    ┌────┐    ┌────
           └────┘    └────┘
    V:  ┌────┐    ┌────┐    ┌──
       ─┘    └────┘    └────┘
    W:  ┌────┐    ┌────┐    ┌──
       ─┘    └────┘    └────┘

3. 检测逻辑(软件实现)

我这里设计的是实时检测模式,上层再对故障进行锁定,设计了一点容错机制。

  • 缺相检测:40ms窗口(两个工频周期)内,两相同步边沿出现≥3次 → 缺相故障;窗口超时无同步 → 自动恢复。
  • 错相检测:边沿顺序状态机,正确顺序 U→V→W 累计计数,相序错误立即报故障;连续正确≥3次 → 自动恢复。现在看起来错项好像有点太严格了~

怕硬件GPIO回读有毛刺,还加了滤波,当连续2次采样一致算,电平变化。

系统框图:

flowchart LR
    INIT[系统初始化<br/>GPIO/定时器/变量] --> TICK

    subgraph TICK [每1ms中断]
        direction LR
        PULSE[脉冲超时检测<br/>三相独立计数]
        SYNC[缺相同步检测<br/>40ms窗口同步计数]
        SEQ[相序检测<br/>U→V→W状态机]
    end

    TICK --> JUDGE{故障判定}
    JUDGE --> RELAY[继电器输出控制]
    RELAY --> TICK

核心代码部分如下:

/**
 * @brief 轮询扫描相位状态
 * @note 必须在1ms定时器中断中调用,市电一般50Hz,20ms相位变化
 */
void PhaseScanProcess(void)
{
    uint8_t u8SeqError = 0;  // 相序检测标记位(1=相序错误)
    uint8_t u8LossError = 0;  // 缺相检测标记位(1=缺相错误)
    uint8_t u8NowU = 0, u8NowV = 0, u8NowW = 0;  // 当前读到的电平结果
    uint8_t u8SumU = 0, u8SumV = 0, u8SumW = 0;  // 前3次扫描的和
    uint8_t u8StableU = 0, u8StableV = 0, u8StableW = 0;  // 稳定的电平结果
    uint8_t u8EdgeU = 0, u8EdgeV = 0, u8EdgeW = 0;  // 边沿检测结果(1=有跳变)
    uint8_t i = 0;

    // 1. 如果之前已经锁定故障或未初始化,直接返回,不再检测,防止闪断
    if (s_u8ErrorSure != 0 ||
        s_u8InitializedFlag != 1) {
        return;
    }

    // 2. 扩展板在位判断

    // 3. 读取当前IO电平 + 检测边沿 (方波脉冲) + 滤波
    u8NowU = PIN_PHASE_U;
    u8NowV = PIN_PHASE_V;
    u8NowW = PIN_PHASE_W;

    // 更新滤波器缓冲区
    s_u8FilterU[s_u8FilterIndex] = u8NowU;
    s_u8FilterV[s_u8FilterIndex] = u8NowV;
    s_u8FilterW[s_u8FilterIndex] = u8NowW;
    s_u8FilterIndex = (s_u8FilterIndex + 1) % FILTER_DEPTH;

    // 取多数值作为稳定电平
    for (i = 0; i < FILTER_DEPTH; i++) {
        u8SumU += s_u8FilterU[i];
        u8SumV += s_u8FilterV[i];
        u8SumW += s_u8FilterW[i];
    }

    u8StableU = (u8SumU > FILTER_DEPTH/2) ? 1 : 0;
    u8StableV = (u8SumV > FILTER_DEPTH/2) ? 1 : 0;
    u8StableW = (u8SumW > FILTER_DEPTH/2) ? 1 : 0;

    // 下降沿边沿检测
    u8EdgeU = (u8StableU != s_u8LastU && s_u8LastU == 1);
    u8EdgeV = (u8StableV != s_u8LastV && s_u8LastV == 1);
    u8EdgeW = (u8StableW != s_u8LastW && s_u8LastW == 1);

    s_u8LastU = u8StableU;
    s_u8LastV = u8StableV;
    s_u8LastW = u8StableW;

    // 4. 缺相检测,检测到边沿 (有脉冲),清空计时器;否则计时器+1
    s_u32TimerU = u8EdgeU ? 0 : (s_u32TimerU < 10000 ? s_u32TimerU + 1 : s_u32TimerU);
    s_u32TimerV = u8EdgeV ? 0 : (s_u32TimerV < 10000 ? s_u32TimerV + 1 : s_u32TimerV);
    s_u32TimerW = u8EdgeW ? 0 : (s_u32TimerW < 10000 ? s_u32TimerW + 1 : s_u32TimerW);
    if (s_u8TimingFlag) { s_u32SyncTimer < 10000 ? s_u32SyncTimer++: s_u32SyncTimer; }

    // 判断是否超时 (缺相),由于硬件方安为无中线方案,缺一相时,该相会与另一相完全同步
    // 持续检测是否有两相的边沿始终同步出现。
    if ((u8EdgeU && u8EdgeV) || (u8EdgeV && u8EdgeW) || (u8EdgeW && u8EdgeU)) {
        if (!s_u8TimingFlag) {
            // 首次检测到同步,启动缺相同步计时
            s_u8TimingFlag = 1;
            s_u8SyncCnt = 0;
        }
        s_u32SyncTimer = 0;
        if (s_u8SyncCnt < 255) {
            // 连续缺相同步+1;
            s_u8SyncCnt++;
        }
    }

    // 两个工频周期内连续出现超过2次同步边沿
    if (s_u8TimingFlag && s_u32SyncTimer < PULSE_LOST_TIME_MS && s_u8SyncCnt >= PHASE_SYNC_CNT) {
        u8LossError = 1;
    } else if (s_u8TimingFlag && s_u32SyncTimer >= PULSE_LOST_TIME_MS){
        // 两个工频周期内未出现同步情况
        s_u8TimingFlag = 0;
        s_u32SyncTimer = 0;
        s_u8SyncCnt = 0;
        u8LossError = 0;
    }

    if (s_u32TimerU > PULSE_LOST_TIME_MS || s_u32TimerV > PULSE_LOST_TIME_MS || s_u32TimerW > PULSE_LOST_TIME_MS ||
        u8LossError) {
        s_eFinalStatus = E_PHASE_STATUS_FAULT_PHASE_LOSS;  // 设为故障状态
        // s_u8ErrorSure = 1;
        s_ePhaseStep = E_PHASE_STEP_WAIT_U;                // 复位相序检测状态机
        s_u8SeqOk = 0;                                     // 复位相序检测计数器
        return;
    }

    // 5. 错相检测, U -> V -> W (循环)
    if (s_ePhaseStep == E_PHASE_STEP_WAIT_U) {
        //  Step 0: 等待U相的脉冲边沿
        if (u8EdgeU) {
            s_ePhaseStep = E_PHASE_STEP_WAIT_V;
        } else if (u8EdgeV || u8EdgeW) {
            u8SeqError = 1;
        }
    } else if (s_ePhaseStep == E_PHASE_STEP_WAIT_V) {
        //  Step 1: 等待V相的脉冲边沿
        if (u8EdgeV) {
            s_ePhaseStep = E_PHASE_STEP_WAIT_W;
        } else if (u8EdgeU || u8EdgeW) {
            u8SeqError = 1;
        }
    } else if (s_ePhaseStep == E_PHASE_STEP_WAIT_W) {
        //  Step 2: 等待W相的脉冲边沿
        if (u8EdgeW) {
            s_ePhaseStep = E_PHASE_STEP_WAIT_U;
            if (s_u8SeqOk < 255) {
                // 连续正确次数+1;
                s_u8SeqOk++;
            }
        } else if (u8EdgeU || u8EdgeV) {
            u8SeqError = 1;
        }
    }

    if (u8SeqError) {
        s_eFinalStatus = E_PHASE_STATUS_FAULT_WRONG_SEQUENCE;
        // s_u8ErrorSure = 1;
        s_ePhaseStep = E_PHASE_STEP_WAIT_U;
        s_u8SeqOk = 0;
    } else {
        // 最终判定: 相序是否稳定正常?
        if (s_u8SeqOk >= PHASE_SEQ_OK_CNT) {
            s_eFinalStatus = E_PHASE_STATUS_NORMAL; // 连续多次正确,判定正常
        }
    }

    return; // 正常结束
}

4. 实测

本来以为,缺相是直接上拉高电平的。结果测了之后才发现,这个缺相会产生同步的情况,于是又修改了一版。最终结果跟预期相符。用的三相调压器,还测试了不同工频下的状态,没有发现明显问题。

参考资料

  1. 哄娃睡觉. (2025). 380v三相电的相序检测,缺相检测,相序保护. https://blog.csdn.net/ddidi111/article/details/145815324 

results matching ""

    No results matching ""