3. 动态校准法:反电动势过零点检测与锁相环跟踪

上一章聊了静态校准,说白了就是给电机一个固定位置,然后测偏差。但电机真正跑起来之后,情况就复杂多了。温度在变,负载在变,磁钢特性也在变。这时候静态校准的结果可能就不太准了。

所以这一章,我们聊聊动态校准。电机转着的时候,怎么实时把电角度偏差找出来?我个人最常用的方法,就是反电动势过零点检测,配合锁相环做跟踪。这套组合拳,我在好几个量产项目里都用过,效果很稳。

3.1 反电动势过零点检测原理

先说说反电动势。电机转起来之后,定子绕组切割转子磁场,会产生一个感应电压。这个电压就叫反电动势(Back EMF)。

反电动势的波形,跟转子位置有直接关系。当转子磁极正好经过某相绕组中心线时,该相反电动势会过零点。你想想看,如果能准确抓到这些过零点,不就等于知道了转子位置吗?

具体来说,对于三相永磁同步电机,反电动势的表达式是这样的:

E_a = ω * ψ_f * sin(θ_e)
E_b = ω * ψ_f * sin(θ_e - 120°)
E_c = ω * ψ_f * sin(θ_e + 120°)

其中 ω 是电角速度,ψ_f 是永磁体磁链,θ_e 就是电角度。当 θ_e = 0° 时,E_a = 0,这就是 A 相反电动势过零点。

核心要点:反电动势过零点对应转子磁极与定子绕组轴线对齐的位置。每转过 180° 电角度,每相会出现两次过零点。对于三相系统,一个电周期内共有 6 个过零点。

我刚开始做这个的时候,犯过一个低级错误。我以为反电动势过零点就是换相点,直接用它触发换相。结果电机抖得跟筛子似的。后来才明白,过零点跟换相点之间,还差 30° 电角度。这个坑,我帮你们踩过了。

3.2 硬件检测电路设计

反电动势信号怎么采?直接采肯定不行。电机端子上有 PWM 斩波电压,幅值很高,反电动势信号被淹没了。必须等 PWM 关断期间,也就是所谓的「续流窗口」去采样。

我常用的电路结构是这样的:

电机相线 → 分压电阻 → 低通滤波 → 比较器 → 过零信号 → MCU 捕获引脚

设计时要注意几个关键点:

  • 分压比:根据母线电压选择,确保比较器输入在共模范围内。我一般取 1:10 到 1:20。
  • 低通滤波截止频率:设为 PWM 频率的 1/10 左右。比如 PWM 20kHz,滤波截止频率 2kHz。
  • 比较器滞回:加一点正反馈,防止噪声引起误触发。滞回电压通常取 50-100mV。

个人经验:比较器输出最好加一个施密特触发器整形。我曾经在一个项目中省略了这步,结果过零点抖动严重,锁相环根本锁不住。后来加了一级 74HC14,问题立刻解决。

3.3 软件过零点检测策略

硬件电路给出过零信号后,软件要做的事情就是:确认这个信号是真的过零点,而不是噪声。

我一般用三步确认法:

  1. 电平确认:捕获到边沿后,延迟一小段时间(比如 10μs),再读一次电平,确认状态稳定。
  2. 时序确认:检查本次过零点与上次过零点的时间间隔,是否在合理范围内。如果间隔突然缩短一半,大概率是误触发。
  3. 相位顺序确认:三相过零点的顺序必须是 A→B→C 或 C→B→A,不能跳相。

代码实现大致如下:

// 过零点中断服务函数
void BEMF_ZeroCrossing_ISR(uint8_t phase) {
    uint32_t now = TIM_GetCounter();
    uint32_t interval = now - last_zc_time[phase];
    
    // 步骤1:延迟确认
    delay_us(10);
    if (GPIO_ReadPin(phase_pin[phase]) != expected_level) return;
    
    // 步骤2:时序确认
    if (interval < MIN_ZC_INTERVAL) return;  // 误触发,丢弃
    if (interval > MAX_ZC_INTERVAL) return;  // 丢步,重新同步
    
    // 步骤3:相位顺序确认
    if (phase != expected_next_phase) {
        // 相位顺序错误,触发重新同步
        sync_lost_flag = 1;
        return;
    }
    
    // 更新过零点信息
    last_zc_time[phase] = now;
    zc_interval[phase] = interval;
    expected_next_phase = (phase + 1) % 3;
    
    // 通知锁相环
    PLL_Update(phase, interval);
}

