首页 / 资讯中心 / 文章详情

永磁同步电机无感FOC零速启动:高频方波注入原理与STM32F405实现

永磁同步电机无感FOC零速启动:高频方波注入原理与STM32F405实现 ★ FEATURED ARTICLE
做电机控制的调试多了我慢慢有个体会速度环和电流环谁都会调真正考验功力的是零速启动那一刻能不能稳准狠。低速段做无感FOC用反电动势观测器基本是白搭得靠HFI高频方波注入这类不依赖转速的主动激励方法。最近整理手头累积的调试资料发现基于STM32F405的这套永磁同步电机无感FOC方案非常典型也踩了不少坑这里把原理、实现和调试经验完整写一遍给准备做无感电机驱动的朋友做个参考。这篇文章不会讲太多理论推导重点放在工程落地为什么要选高频方波注入、F405上怎么安排信号链、代码从哪下刀、PLL参数怎么调以及那些让你浪费一整个晚上的诡异问题。不管你是刚接触无感FOC还是已经在用滑模观测器但苦于低速启动困难这篇都值得看。1. 无感FOC低速困境与高频注入的思路1.1 反电动势法在低速为什么失灵绝大多数无感FOC方案在中高速段用的是反电动势类观测器比如滑模观测器SMO、龙伯格观测器或者磁链观测器。它们的共同基础是转子旋转时定子绕组上会感应出反电动势其幅值近似正比于电角速度E ≈ Ke·ω。转速高了信号强观测器随便一估就能把转子磁链方向估得八九不离十。问题在于低速。转速降到额定转速的5%以下时反电动势幅值可能只有零点几伏这时候整个驱动系统的干扰源——逆变器死区压降、开关纹波、电流采样噪声、母线电压波动——随便哪个都比反电动势信号大。信噪比一塌糊涂观测器输出的角度要么来回抖要么彻底发散。这个困境是物理原理决定的反电动势法就是依赖转速转速低到一定程度它的信息源就没了。所以无感控制的难点从来不在高速而在零速和极低速那一段。工程上常用的解决办法是加霍尔传感器或者编码器但很多场景压缩机、风机、部分电动工具装不了传感器要么空间不够要么成本敏感要么环境温度太高。这时候HFI高频注入就派上用场了。1.2 高频注入如何利用电机的“隐藏刻度”高频注入的思路和方法电动势观测器完全不同。它不是被动等转子转起来再读信号而是主动向电机定子注入一个高频电压激励然后从电流响应里读出转子位置。这里的物理基础是电机本身的凸极性。对于内置式永磁同步电机IPMSM转子磁路不对称导致d轴电感和q轴电感差异明显通常Ld小于Lq。这就相当于电机里藏了一个和转子同步旋转的“刻度盘”你在某个方向上施加高频电压电流响应的大小和方向都会受这个刻度盘调制位置信息就藏在里面。因为高频注入不依赖转速电机哪怕完全静止只要施加激励就能读取位置所以它能覆盖零速和极低速段。表贴式永磁电机SPMSM也适用只是原理稍有差别。理想情况下SPMSM的Ld约等于Lq凸极性几乎为零但是当电流增大到一定程度磁路饱和会让d轴和q轴电感出现差异这叫“饱和凸极性”。我在实际测试里确实能用HFI让一台表贴电机从零速带载启动但位置误差信号比内嵌式电机弱很多对采样精度要求更高调试难度也上一个台阶。1.3 方波注入对比正弦注入的取舍高频注入并不是新概念早期产品里多的是正弦注入方案。正弦注入是在估计d轴上叠加一个正弦电压注入频率一般取PWM开关频率的十分之一左右比如10kHz载波对应1kHz注入频率。它的缺点是正弦信号需要用带通滤波器从电流反馈里提取滤波器相位延迟会吃掉一部分控制带宽位置环动态响应偏慢而且滤波器参数还要跟着电机参数走调起来很费劲。方波注入的思路激进得多。它用正负交替的方波电压代替正弦信号注入频率可以直接做到开关频率的一半。以10kHz PWM为例方波注入频率就是5kHz比传统正弦注入高了好几倍。注入半周期只有一个PWM周期电流响应不需要额外滤波直接靠相邻周期的采样差值就能把高频信号提取出来。PLL带宽可以拉得更高动态性能明显更好。代价也有注入电压在相邻PWM周期之间突变电流采样时刻和ADC触发同步精度必须到位否则解调出来全是噪声。对比项正弦注入方波注入注入频率载波的约1/10载波的1/2电流提取需要带通滤波器相邻周期差分位置环带宽受限可拉高采样同步要求一般严格实现复杂度中等中等偏低我在实际项目中选了方波注入理由很简单F405主频够、ADC触发能做精确同步方波方案的实时性和代码复杂度都更适合做产品。2. 核心细节解析F405硬件资源与高频信号链路2.1 硬件系统与PWM/ADC采样搭配STM32F405主频168MHz带单精度FPU跑一套完整的FOC加HFI算法10kHz中断里做完所有运算还绰绰有余。硬件上我习惯用基本的MOSFET三相全桥加上母线电压采样和两相下桥臂电流采样。编码器不需要但调试阶段我强烈建议留一个编码器接口做位置对照否则出了问题你不知道是算法错还是硬件错。PWM定时器用TIM1高级定时器配置成中央对齐模式输出6路互补PWM开关频率10kHz到20kHz都行。中央对齐模式有一个非常重要的工程优势PWM计数溢出点正好处于占空比的“中间时刻”这时候三相桥臂的开关纹波分量最小ADC在这个点采样电流得到的值最干净。ADC这边我用ADC1和ADC2分别采样A相和B相电流通过TIM1的TRGO事件触发同步采样。这里有个关键点方波注入信号在一个PWM周期内是恒定的下一个PWM周期符号翻转所以ADC必须做到每个PWM周期都采样一次都不能漏。触发方式必须用硬件触发不能靠中断里软件打点否则时序抖动会把解调信号污染得一塌糊涂。提示调试时如果发现位置估计有周期性抖动先别怀疑算法先检查ADC触发是否和PWM严格同步。软件触发的随机延迟在高速注入下就是致命的。2.2 高频电流响应如何变成位置误差信号方波注入的实现方式是在估计d轴电压指令上叠加一个正负交替的方波电压。假设估计坐标系和真实转子坐标系之间存在一个位置误差θerr这个误差会在估计q轴上感应出一个高频电流分量。忽略电阻压降和死区影响的近似表达式可以写成err ≈ Vi·ΔT·(LdLq差项)·sin(2θerr)当θerr很小的时候sin(2θerr)约等于2θerr也就是说估计q轴的高频电流分量近似正比于位置误差。这是个天然的误差信号只需要把它送进PLL让PLL调整估计角度朝着误差减小的方向收敛位置估计就闭环了。这里最容易犯的错误是符号问题。因为注入电压是正负交替的q轴高频电流分量也会跟着翻转。如果直接把这个电流送进PLLPLL看到的误差信号在正负半周期符号相反角度会一直来回震荡。解决办法是在解调时乘上注入电压的符号sign(Vinj)把电压方向的影响抵掉这样PLL输入端得到的就是一个和θerr同号的稳定误差。2.3 从误差信号到转子角度PLL观测链路整条位置估计链路可以拆成三段。第一段是信号获取每个PWM周期中点采样相电流做Clarke变换得到alpha-beta静止坐标系电流。这里的电流包含了基波分量、开关纹波和高频注入分量需要下一步把高频响应单独拎出来。第二段是差分提取。因为注入方向是每隔一个PWM周期翻转的所以相邻两个PWM周期的采样值做差基波分量基本会被抵消剩下的主要是注入电压引起的电流增量。把这个增量变换到估计dq坐标系取q轴分量再乘上注入方向符号就得到了位置误差信号。这个过程相当于做了一个同步解调不需要额外的带通滤波器非常简洁。第三段是环路跟踪。误差信号进入一个PI调节器PI输出是估计电角速度对电角速度积分就得到估计电角度。整个循环在每个PWM中断里都执行一遍更新频率就是PWM频率。PLL本身就对误差信号有低通作用所以只要PLL带宽设计合理一般不需要在输入端再额外加滤波器加了反而会引入相位延迟。// PWM中断服务函数10kHz void TIM1_UP_IRQHandler(void) { // 1. 读取ADC采样电流 float ia adc_get(ADC_CH_A); float ib adc_get(ADC_CH_B); // 2. Clarke变换 float i_alpha ia; float i_beta (i_alpha 2.0f * ib) * 0.57735f; // 3. 与上一周期采样值差分抵消基波 static float old_i_alpha, old_i_beta; float di_alpha i_alpha - old_i_alpha; float di_beta i_beta - old_i_beta; old_i_alpha i_alpha; old_i_beta i_beta; // 4. 变换到估计dq系取q轴分量 float cos_t cosf(theta_est); float sin_t sinf(theta_est); float di_q -sin_t * di_alpha cos_t * di_beta; // 5. 注入方向符号补偿 float err_raw sign_inj * di_q; // 6. PLL更新 pll_update(err_raw); }3. 实操过程与代码实现零低速启动到高速切换3.1 第一步预定位与开环强拖无感FOC的启动流程我习惯分成三个阶段预定位、开环强拖、HFI闭环切换。预定位的逻辑很简单给电机施加一个固定方向的定子电压矢量持续一段时间让转子转到和这个电压矢量对齐的位置。这样你就知道了转子的初始角度。电压幅值既不能太小否则克服不了静摩擦和负载转矩转子转不过去也不能太大可能产生过电流。我一般从额定电流对应电压的20%到30%起步观察母线电流和实际角度的变化再微调。持续时间通常100到300毫秒具体看机械时间常数。负载越重稳定时间越长。预定位完成后进入开环强拖。强拖阶段的速度指令按斜坡上升角度由软件直接给定同时电流环正常工作用来限制电流。这里要特别注意给定角度的变化率必须平缓。转子是靠定子磁场拖着走的如果给定角度变化太快转子会跟不上角度差超过90度后电磁转矩不再增加反而会导致失步甚至反转。开环阶段电流环PI参数如果太激进还会把HFI注入信号当成扰动去抵消所以这个阶段注入可以先关掉等PLL在线锁定后再开启。3.2 HFI解调与PLL的核心C代码HFI的核心代码结构可以分成三个部分注入信号生成、电流差分解调、PLL更新。注入信号生成非常简单每个PWM周期翻转一次sign_inj变量然后在电流环PI输出上叠加float sign_inj; float ud_pi, uq_pi; // 电流环PI输出 float ud_ref, uq_ref; // 最终电压参考值 void inject_hfi(void) { // 每个PWM周期翻转一次注入方向 sign_inj -sign_inj; // 在估计d轴叠加方波电压 ud_ref ud_pi VOLT_INJ * sign_inj; uq_ref uq_pi; }注意注入分量加在哪个位置。电流环PI的输出是电压指令我们在这个电压指令上直接叠加注入电压。为什么不会破坏电流环因为PI的带宽远低于注入频率电流环PI对高频注入分量几乎没反应它只会去调节基波电流。但如果PI参数整定得太激进积分项可能会吸纳一部分注入分量导致实际加到电机上的注入电压幅值衰减PLL锁不住这一点在并联压缩机这种大负载场景尤其明显。PLL更新的代码也不复杂但有几个细节要处理好。PLL输入是误差信号输出是速度估计再积分得到角度typedef struct { float kp; float ki; float integral; float speed; float theta; } pll_t; void pll_update(pll_t *pll, float err, float dt) { pll-integral err * dt; pll-speed pll-kp * err pll-ki * pll-integral; pll-theta pll-speed * dt; // 角度归一化到 [0, 2π) pll-theta fmodf(pll-theta, 2.0f * 3.1415926f); }PLL计算得到的theta就是估计转子位置给Park变换和逆Park变换用。速度则送给速度环作为反馈。如果速度环需要阶跃响应快PLL带宽要稍微拉高如果只需要转速闭环稳定带宽可以低一些。总的原则是让PLL响应速度远快于速度环但又远低于注入频率我一般取PLL带宽为注入频率的十分之一附近。3.3 PLL参数整定思路PLL参数的整定我很少一上来就算而是按一套固定的流程去试。第一步Kp取一个很小的值Ki置零观察误差信号和估计角度能不能朝正确的方向收敛。如果极性反了角度会越跑越偏直至发散这时候先检查符号问题而不是调参数。第二步逐步增大Kp直到角度在启转过程中能跟得上真实位置不会出现明显的滞后或者抖动。第三步加Ki消除稳态误差。Ki太大会让估计速度产生振荡启动时表现为电流抖动转速爬升不平滑。还有一个重要技巧把PLL的输入误差信号和最终估计的角度用DAC或者串口示波器拉出来看。F405自带DAC可以把误差信号直接输出到示波器通道同时用编码器对照真实角度误差。这个手段能省掉大量猜测时间。我每次调试新电机都是先看误差信号的波形质量波形干净了再谈参数。3.4 与中高速观测器的切换方法HFI只在低速段有优势中高速段还是得靠反电动势观测器比如滑模观测器或者磁链观测器。一个完整的无感FOC方案低速用HFI中高速用SMO中间加一段过渡区。切换转速的选取依据是反电动势信号质量一般取额定转速的10%到20%。转速太低反电动势信噪比不足以支持SMO正常工作过早切换会直接失控转速太高HFI的注入损耗白白浪费而且注入信号还可能干扰SMO的电流反馈。切换要实现三个平滑角度平滑、速度平滑、切换迟滞。角度平滑是重点HFI观测量和SMO观测量在切换瞬间不能有跳变做法是让两个观测器在过渡区内同时运行估计角度做加权输出。速度平滑处理一个缓冲防止速度环在切换瞬间看到突变。切换迟滞是为了避免在两个工作区边界来回振荡比如从HFI切换到SMO是在转速1100rpm触发的那从SMO切回HFI要等转速降到900rpm以下才允许中间的差值就是迟滞带。float speed_hfi, speed_smo; float ratio, speed_final; // 过渡区 1000~1200rpm越接近高速段SMO权重越大 if (speed_ref 1000.0f) { ratio 1.0f; } else if (speed_ref 1200.0f) { ratio 0.0f; } else { ratio (1200.0f - speed_ref) / 200.0f; } speed_final ratio * speed_hfi (1.0f - ratio) * speed_smo;4. 常见问题与排查技巧实录4.1 注入电压幅值怎么标定注入电压幅值是最先要定下来的参数也是最容易拍脑袋定错的。幅值太小位置误差信号淹没在采样噪声和死区谐波里PLL锁不住幅值太大电机发出明显的高频啸叫铁耗增加母线电流纹波变大甚至引起电流环饱和。我的标定流程是先从一个中等数值开始比如额定电压的5%到8%然后用示波器看解调后的误差信号波形。目标是让误差信号峰峰值是噪声底数的5到10倍同时让电机噪声在可接受范围内。对于供电电压24V、相电感几百微亨级别的电机电压标幺值在0.1左右是比较常见的范围。前提是采样电流噪声别太离谱如果硬件上电流信号毛刺很大优先解决采样电路而不是一味加大注入电压。4.2 位置估计偏移的常见诱因位置估计出现恒定角度偏移是最难排查的问题之一因为现象经常表现为“能转但性能差”比如负载能力下降、电流偏大、转矩抖动。排查顺序我习惯按下面这张表来现象可能原因检查方法固定角度偏移采样点偏离PWM中心ADC触发改用TIM1硬件触发启动方向错乱解调符号反了反转sign_inj观察收敛方向低速抖动低通滤波相位延迟取消多余滤波直接PLL负载增大后偏移变大死区效应未补偿加入死区补偿或加大注入幅值换电机后失败电感参数差异大做归一化HFI或重新标定我印象最深的一次是电机空载转动完全正常一加载就从几百转开始抖。后来发现是电流采样电阻两端的共模噪声被ADC采进去了和注入信号发生了拍频导致位置误差信号周期性波动。换成差分采样后问题消失。4.3 启动和切换瞬间的电流冲击无感FOC最容易炸MOSFET的时刻就是启动瞬间和切换瞬间比稳态运行危险得多。预定位结束瞬间电流会有一个反冲。解决办法是预定位结束后电流环给定做斜坡恢复不要瞬间跳零。开环强拖阶段电流环给定跟随速度斜坡生长但生长率必须受到限制否则转子没跟上磁场电流会顶到限幅值。HFI闭环切换瞬间如果PLL估计角度和开环给定角度之间还有残余误差切换时力矩会突变表现为电流尖峰。稳妥的流程是在开环阶段就让PLL在线运行先跟踪开环给定角度等误差收敛到很小范围内再切换角度来源整个过程用斜坡过渡。高速段切换到SMO也是一样的逻辑用前文提到的加权过渡可以让电流冲击大幅减少。我曾经试过不做过渡直接切换电流瞬间从额定值跳到2.5倍直接触发硬件过流保护。加了200ms的过渡后全程电流平稳。4.4 量产化参数敏感性与归一化HFI如果只是做样机PLL增益固定也能勉强工作。但要做成批量产品就会发现HFI还有个头疼的问题不同批次的电机、不同温度下Ld和Lq会变化位置误差信号的增益随之变化。同样的PLL参数在一台电机上锁得很稳换一台电机可能锁不住。解决思路是对误差信号做归一化处理。位置误差信号的幅值除了和θerr有关还正比于注入电压幅值、差分时间、以及电感的差异程度。如果把误差信号除以估计d轴的高频电流增量幅值就把这些不确定因素基本抵消掉了剩下的是一个和θerr近似线性、增益几乎恒定的量。这个技巧就是“归一化HFI”在量产项目中非常实用强烈建议实现。实现时有个细节估计d轴的高频电流增量幅值可能很小直接做除法会有噪声放大风险需要先对这个幅值信号做低速滤波同时设一个下限保护避免除零和极端放大。最后再分享一个调试心得。HFI这套方案里问题多半藏在时序和符号里而不是理论公式里。动手写代码之前先把PWM触发ADC的时序图画一遍把每个PWM周期里采样点在哪、注入方向何时翻转、差分用哪两次采样值都标清楚。这张图画完了整个系统就通了一半。剩下的调试时间基本都花在扫清采样噪声和调参数上了。
阅读完成 · 觉得有帮助?
咨询建站