4、基于电流变化率的检测法:di/dt 检测原理、噪声抑制技巧、快速响应实现

各位工程师朋友,咱们继续聊堵转检测。前面讲了稳态电流法、电压法,今天这个 di/dt 检测法,我个人认为是所有方法里响应最快的一个。说白了,它不看你电流有多大,而是看电流变化得有多快。

你想想看,电机正常转的时候,电流变化是比较平缓的。一旦堵转,转子卡住,反电动势瞬间消失,电流会像脱缰的野马一样往上冲。这个「冲」的斜率,就是 di/dt。抓住这个斜率,你就能在电流还没升到危险值之前,提前做出判断。

核心思想:堵转瞬间,电流变化率 di/dt 远大于正常工况。检测这个突变,比等电流升到阈值快得多。

4.1 di/dt 检测原理:为什么它比电流幅值法快?

咱们先看一个简单的电机等效模型。电机绕组可以看成是电阻 R 和电感 L 串联,再加上一个反电动势 E。正常运行时,电压方程是:

U = I·R + L·(di/dt) + E

堵转那一刻,转子停了,反电动势 E 几乎瞬间掉到零。这时候方程变成:

U ≈ I·R + L·(di/dt)

因为 U 和 R 基本不变,E 突然消失,那多出来的电压去哪了?全压在 L·(di/dt) 上了。所以 di/dt 会突然变大。这个变化有多快?我实测过,在 PWM 开关周期内就能看到明显的斜率跳变。

我习惯用 电流采样窗口法 来算 di/dt。具体做法是:

  1. 在 PWM 的导通区间内,连续采两个电流点 I1 和 I2
  2. 两个点的时间间隔 Δt 固定,比如 10μs
  3. 计算 di/dt = (I2 - I1) / Δt

为什么要选在 PWM 导通区间?因为关断期间电流是续流状态,波形受二极管影响大,斜率不准。这个坑我踩过,后面细说。

检测方法 响应时间 典型延迟 适用场景
电流幅值法 慢 5~20 个 PWM 周期 稳态堵转
di/dt 法 快 1~3 个 PWM 周期 瞬态堵转、快速保护
电压法 中等 3~10 个 PWM 周期 低速、静止状态

从表格能看出来,di/dt 法的响应速度是碾压级的。但快是有代价的——它对噪声极其敏感。

4.2 噪声抑制技巧:别让毛刺骗了你

嗯,这里要注意。di/dt 检测最大的敌人就是噪声。你想啊,di/dt 本身就是个微分运算,微分天生放大高频噪声。PWM 开关瞬间的尖峰、采样电阻上的振铃、甚至 ADC 的量化噪声,都会让 di/dt 的计算结果上蹿下跳。

我曾经在一个项目中,di/dt 阈值设得很低,结果电机正常转的时候频繁误触发保护。查了半天,发现是 PWM 开关边沿的尖峰被当成堵转信号了。后来怎么解决的?三个招:

4.2.1 硬件滤波:第一道防线

在电流采样信号进入 ADC 之前,加一个 低通滤波器。我一般用一阶 RC 滤波,截止频率设在 PWM 频率的 1/10 左右。比如 PWM 是 20kHz,RC 截止频率就设在 2kHz。这样能滤掉大部分开关噪声,又不会把有用的电流变化信息削掉太多。

小技巧:RC 滤波的电容不要用普通的 X7R,用 C0G 或者薄膜电容。X7R 的容值随电压变化,会导致截止频率漂移。我吃过这个亏,后来全换了 C0G。

4.2.2 软件同步采样:避开开关边沿

硬件滤波只能削弱噪声,不能完全消除。更狠的一招是:在 PWM 的中间时刻采样。PWM 开关边沿的尖峰通常持续几百纳秒到几微秒,你只要把采样点避开这个区间就行。

我习惯的做法是:

  • PWM 周期中间 50% 的区域,电流波形最平稳
  • 在这个区域里采两个点,间隔固定 Δt
  • 如果 Δt 内出现 PWM 边沿,就跳过这次计算
// 伪代码示例:同步采样与 di/dt 计算
#define SAMPLE_INTERVAL_US  10   // 采样间隔 10μs
#define DI_DT_THRESHOLD      500 // 阈值,单位 A/s

uint32_t pwm_center_time = PWM_PERIOD / 2;