注意:过零点检测在低速时效果很差。转速低于 200 RPM 时,反电动势幅值太小,信噪比急剧下降。这时候建议切换到开环强拖模式,等转速上来再切回闭环。

3.4 锁相环跟踪原理

光有过零点还不够。过零点每 60° 电角度才出现一次,中间的位置怎么办?这就需要锁相环(PLL)来插值了。

锁相环的核心思想很简单:用一个本地振荡器去跟踪输入信号的频率和相位。输入信号就是过零点序列,本地振荡器输出就是估算的电角度。

我常用的结构是二阶锁相环,包含三个部分:

  • 鉴相器(PD):比较实际过零点与估算过零点的相位差。
  • 环路滤波器(LF):对相位差进行 PI 调节,输出频率修正量。
  • 压控振荡器(VCO):根据频率修正量更新电角度估算值。

下面这张图展示了锁相环跟踪的核心流程:

锁相环跟踪电角度流程图 过零点序列 鉴相器 (PD) 环路滤波器 (LF) 压控振荡器 (VCO) 估算电角度 估算过零点 核心公式 θ_est = ∫(ω_0 + Δω)dt Δω = Kp·Δθ + Ki·∫Δθ dt

3.5 环路参数整定

锁相环好不好用,全看参数整定。我见过不少工程师,PLL 参数随便填,结果要么跟踪太慢,要么震荡发散。

环路滤波器的传递函数是:

H(s) = Kp + Ki / s

其中 Kp 决定响应速度,Ki 决定稳态精度。整定时我遵循以下原则:

参数 作用 整定方法 典型值范围
Kp 比例增益,决定跟踪速度 先调 Kp 使系统不震荡,再逐步增大 0.5 ~ 5.0
Ki 积分增益,消除稳态误差 Kp 调好后,Ki 从 0.1 开始往上加 0.01 ~ 0.5
带宽 决定抗噪声能力 带宽 = Kp / (2π),一般取 10~50 Hz 10 ~ 50 Hz

我的调试习惯:先把 Ki 设为 0,只调 Kp。让系统能跟上转速变化但不震荡。然后慢慢加 Ki,直到稳态误差消失。最后再微调一下 Kp,让动态响应和稳态精度都满意。整个过程大概需要半小时。

3.6 偏差补偿与角度融合

锁相环输出的是估算电角度 θ_est。但这个角度跟真实电角度之间,还是有偏差的。这个偏差来自哪里?

  • 硬件延迟:滤波电路、比较器、光耦都会引入延迟。延迟时间乘以电角速度,就是相位误差。
  • 软件延迟:中断响应时间、AD 采样时间、计算时间,都会造成角度滞后。
  • 负载效应:重载时,反电动势波形会畸变,过零点位置会偏移。

补偿方法我分两步走:

  1. 固定补偿:测量硬件和软件的总延迟时间,在估算角度上加上一个固定偏移量。比如延迟 50μs,当前转速 3000 RPM(电频率 200Hz),那么补偿角度 = 360° × 200 × 50e-6 = 3.6°。
  2. 自适应补偿:利用电流环的 q 轴电流反馈,判断角度是否准确。如果 q 轴电流指令和实际值偏差大,说明角度有误差,微调补偿量。

最终输出的电角度是:

θ_final = θ_pll + θ_offset_fixed + θ_offset_adaptive

曾经踩过的坑:有一次我在一个项目中,固定补偿算得很准,空载时效果完美。但一加载,电机就开始抖。查了两天才发现,重载时反电动势波形畸变,过零点偏移了。后来加了自适应补偿,根据 q 轴电流实时修正,问题才解决。所以,固定补偿只适用于轻载或恒载场景,变载场合必须上自适应。

3.7 性能对比与适用场景

动态校准法跟静态校准法比,各有优劣。我整理了一个对比表:

对比项 静态校准法 动态校准法(反电动势+PLL)
校准时机 电机静止时 电机运行中持续校准
精度 高(±1°以内) 中等(±3°~±5°)
抗干扰能力 强 中等(受 PWM 噪声影响)
低速性能 适用 不适用(低于 200 RPM 失效)
实现复杂度 低 中高
适用场景 启动前校准、高精度场合 中高速运行、变载场合

我个人建议,实际项目中把两种方法结合起来用。启动前做一次静态校准,得到初始偏差。运行中用动态校准法持续跟踪和修正。这样既保证了启动精度,又兼顾了运行中的实时性。

嗯,动态校准法就聊到这里。这套方法我用了很多年,从早期的方波驱动到现在的正弦波驱动,核心思想一直没变。关键是把过零点抓准,把 PLL 参数调好,剩下的就是水到渠成的事。