4、软件保护策略:逐周期限流、平均值保护、有效值保护

硬件保护再快,也扛不住工况变化。我个人的习惯是,硬件保护做最后一道防线,软件保护做日常主力。为什么?因为软件能“看趋势”,能“做预判”,还能“自适应”。

这一章我们聊三个最常用的软件保护策略:逐周期限流、平均值保护、有效值保护。它们各有各的脾气,用对了地方,电机怎么折腾都不怕。

4.1 逐周期限流(Cycle-by-Cycle Current Limiting)

说白了,就是每个PWM周期都盯着电流。一旦超过阈值,立刻关掉当前周期的驱动脉冲,等下一个周期再重新开通。有点像“打地鼠”——电流冒头就拍下去。

核心思想:不让电流在单个周期内持续增长,把峰值电流锁死在设定值以下。

我在做低压无刷驱动时遇到过一个问题:启动瞬间电流飙升,硬件比较器触发了,但关断后重启又冲上去,反复震荡。后来改用逐周期限流,每个周期都做一次判断,电流被“削”得整整齐齐。

4.1.1 实现方式

通常有两种做法:

  • 比较器直接触发PWM关断:硬件比较器输出接PWM模块的故障输入引脚,响应快(几十ns),但灵活性差。
  • ADC采样+软件判断:每个PWM周期中间点采样电流,软件比较后决定是否关断。响应慢一些(几μs),但可以加滤波、加滞回。

我个人更倾向第二种。虽然慢一点,但能做的事情多。比如可以记录过流次数,判断是瞬时干扰还是真过流。

小技巧:ADC采样点选在PWM导通中间段,避开开关噪声。我一般会在导通后的30%~70%区间采样,效果最好。

4.1.2 代码示例(伪代码)

// PWM中断服务函数,每个周期执行一次
void PWM_ISR(void) {
    uint16_t adc_val = ADC_GetCurrent();  // 读取当前相电流
    
    if (adc_val > CURRENT_LIMIT_THRESHOLD) {
        PWM_DisableOutput();              // 关断当前周期输出
        overcurrent_count++;              // 记录过流次数
    } else {
        PWM_EnableOutput();               // 正常输出
        overcurrent_count = 0;            // 清零计数
    }
    
    // 如果连续过流次数超过N次,进入故障保护
    if (overcurrent_count > 3) {
        Motor_Stop();                     // 停机保护
        Error_Flag_Set(ERROR_OVERCURRENT);
    }
}

4.1.3 优缺点

优点 缺点
响应快,一个周期内就能限流 对采样时序要求高,容易受噪声干扰
实现简单,资源占用少 只能限制峰值,不能反映真实发热
适合启动、堵转等瞬时大电流场景 频繁关断会导致转矩脉动

4.2 平均值保护(Average Current Protection)

逐周期限流管的是“瞬间”,平均值保护管的是“一段时间”。它计算若干个PWM周期内的电流平均值,如果平均值超过阈值,就认为电机处于过载状态。

你想想看,电机发热靠的是平均电流,不是峰值电流。峰值电流再大,只要占空比小,平均下来也不一定烧。反过来,峰值电流不大,但一直持续,电机照样过热。

注意:平均值保护不能替代逐周期限流。它们是互补关系——一个管瞬时,一个管持续。

4.2.1 实现方式

常用的计算方法有两种:

  • 滑动窗口平均:维护一个长度为N的采样数组,每次新采样替换最旧的值,然后求平均。内存占用大,但实时性好。
  • 一阶低通滤波:用公式 avg = avg * (1 - α) + sample * α,α是滤波系数。内存占用小,但响应有滞后。

我一般用第二种。嵌入式系统内存金贵,能省就省。α取0.01~0.05之间,具体看PWM频率和需要的响应时间。

4.2.2 代码示例

#define ALPHA 0.02f  // 滤波系数

float current_avg = 0.0f;

void AverageProtection_Task(void) {
    uint16_t adc_val = ADC_GetCurrent();
    float current = (float)adc_val * ADC_TO_CURRENT;
    
    // 一阶低通滤波
    current_avg = current_avg * (1.0f - ALPHA) + current * ALPHA;
    
    if (current_avg > AVERAGE_LIMIT) {
        // 平均值超限,降低输出功率
        Motor_ReducePower(50);  // 降额50%
        avg_overcurrent_timer++;
        
        if (avg_overcurrent_timer > TIMEOUT_TICKS) {
            Motor_Stop();  // 持续超限则停机
        }
    } else {
        avg_overcurrent_timer = 0;
        Motor_RestorePower();  // 恢复正常输出
    }
}

