ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

高频方波注入原理与零速启动实现:无感FOC完整技术路线

高频方波注入原理与零速启动实现:无感FOC完整技术路线 高频方波注入这几个字在无感FOC圈子里讨论度一直不低尤其是做空调压缩机、电动工具、水泵这类需要重载起动的项目几乎绕不开。零速或者极低速下反电动势为零传统滑模观测器、龙伯格观测器全部失效这时候高频注入就是少数能干活的方案之一。这篇文章我把高频方波注入的原理、解调算法、参数选取和一份可以直接参考的代码示例一起放出来给正在折腾电机零速启动的朋友一条完整的技术路线。这篇文章适合两类人看一是已经跑通FOC基础框架但被零速低速段折磨的工程师二是准备做无感FOC项目正在做技术预研的硬件或算法工程师。前者可以直接跳到第4章拿代码后者建议从第1章开始把原理过一遍。我会把我踩过的坑、试错过程中掉过的链子以及最终稳定的调参经验全部写出来尽量不让你再经历一遍。需要说明的是本文讨论的对象是PMSM永磁同步电机凸极率的来源和表贴电机有区别但方法论的迁移性很强。你手上如果是表贴电机只要凸极率够用同样可以套用。1. 零速启动为什么难先说清楚无感FOC的底层逻辑1.1 反电动势法在中高速段很香但在零速段失灵无感FOC的核心难点在于没有编码器却要知道转子位置。中高速下我们依赖的是反电动势——电机旋转时转子上的永磁体在定子绕组中感生出电动势这个电动势的相位包含着转子位置信息。反电动势的大小和转速成正比这是物理规律。转速为零时反电动势也为零转速很低时反电动势只有一丁点。滑模观测器这类基于反电动势的算法在10%额定转速以下信噪比就开始急剧恶化到了5%以下基本就是乱跳零速更是直接失效。这不是观测器做得不好而是物理层面信号就接近为零。你可以理解为在黑屋子里用眼睛找东西还有微弱光线时勉强能看见轮廓完全没光时眼睛再好也没用。反电动势法就是那对眼睛而高频注入相当于自己带了一只手电筒。1.2 抛开反电动势还有什么信息能感知转子位置既然反电动势靠不住就得换一条路。电机定子绕组不是一个理想的电感它的电感会随转子位置变化而变化——特别是IPM内嵌式永磁同步电机d轴和q轴磁路有明显差异凸极率通常在1.5到3之间。这种结构上的不对称导致高频电流在不同转子位置下的响应不同。思路就出来了向定子绕组注入一个高频电压信号然后去观察高频电流的响应。响应的差异里就藏着转子位置信息。由于高频信号是主动注入的和反电动势无关所以哪怕电机静止不动信息也在那里。这就是高频注入能在零速工作最根本的原因。高频注入根据波形分两类高频正弦注入和高频方波注入。正弦注入起来绕、带宽低、需要滤波器方波注入简单直接数字化实现方便而且不需要额外增加信号发生器靠PWM中断时基就能做非常适合单片机实现。1.3 高低速方案如何配合一个完整的无感FOC系统分工实际工程中单一观测器很难覆盖0到额定转速全域。我见过很多方案是这样一个分工零速和低速段0~5%额定转速高频方波注入负责提供转子位置和速度中高速段10%额定转速以上滑模观测器或反电动势观测器负责中间区域5%~10%做切换过渡可以用加权混合也可以用状态机强制执行为什么不能一个算法吃到底因为高频注入在中高速时存在两个问题一是基波电压变大高频电流响应会被淹没信噪比下降二是注入频率和旋转频率混合解调复杂度上升。反电动势法在高速段则越用越准两个算法的优势区间恰好互补。后面我会详细讲这个切换怎么做重点是你需要在零速段把高频注入跑稳切换只是水到渠成的事。2. 高频方波注入的原理凸极效应是怎么变成转子角度的2.1 从磁路差异说起为什么IPM电机天生适合高频注入在数学模型上IPM电机的d轴磁路会遇到更多的铁心饱和和磁阻变化而q轴磁路相对通畅这就形成了d轴电感小于q轴电感。这个差值越大凸极率越高高频注入的信号就越强越容易解调。对PMSM建立高频模型时通常忽略电阻影响只用电感特性来分析。在转子同步旋转坐标系下高频电压与高频电流之间的关系可以通过一个包含转子位置信息的电感矩阵来描述。当观测器使用的估计坐标系与真实转子坐标系之间存在角度误差时这个矩阵不再是对角阵d轴的高频电压就会在q轴产生高频电流响应q轴响应的大小正比于角度误差。这一段原理比较抽象我用一句话总结只要转子位置估计不准你注入的d轴电压就会在q轴电流上留下痕迹而这个痕迹恰好可以用来自动修正角度误差。2.2 方波注入 vs 正弦注入为什么我选方波我最早尝试的是高频正弦注入用信号发生器原理注入5kHz正弦波然后通过带通滤波器提取高频电流分量再用乘法器解调。这套方案理论上很漂亮但实际工程里滤波器带宽、相位延迟、数字化误差会把人搞到怀疑人生。换成方波注入之后清爽很多方波电压由PWM占空比直接产生不需要额外的DAC或者正弦表只需在每个PWM周期交替改变注入电压符号解调时不需要带通滤波器直接用相邻PWM周期的电流差值做差分运算把低频分量和基波分量去掉剩下高频响应信号带宽更高动态响应快对负载突变更从容代价是注入电压是阶跃变化的对电流采样点的噪声控制要求更高同时方波注入会产生高频电磁噪声和转矩脉动这个后面讲怎么压。2.3 注入电压和注入频率怎么定这是高频注入落地时最让人头疼的参数我给一个经验范围你按这个范围去试比自己瞎猜快得多。注入电压幅值一般取电机额定电压的5%~15%。电压太低高频电流响应太小解调信噪比不足电压太高高频电流过大转矩脉动和铁耗发热都会增加还可能逼着电流调节器饱和。以310V直流母线、额定电压220V的压缩机电机为例我常用12V到20V的注入幅值。注入频率方波注入的频率一般是开关频率的四分之一到二分之一。PWM开关频率10kHz时常见注入频率是2.5kHz到5kHz。选太低解调带宽不够选太高受到电流采样率和PWM分辨率限制。还要考虑一个点注入频率不能与电流环带宽、速度环带宽及其谐波重叠否则会形成闭环耦合引起振荡。我一般先把电流环设计好再选注入频率保证与电流环响应频率至少相差一个数量级。3. 基于高频方波的转子位置观测器设计3.1 位置误差信号的完整推导虽然我不喜欢堆公式但这个环节真的太关键我把核心推导写出来方便你理解代码里的每一行是怎么来的。设真实转子坐标系为dq估计坐标系为dq_est两者夹角为theta_err。在估计坐标系下考虑到d轴和q轴电感不同高频电流增量方程可以近似为delta_i_d v_h * dt * (L_avg - L_diff * cos(2*theta_err)) / (L_d * L_q) delta_i_q v_h * dt * L_diff * sin(2*theta_err) / (L_d * L_q)其中L_avg (L_d L_q)/2L_diff (L_d - L_q)/2。看第二个公式delta_i_q与sin(2*theta_err)成正比。当 theta_err 很小时sin(2*theta_err) ≈ 2*theta_err说明q轴高频电流增量直接反映了角度误差。这就是解调算法的数学基础。但由于 v_h 是方波正负交替delta_i_q 也会跟着正负交替。解调时只要乘上当前的注入符号就能把方波符号去掉得到只和误差相关的量theta_err_signal delta_i_q * sign(v_h)这段代码实现起来就三行但背后的数学要清楚否则PLL出来全是乱的。3.2 从误差信号到角度和速度锁相环怎么搭得到位置误差后不能直接拿这个误差值当角度因为它是带噪声的而且误差信号是2倍角度的正弦直接使用会抖动。标准做法是接一个锁相环让PLL去跟踪真实角度PLL输出就是平滑的估算角度和速度。PLL内部是一个PI调节器加一个积分器。误差信号经过PI后得到估算速度估算速度积分得到估算角度。当误差信号为零时PLL锁定估算角度等于真实角度。我用的PLL参数整定方法是先确定解调环路等效增益即误差信号的单位换算系数再根据期望的位置估计带宽一般是速度环带宽的5到10倍用带宽法计算PI参数实际调试中我习惯PLL响应稍微慢一点优先保证稳定性和抗噪性尤其是在带负载起动的场合。等起动稳定了再根据动态需求调整带宽。带宽调太快容易在重载下振荡调太慢动态响应跟不上堵转时角度会滞后。3.3 初始位置检测与磁极极性判断高频方波注入有一个天然的麻烦误差信号在theta_err0和theta_errpi时都可能是稳定平衡点也就是说PLL可能收敛到正确位置也可能收敛到反方向180度。开机什么都不知道的情况下必须先把初始位置找出来。我的做法分两步先发几个正反向电压脉冲对比电流响应峰值判断出磁极的N极还是S极也就是判断d轴正方向再用高频方波注入闭环让PLL收敛到某一边配合第一步的极性判断决定是否加180度偏置第一步有现成的实现方法在估计d轴正向注入一个窄电压脉冲记录电流峰值再在负向注入一个同样宽度的电压脉冲记录电流峰值。由于磁路饱和效应正方向电流峰值通常大于反方向峰值大的方向就是磁极方向即d轴正方向。这块逻辑在零速启动里非常重要很多零速起不来的案例都是初始位置错了180度一通电就往反方向转。提示初始位置检测的脉冲电压宽度不能太宽否则转轴会因为电磁转矩移动也不能太窄否则电流峰值不够分辨。具体宽度和幅值需要根据电机电感参数粗略估算后微调。4. 代码实现注入、解调、观测器一条龙4.1 整体软件框架与中断时序在开始代码之前先明确软件架构。以我常用的gd32f527为例PWM频率设在10kHz一个PWM周期对应一次AD采样和一次电流环计算。高频方波注入频率选5kHz也就是每两个PWM周期切换一次注入方向。软件上拆成几个模块PWM下溢中断电流采样、坐标变换、电流环PI、高频注入叠加、SVPWM更新高频注入模块管理注入方向和时序解调模块计算相邻周期电流差值得到位置误差PLL观测器模块从误差信号得到角度速度状态机模块负责零速检测、起动、低速/高速策略切换中断执行顺序很重要。注入电压的切换必须和电流采样点错开至少一个PWM周期否则当前的注入电压刚变化就采样采样值会混入开关瞬态导致解调出问题。我把注入符号切换放在PWM周期中间点而电流采样放在PWM下溢点中间隔了半个周期实测稳定多了。注意注入符号切换和电流采样必须错开至少半个PWM周期。我见过不少样板直接把切换放在采样时刻导致解调得到的误差信号里混入大量开关噪声波形惨不忍睹。4.2 高频方波注入与电流采样的对齐实现先定义注入状态结构体typedef struct { float v_inj; // 注入电压幅值(V) int8_t sign; // 当前注入符号 1 / -1 uint16_t half_period; // 半周期对应的PWM周期数(2) uint16_t pwm_count; // PWM周期计数 } hfi_inject_t;在PWM下溢中断里每次进入时计数器加一判断是否到达切换点void hfi_inject_update(hfi_inject_t *inj, uint16_t pwm_period_count) { inj-pwm_count; if (inj-pwm_count inj-half_period) { inj-pwm_count 0; inj-sign -inj-sign; // 翻转注入方向 } }在电流环输出之后、坐标反变换之前把注入电压叠加到d轴电压参考值上// 电流环输出 v_d_output pi_d_update(...); v_q_output pi_q_update(...); // 高频方波注入叠加只加在估算的d轴 v_d_inject v_d_output inj.v_inj * inj.sign; // 反Park变换 SVPWM ...这样每次注入符号切换时电压给到SVPWM并在下一个PWM周期生效。采样点放在PWM下溢也就是符号切换前的同一个周期内本质上采样的是上一个注入方向下的响应。这样处理的好处是不需要额外的相位补偿解调算法的各组电流差值都是同一种注入方向下的结果误差可控。4.3 位置误差解调与PLL代码解调模块的核心逻辑是相邻两个PWM周期做电流差分然后乘以当前注入符号。我在代码里保存上一拍的高频电流值直接做差typedef struct { float i_d_prev; // 上一拍高频采样d轴电流 float i_q_prev; // 上一拍高频采样q轴电流 float theta_err; // 解调得到的位置误差 float gain_demod; // 解调增益系数 } hfi_demod_t; void hfi_demod_process(hfi_demod_t *demod, float i_d_fb, float i_q_fb, int8_t inj_sign) { float delta_i_q i_q_fb - demod-i_q_prev; // 去掉方波符号影响得到角度误差信号 demod-theta_err delta_i_q * inj_sign * demod-gain_demod; // 保存当前值作为下一拍的“上一拍” demod-i_d_prev i_d_fb; demod-i_q_prev i_q_fb; }注意这里的gain_demod不是随便设的它需要把电流增量转换为弧度。实际计算时可以先用标定法得到角度误差和输出信号的比例。我通常是让PLL的输入单位本来就是任意比例然后在PLL里通过pi参数统一吸收但为了方便调试还是把gain_demod设为1后面用PLL带宽去解释。PLL观测器代码typedef struct { float theta_est; // 估算角度(rad) float speed_est; // 估算速度(rad/s) float i_error_integral; // 速度环积分项 float kp_pll; float ki_pll; float dt; // 控制周期(s) } hfi_pll_t; void hfi_pll_update(hfi_pll_t *pll, float theta_err) { // PI调节器误差 - 角速度 pll-speed_est pll-kp_pll * theta_err pll-i_error_integral; // 角速度积分 - 估算角度 pll-theta_est pll-speed_est * pll-dt; } void hfi_pll_integral_update(hfi_pll_t *pll, float theta_err) { pll-i_error_integral pll-ki_pll * theta_err * pll-dt; }在中断中调用顺序// 1. 采样电流、坐标变换得到 id_fb / iq_fb // 2. 高频解调 hfi_demod_process(hfi_demod, id_fb, iq_fb, inj.sign); // 3. PLL积分项更新 hfi_pll_integral_update(hfi_pll, hfi_demod.theta_err); // 4. PLL主更新 hfi_pll_update(hfi_pll, hfi_demod.theta_err); // 5. 电流环使用估算角度做Park变换和反Park ...把PLL积分项更新放在主更新之前等于用当前拍误差先修正速度再更新角度能减少一拍延迟实际对起动过程稳定有明显帮助。4.4 零速起步到中速段的策略切换高频注入跑到一定转速后要让位于反电动势法。我用的切换策略是“速度阈值 角度互锁”。状态机先定义两个算法都有估算角度和估算速度命名如下theta_hfi, speed_hfi高频注入观测器输出theta_smo, speed_smo滑模或反电动势观测器输出theta_use, speed_use最终用于坐标变换和速度环的输出在高速段speed_smo大于切换阈值后先用一个互锁逻辑确保两边角度差小于某个阈值比如30度然后把最终角度改为smo侧。为了防止突变我做了一个加权过渡// 过渡系数alpha0表示完全用HFI1表示完全用SMO float alpha 0.0f; if (speed_ref switch_high) { alpha alpha_step; // 按固定步长往上加 if (alpha 1.0f) alpha 1.0f; } else if (speed_ref switch_low) { alpha - alpha_step; if (alpha 0.0f) alpha 0.0f; } // 角度需要做边界处理避免-π/π跳变 float delta theta_smo - theta_hfi; if (delta PI) delta - TWO_PI; if (delta -PI) delta TWO_PI; theta_use theta_hfi alpha * delta; speed_use (1.0f - alpha) * speed_hfi alpha * speed_smo;这个过渡的思路是在切换区间内同时用两个观测器的信息让角度从HFI平滑过渡到SMO。切换点一般选在额定转速的10%附近切换阈值不能设太窄否则负载波动会让观测器来回切换电流和速度都会振荡。5. 调试实录常见问题与排查方法5.1 起动瞬间电流冲击大甚至过流保护这个现象我第一次调高频注入时也遇到过主要原因通常是初始位置检测不准或者注入幅值过大。排查步骤先把初始位置检测单独跑一遍打印出检测角度和实际电机静止位置看是否偏差特别大用示波器看电流波形如果起动瞬间高频电流峰值超过额定电流好几倍就先降低注入电压幅值如果电流冲击是方向性的很可能是180度反了检查磁极极性判断逻辑我遇到过的一个坑是初始位置检测时用带通滤波器处理信号滤波器相位延迟没补偿导致检测角度偏差20多度一通电电流直接冲顶。去掉滤波器、改用直接差分后问题消失。5.2 位置估算抖动大起动后电机来回震动位置抖动大最常见的原因是解调信号噪声大、PLL带宽过高或者PLL参数不合适。高频注入本身的信号就是脉冲化的如果PLL带宽比注入频率还高那些高频分量全都会进入速度输出震动是必然的。我建议把PLL带宽控制在20Hz到80Hz之间具体取决于系统惯量和负载。压缩机这种大惯量负载带宽取低一些动态要求高的伺服负载取高一些。另外检查一下注入频率和电流环带宽有没有重叠重叠了就把注入频率或电流环带宽错开。还有一个容易忽视的点死区时间。死区会造成电压误差影响高频电流的解调。如果注入电压幅值比较小死区的影响占比就高抖动会明显。可以加逆变器死区补偿或者适当提高注入幅值。5.3 高频注入噪声如何压高频方波注入的代价之一就是电磁噪声电流里会有明显的高频分量电机也会发出尖叫声。噪声来源有几个方面注入频率刚好落在人耳敏感区间选注入频率时尽量避开2kHz到4kHz或者你本身不介意噪声否则留意一下注入电压偏大不需要那么大的信号响应适当减小解调后的谐波分量可以加一个低通滤波器把PLL输入信号稍微滤一下但不能滤太狠滤多了会引入相位延迟我刚做第一版时用的是3.5kHz注入泵体噪声明显调到5kHz后好了一些同时在电流采样上加了一个一阶低通滤波相位在注入频率下延迟不到20度效果可以接受。5.4 参数整定速查表把我在实际项目中用过的参数范围和调整逻辑整理成表方便你直接抄参数参考范围影响调试建议注入电压幅值额定电压的5%~15%信号强度、噪声、发热从下限开始往上加直到起动稳定注入频率开关频率的1/4~1/2解调带宽、听觉噪声避开人耳敏感区间与电流环带宽错开解调方式相邻周期差分延时、噪声无滤波器优先必要时加一阶低通PLL带宽10Hz~80Hz动态响应、抗噪性从低往高调以系统不过冲为准切换阈值额定转速的5%~15%切换平稳性先小范围测再逐步扩大这份表是我花了大量时间反复试出来的每个参数都有牵一发动全身的效果建议一次只改一个参数改完看波形再做下一步调整。最后说点操作层面的体会。高频方波注入这套东西原理书上都写得清楚真正难的是把零速定位稳、把初始位置判对、把切换调顺。我一开始自信满满以为代码对着论文抄一遍就能跑结果在零速起动这里折腾了快两周最后发现问题全出在细节上采样点对没对齐、初始N/S判反了、PLL参数太激进。后来我把整个流程拆成注入、解调、PLL、切换四个独立模块每个模块单独打印数据和波形问题才一个个浮出来。调试无感FOC最快的路径永远是先把模块拆干净每个模块都可视、可测、可独立调然后再合起来跑系统。希望这篇文章能帮你少走我走过的弯路也欢迎在实际项目里踩到新坑后回来一起交流。
返回列表