void di_dt_detection(void) {
    // 等待到 PWM 中心时刻
    while(get_pwm_counter() < pwm_center_time);
    
    int16_t I1 = read_current();
    delay_us(SAMPLE_INTERVAL_US);
    int16_t I2 = read_current();
    
    int32_t di_dt = (I2 - I1) * 100000 / SAMPLE_INTERVAL_US;
    
    if(di_dt > DI_DT_THRESHOLD) {
        trigger_protection();
    }
}

4.2.3 多次平均 + 滞回比较

就算做了同步采样,偶尔还会有毛刺。我建议再加一层 滑动平均。比如连续算 3 次 di/dt,取平均值,再跟阈值比较。同时引入滞回:

  • 触发阈值:di/dt > 500 A/s 时,认为堵转
  • 恢复阈值:di/dt < 300 A/s 时,才解除堵转标志

这样能避免在阈值附近来回抖动。说白了,就是给判断加个「死区」。

注意:滑动平均的窗口不能太大。窗口大了,响应速度就慢了,那用 di/dt 法还有什么意义?我一般窗口不超过 3 个点。

4.3 快速响应实现:从检测到保护,一个 PWM 周期搞定

好,原理和噪声抑制都聊完了。怎么把响应速度做到极致?我的目标是:从堵转发生到保护动作,控制在 1~2 个 PWM 周期内。

要实现这个目标,有几个关键点:

4.3.1 用硬件比较器代替 ADC

ADC 采样 + 软件计算,再怎么快也有几十微秒的延迟。如果你对速度有极致要求,可以用 硬件比较器 直接检测电流变化率。

具体做法是:

  1. 在电流采样电阻上并联一个电容,构成微分电路
  2. 微分电路的输出正比于 di/dt
  3. 把这个输出接到比较器,跟预设阈值比较
  4. 比较器输出直接触发 PWM 关断或中断

这个方案我是在一个伺服驱动器上用的。从堵转到 PWM 关断,延迟不到 1μs。但缺点也很明显:硬件微分电路容易受温度影响,阈值不好调。而且一旦焊好,就不能软件改参数了。

4.3.2 软件快速路径:中断里只做判断,不做滤波

如果你还是用 ADC + 软件方案,那就要优化代码结构。我的习惯是:

  • 在 ADC 中断里:只做 di/dt 计算和阈值比较,不滤波、不平均
  • 在主循环里:做滑动平均、滞回判断、状态管理

这样,一旦发生真正的堵转,中断里就能立刻触发保护。而噪声引起的误触发,会在主循环里被滤波逻辑过滤掉。相当于「快判断 + 慢确认」的双保险。

// ADC 中断服务函数 - 快速路径
void ADC_IRQHandler(void) {
    static int16_t I_prev = 0;
    int16_t I_curr = read_adc();
    
    int32_t di_dt = (I_curr - I_prev) * 100000 / SAMPLE_INTERVAL_US;
    I_prev = I_curr;
    
    // 快速路径:只做简单判断,不滤波
    if(di_dt > DI_DT_FAST_THRESHOLD) {
        fast_fault_flag = 1;  // 置快速故障标志
        disable_pwm();        // 立刻关 PWM
    }
}

// 主循环 - 慢速确认
void main_loop(void) {
    if(fast_fault_flag) {
        // 做更精确的滤波判断
        if(confirm_fault()) {
            enter_protection_state();
        } else {
            fast_fault_flag = 0;  // 误触发,清除标志
            enable_pwm();
        }
    }
}

4.3.3 阈值自适应:别让参数死板

不同工况下,正常的 di/dt 是不一样的。电机启动时电流变化率本来就大,如果阈值固定,很容易误触发。我建议做 阈值自适应:

  • 正常运行时,实时统计 di/dt 的最大值,作为基准
  • 阈值 = 基准 × 系数(比如 3 倍)
  • 系数可以根据负载类型调整

这样,不管是轻载启动还是重载运行,阈值都能自动适配。

总结一下我的经验:di/dt 检测法,快是真快,但噪声是真烦。硬件滤波 + 同步采样 + 滑动平均,三管齐下才能稳住。如果追求极致速度,上硬件比较器;如果追求灵活性,用 ADC + 双路径判断。没有银弹,只有取舍。

di/dt 堵转检测流程 电流采样 计算 di/dt 噪声抑制 di/dt < 阈值 正常状态 di/dt > 阈值 堵转检测 触发保护 关键点 噪声抑制是 di/dt 法的核心:硬件滤波 + 同步采样 + 滑动平均,缺一不可

这张图把整个流程串起来了。从采样到计算,再到噪声抑制,最后分叉:正常就继续跑,堵转就触发保护。每一步都有讲究,每一步都影响最终效果。