4.2.3 应用场景

  • 启动过程:启动电流大但时间短,平均值保护不会误触发。
  • 堵转保护:堵转时电流持续偏高,平均值会快速上升。
  • 过载保护:负载波动大时,平均值能平滑反映真实负载。

4.3 有效值保护(RMS Current Protection)

有效值保护,说白了就是算电流的“真发热量”。平均值只能反映直流分量,但电机电流是交流的,尤其是无感启动阶段,电流波形可能很不规则。这时候有效值比平均值更准确。

我记得有一次做水泵项目,启动时电流波形畸变严重,平均值保护一直没触发,但电机温度却蹭蹭往上涨。后来换成有效值保护,问题就解决了。

有效值公式:IRMS = √( (1/N) * Σ(ik²) )

说白了就是:先平方,再平均,再开方。

4.3.1 实现方式

有效值计算比平均值复杂,主要开销在平方和开方。嵌入式MCU做浮点开方很慢,所以一般用查表法或近似算法。

我常用的做法:

  • 滑动窗口平方和:维护一个窗口,每次采样后累加平方值,减去最旧的平方值。开方用快速近似函数。
  • 分段线性近似:把平方和映射到有效值,用查表+插值实现。

4.3.2 代码示例

#define WINDOW_SIZE 64  // 窗口长度

uint32_t square_sum = 0;
uint16_t buffer[WINDOW_SIZE];
uint8_t index = 0;

float FastSqrt(float x) {
    // 快速开方近似,精度约1%
    if (x < 1e-6f) return 0.0f;
    float y = x;
    for (int i = 0; i < 3; i++) {
        y = (y + x / y) * 0.5f;
    }
    return y;
}

void RMSProtection_Task(void) {
    uint16_t adc_val = ADC_GetCurrent();
    float current = (float)adc_val * ADC_TO_CURRENT;
    
    // 移除最旧值,加入新值
    square_sum -= buffer[index] * buffer[index];
    buffer[index] = (uint16_t)(current * 1000);  // 放大后存整型
    square_sum += buffer[index] * buffer[index];
    index = (index + 1) % WINDOW_SIZE;
    
    // 计算有效值
    float rms = FastSqrt((float)square_sum / WINDOW_SIZE) / 1000.0f;
    
    if (rms > RMS_LIMIT) {
        Motor_ReducePower(30);  // 降额30%
        if (rms > RMS_LIMIT_CRITICAL) {
            Motor_Stop();  // 严重超限直接停机
        }
    }
}

4.3.3 三种策略对比

策略 响应速度 计算开销 保护对象 适用场景
逐周期限流 最快(1个PWM周期) 低 峰值电流 启动、堵转、短路
平均值保护 中等(几十个周期) 低 平均发热 过载、持续大电流
有效值保护 较慢(取决于窗口长度) 高 真实发热 波形畸变、不规则负载

4.4 三种策略的协同工作

实际项目中,我不会只用一种策略。三种策略各有侧重,组合起来才能覆盖所有工况。

我一般这样搭:

  • 逐周期限流做第一道防线,管住峰值。
  • 平均值保护做第二道防线,管住持续过载。
  • 有效值保护做第三道防线,管住真实发热。

优先级上,逐周期限流最高,有效值保护最低。一旦逐周期限流频繁触发,平均值和有效值保护也会跟着响应,形成“三级联动”。

避坑指南:我曾经把三种保护的阈值设得太接近,结果启动时三个保护同时触发,电机直接停机。后来把逐周期限流阈值设高10%,平均值和有效值设低一些,让它们分层次动作,效果就好多了。

4.5 本章知识体系

下面这张图展示了三种软件保护策略的关系和协同逻辑:

软件保护策略协同关系图 软件保护策略协同关系 相电流采样 逐周期限流 每个PWM周期判断 平均值保护 滑动窗口/低通滤波 有效值保护 平方平均开方 保护动作决策 降额 / 停机 / 恢复 说明: 三种策略优先级:逐周期限流 > 平均值保护 > 有效值保护。逐周期限流最快,有效值保护最准。 反馈调整阈值

嗯,这张图把三种策略的关系讲清楚了。从电流采样开始,分三路进入不同的保护逻辑,最终汇聚到保护动作决策。虚线表示策略之间的协同——比如逐周期限流频繁触发时,可以动态调整平均值保护的阈值。