做无感FOC,核心永远绕不开一个问题:转子位置到底怎么拿。STM32G431FOC线性磁链观测器这套方案,就是把这个“怎么拿”的问题用全C语言、在单片机上落地的一套完整控制思路。它不提高频注入,也不玩滑模抖振,而是用一个线性磁链观测器把电角度“追”出来,同时把零速闭环启动和电角度快速收敛结合到一起。这篇文章适合正在搞电机控制的工程师、刚接触无感FOC的学生,以及想降低BOM成本、去掉编码器的产品开发者。我会把方案为什么这么选、观测器的数学怎么落地、零速启动和角度收敛的工程实现、以及我在实际调试里踩过的坑,一起拆开讲清楚。
1. 整体方案:为什么选STM32G431和线性磁链观测器
1.1 STM32G431这颗芯片到底强在哪
先聊硬件。STM32G431是一颗带着硬件除法器和FPU的Cortex-M4内核单片机,主频做到170MHz,在电机控制这个细分领域里,它几乎是“价廉物美”的典型代表。芯片内部集成了多路12位ADC、比较器、运算放大器,高级定时器还专门为电机控制做了互补PWM输出和电流采样触发同步,这意味着你用单电阻或者双电阻电流采样时,不需要在外部再堆一堆运放和比较器,直接把三相电流调理电路接到内部运放即可。
更重要的是,170MHz主频配合FPU,跑一套完整的FOC加观测器,通常开销只在十几微秒到几十微秒之间。我实际测试过,20kHz的控制频率下,做完电流环、速度环、坐标变换、SVPWM、观测器更新,CPU占用率仍然有大量余量。这颗器件选型的时候,我唯一提醒的就是注意不同封装和型号差异,引脚数少的封装可能在ADC通道分配上捉襟见肘,布板前先对着封装把资源规划好。
另外G431的定时器支持中心对齐PWM,输出在PWM周期的中点产生更新事件,这个特性可以做“中心采样”,即电流采样点正好放在PWM载波峰顶或谷底,电机相电流纹波在这个时刻最小,采样到的电流值最接近一个PWM周期内的平均值。这个细节对无感FOC尤其重要,因为观测器对电流噪声极其敏感,采样一抖,角度就开始晃。
1.2 控制架构和功能划分
这套方案的控制架构是经典的速度外环、电流内环双闭环结构。速度环输出q轴电流参考,d轴电流参考一般给0,或者在某些弱磁工况下给负值。采样得到三相电流后,经过Clarke变换到αβ坐标系,再经过Park变换到dq坐标系,交给两个PI控制器调节,输出的dq电压经过反Park变换得到αβ电压,最后进SVPWM生成占空比。
观测器和角度估计单独作为一个模块,不参与电流环内部的高频运算逻辑,但在每一次控制中断里都必须和电流环同步更新。观测器输入的是αβ轴电压电流,输出的是电角度和电角速度。速度环用的速度来自观测器的角速度估计,电流环用的角度来自观测器的电角度估计。整条链路的实时性要求是:一次中断周期内,采样、变换、电流环、观测器、调制必须全部跑完,任何一个部分超出执行时间,都会导致PWM更新不及时,出现波形畸变。
我习惯把中断周期定为50微秒,也就是20kHz。这个频率对多数中小功率PMSM足够,电流环带宽可以做到800Hz到1kHz左右,系统动态响应已经很理想。再提高频率当然可以,但对这部分数字运算能力和ADC采样稳定性都是考验。
1.3 为什么选线性磁链观测器而不是滑模或扩展卡尔曼
无感FOC领域里观测器方案五花八门,常见的有反电动势过零检测、滑模观测器、扩展卡尔曼滤波、模型参考自适应、龙贝格观测器,以及这里要说的线性磁链观测器。它们各有用途,但在某些场景下选择线性磁链观测器比其它方案更合理。
滑模观测器鲁棒性很强,对参数误差不太敏感,但换来的是系统存在高频抖振。抖振会通过电流环表现为明显的转矩纹波,你必须加低通滤波器来平滑,但这又引入了相位延迟。延迟在低速下特别致命。扩展卡尔曼滤波效果好,但矩阵运算复杂,Y矩阵、增益矩阵、协方差矩阵全套算下来,在G431上虽然能跑,但整个工程的可读性和调参复杂度都上去了,而且它对初始值很敏感,调不好就发散。
线性磁链观测器本质上是一个基于电压模型的二阶积分观测器,配上电流模型的反馈校正。它的好处是模型线性、结构清晰、没有符号切换,CPU开销很低,适合全C手写,便于按实际芯片资源和电机参数去裁剪。低速下反电动势本来就弱,纯反电动势算法肯定不行,线性磁链观测器因为引入了电流模型和反馈项,比单纯反电动势积分的稳定性好很多,同时又不那么依赖高频注入那样复杂的信号处理。
当然,任何观测器在真正的零速静止状态下都无法只靠反电动势获得转子初始角度,所以方案里专门设计了零速闭环启动的预定位和状态机。这才是整个方案的完整闭环,也是标题里“零速闭环启动”和“电角度快速收敛”的工程含义。
2. 线性磁链观测器的数学原理与离散化实现
2.1 从电压模型出发:磁链怎么被“观测”出来
先回到最基本的永磁同步电机电压方程。在αβ静止坐标系下,定子电压方程是:
uα = Rs·iα + dψα/dt uβ = Rs·iβ + dψβ/dt
其中ψα、ψβ是定子磁链在αβ轴上的分量,Rs是定子电阻。只要把电压减去电阻压降,再对时间积分,就能得到定子磁链:
ψα = ∫(uα - Rs·iα) dt ψβ = ∫(uβ - Rs·iβ) dt
定子磁链由两部分组成,一部分是电感产生的磁链,另一部分是永磁体转子磁链:
ψα = Ls·iα + ψpmα ψβ = Ls·iβ + ψpmβ
于是永磁体转子磁链分量可以写成:
ψpmα = ψα - Ls·iα ψpmβ = ψβ - Ls·iβ
转子电角度就是永磁体磁链矢量在αβ坐标系下的角度:
θe = atan2(ψpmβ, ψpmα)
从式子看,整个计算链条非常清晰:先获取αβ轴电压电流,减去电阻压降,积分得到定子磁链,再减去电感磁链,得到永磁体磁链,最后通过反正切求角度。
这套公式在高速工况下工作得很好,但在低速时问题非常大。第一,反电动势uα - Rs·iα的幅值正比于转速,转速越低信号越弱,很容易被电流采样噪声和ADC量化误差淹没。第二,纯积分器存在直流偏移积分饱和问题,只要电压采样或电阻压降有一点直流偏置,积分结果就会缓慢飘走,磁链圆变成一个慢慢偏心的圆,角度也会跟着漂。第三,积分初始值如果给错,角度起始就有偏差。
所以实际工程里不能直接用纯积分器,必须给观测器加入反馈校正回路。这就引出了带反馈的线性磁链观测器。
2.2 加入电流模型反馈:带校正的观测器结构
纯电压模型的问题在于“开环积分”,没有任何约束。为了把积分结果拉回到真实物理范围内,可以构造一个电流模型来提供参考磁链,再通过反馈项把电压模型的积分结果“拉”向参考值。
电流模型的表达式是:
ψimα = Ls·iα + ψpm·cos(θ̂e) ψimβ = Ls·iβ + ψpm·sin(θ̂e)
这里的θ̂e是上一拍观测器估计出的角度,ψpm是永磁体磁链幅值。电流模型相当于根据当前电流和估计角度给出一个“期望磁链”,它不会像积分器那样漂移,但依赖角度和磁链参数的准确性。
把两个模型结合起来,得到带校正项的观测器递推方程:
dψ̂α/dt = uα - Rs·iα + Kobs·(ψimα - ψ̂α) dψ̂β/dt = uβ - Rs·iβ + Kobs·(ψimβ - ψ̂β)
其中Kobs是反馈增益,单位是rad/s,相当于一个一阶低通截止频率。从控制结构看,前面是电压模型在负责高频段积分,后面是电流模型在负责低频段校正,两者交叉,观测器在宽速度范围内都能保持稳定。
这个结构的好处是:当转速较高、反电动势信号较强时,电压模型主导,积分结果准确;当转速较低、反电动势信号弱时,反馈校正项把磁链拉向电流模型给出的参考值,避免积分漂移。参数Kobs选得越大,观测器越“信任”电流模型,动态响应越快,但容易引入角度噪声;选得越小,越“信任”电压模型,低速稳定性差一些。实际调试时需要根据电机参数和最低工作转速做折中。
2.3 离散化处理与标幺化选择
嵌入式实现时,连续域的微分方程必须离散化。我比较推荐一阶后向欧拉法,公式直观且在高频采样下稳定。离散后的递推式是:
ψα[k] = ψα[k-1] + Ts·(uα[k] - Rs·iα[k] + Kobs·(ψimα[k-1] - ψα[k-1])) ψβ[k] = ψβ[k-1] + Ts·(uβ[k] - Rs·iβ[k] + Kobs·(ψimβ[k-1] - ψβ[k-1]))
注意反馈项里用的是上一拍的磁链差,这样可以避免在同一个中断内形成代数环,代码实现也更简单。
数值处理上,我强烈建议做标幺化。原因很简单:直接用国际单位时,磁链量级可能是0.001到0.1韦伯,电流可能从零点几安到几十安,电阻是欧姆级,所有量混在一个表达式里,数值尺度差异极大,调试的时候看变量曲线很不直观,也容易在小数运算中出现精度问题。标幺化则把所有物理量折算到额定值的百分比,比如磁链基准取额定磁链,电流基准取额定电流,电压基准取额定相电压,这样在线运算的数值基本都在0到2之间,观察曲线、断点调试都方便得多。
离散化之后再加一个角度提取模块。我用的方法不是直接对磁链求反正切,而是先做角度修正和连续性处理。因为atan2的输出范围是-π到π,如果直接在角度域做速度估计,跨越±π边界时会突然跳变360度,速度估计会出尖峰。正确做法是把角度差值先处理到-π到π范围内再求差分,或者用锁相环结构估计角度和速度,后者更平滑。
2.4 全C语言实现的核心代码框架
全C语言实现这套观测器,主要就是定义好状态结构体和配置结构体,在中断里调用更新函数。下面这段代码是我整理的观测器核心框架,不含具体硬件驱动,重点看结构:
typedef struct { float Rs; // 定子电阻 [Ω] float Ls; // 定子电感 [H] float FluxPm; // 永磁体磁链幅值 [Wb] float Kobs; // 观测器反馈增益 [rad/s] float WcFluxLow; // 低通校正系数,用于限制积分漂移 } FOC_Obs_Cfg; typedef struct { float iAlpha; // α轴电流 float iBeta; // β轴电流 float uAlpha; // α轴电压 float uBeta; // β轴电压 float psiAlpha; // 定子磁链α分量 float psiBeta; // 定子磁链β分量 float thetaElec; // 电角度 [rad] float speedElec; // 电角速度 [rad/s] float psiPmAlpha; // 永磁体磁链α分量 float psiPmBeta; // 永磁体磁链β分量 } FOC_Obs_State; void FOC_Obs_Init(FOC_Obs_State *s, FOC_Obs_Cfg *c) { s->psiAlpha = 0.0f; s->psiBeta = 0.0f; s->thetaElec = 0.0f; s->speedElec = 0.0f; (void)c; } void FOC_Obs_Update(FOC_Obs_State *s, FOC_Obs_Cfg *c, float Ts) { float psiImAlpha, psiImBeta, errAlpha, errBeta; float sinTheta, cosTheta; // 1. 根据上一拍角度构造电流模型参考磁链 sinTheta = arm_sin_f32(s->thetaElec); cosTheta = arm_cos_f32(s->thetaElec); psiImAlpha = c->Ls * s->iAlpha + c->FluxPm * cosTheta; psiImBeta = c->Ls * s->iBeta + c->FluxPm * sinTheta; // 2. 后向欧拉更新定子磁链 errAlpha = psiImAlpha - s->psiAlpha; errBeta = psiImBeta - s->psiBeta; s->psiAlpha += Ts * (s->uAlpha - c->Rs * s->iAlpha + c->Kobs * errAlpha); s->psiBeta += Ts * (s->uBeta - c->Rs * s->iBeta + c->Kobs * errBeta); // 3. 提取永磁体磁链分量 s->psiPmAlpha = s->psiAlpha - c->Ls * s->iAlpha; s->psiPmBeta = s->psiBeta - c->Ls * s->iBeta; // 4. 角度估计 s->thetaElec = atan2f(s->psiPmBeta, s->psiPmAlpha); // 5. 角度连续性处理:把角度差限制在±π内 // 这里最好用锁相环结构,输出角度和速度,避免角度跳变 }这个框架已经能跑,但实际工程里我还会加入防积分饱和和抗漂移逻辑,比如给磁链积分加限幅,在长时间极低速运行且没有收敛时根据电流模型强制校正等。代码看起来简单,但背后的参数标定和边界处理才是真正工作量所在。
3. 零速闭环启动与电角度快速收敛的工程实现
3.1 零速到底难在哪
很多人一开始不理解,为什么“零速闭环启动”听起来是矛盾的事。无感FOC没有编码器,观测器从哪儿获得转子位置?零速时反电动势为零,电压模型根本提取不到位置信息,如果直接上电就满电压输出,转子完全不知道朝哪转,轻则抖一下,重则堵转发热。
所以真正的工程处理是把“零速”分成两个阶段:第一阶段是在静止状态下通过预定位把转子拉到一个已知角度,第二阶段是让观测器从已知角度出发,在电流闭环中维持转子状态,并快速建立磁链观测收敛。也就是说,零速闭环启动的本质是“先把初始条件整出来,再让观测器接棒”。
3.2 初始位置对齐与观测器状态注入
初始对齐的通俗说法是“把一个电压矢量朝某个方向压过去”,让转子转到一个和矢量方向一致的位置。实际操作时,给定一个固定的d轴电流参考,比如Id_ref等于额定电流的20%,Iq_ref等于0,同时把dq坐标系的角度固定在一个已知电角度,比如零度。此时定子电流产生的磁场会把转子“吸”到与给定磁场方向一致的位置。
这个过程不能太短,否则转子还没稳定下来就开始后续控制,角度就会有偏差。我一般给30毫秒到100毫秒,具体视负载惯量和摩擦力而定。对齐期间电流环是闭环的,所以电流会稳定在给定值,转子会缓慢转动并最终停住。判断对齐完成的标志是:d轴电流实际值稳定接近参考值,且指令角度与实际电流相位差基本固定。
对齐之后的步骤很关键,也是很多人遗漏的:把观测器初始磁链状态直接“预置”成对齐位置对应的磁链值。如果对完齐得到电角度θ0,那么永磁体磁链的初始分量可以直接写成:
ψpmα0 = ψpm·cos(θ0) ψpmβ0 = ψpm·sin(θ0)
然后把定子磁链初始值设为:
ψα0 = Ls·iα0 + ψpmα0 ψβ0 = Ls·iβ0 + ψpmβ0
这样做的直接好处是:一进入观测器闭环,磁链矢量的幅值和方向已经对准真实转子磁链,而不是从零开始慢慢积分建立。这就实现了标题里说的“电角度快速收敛”,不需要等待观测器从初始混沌状态里把角度追出来,启动的一瞬间角度就是对的。
很多初学者只做了预定位,却忘了把观测器状态同步初值,导致预定位虽然把转子拉正了,但观测器内部磁链仍从零开始积分,启动瞬间角度会先跳到一个错误的中间值,然后才慢慢收敛。这个细节直接决定了零速启动会不会“砰”地一下抖出去。
3.3 I/f强拖与闭环切换:收敛的衔接机制
预定位结束后,如果目标速度是0,就让系统在闭环状态待命。如果目标速度大于0,那么下一步就涉及到加速启动。低速段反电动势依然很弱,观测器反馈校正压力大,直接全闭环可能不稳定,所以工程上常用一种I/f强拖方式衔接。
所谓I/f强拖,就是给定一个幅值稳定的电流矢量,以固定的加速度或速度斜坡旋转,电流矢量“拖”着转子往前走。此时电流环仍然闭环工作,但角度来自一个给定的开环转子角度斜坡,而不是观测器输出。速度环在这个阶段可以禁用,避免转速反馈不稳定。
强拖过程中,观测器一直在后台工作,实时计算真实的电角度。强拖电角度和观测器角度之间存在一个逐渐缩小的偏差,因为转速起来之后反电动势增强,观测器收敛的角速度跟得上实际转速,偏差会越来越小。当满足以下条件时,切换成全闭环FOC:
- 观测器角度与给定角度的偏差小于一个设定阈值,比如5度电角度;
- 偏差值持续稳定一段时间,比如50毫秒,避免瞬时波动造成误判;
- 估计速度与给定速度的偏差在允许范围内。
切换时不能简单地把角度源从“给定角度”一刀切到“观测器角度”,否则电流矢量方向和转子实际方向有残余偏差时,电流会突变,产生“打齿”现象。平滑做法是把给定角度和观测器角度做一个加权过渡,或者根据偏差方向对观测器角度做小幅修正,让切换在几个周期内完成。
我在实际调试中试过直接硬切,低速45度偏差以下还勉强能接受,一旦负载波动大一点,切换瞬间q轴电流能冲出额定电流的150%,母线电压都被拉出明显塌陷。后来改成切换前先让给定角度以观测器角度为锚点做速降修正,切换时的电流冲击就小得多。
3.4 电角度快速收敛的判据与测量方式
收敛速度快不快,不能光靠感觉,要量化。最简单的观测方法是用调试接口把观测器角度和给定角度同时导出来,观察偏差曲线。另一路重要的信号是切换瞬间的dq轴电流。如果收敛和过渡做得好,切换瞬间Id和Iq的冲击很小,基本维持在切换前的水平;如果收敛不好,Id会突然跳到较大的数值,甚至影响电流环稳定性。
转速观测值的收敛也很重要。如果使用锁相环估计速度,收敛时间主要由锁相环带宽决定。带宽设太高,角度噪声会被放大为速度抖动;带宽设太低,启动加速过程中速度估计滞后,影响速度环响应。我一般把锁相环带宽设在40到80Hz左右,对多数中小功率电机都够用。
4. 实操调试与工程落地细节
4.1 先标定电流采样,别急着跑观测器
无感FOC对电流采样的准确性要求极高。ADC的零漂、增益偏置、采样电阻误差,这些都会直接映射为dq轴电流误差,最终导致观测器角度偏差。
第一个坑是ADC零漂。运放输入存在小的直流偏置,未运行时读到的ADC值可能不是数字中心值,如果不做软件校准,静止状态下就会出现“假电流”,观测器会误判磁链方向。我建议在电机不转、无PWM输出时,把每个通道的ADC值采集200个点取平均,作为零漂补偿值,存起来。启用PWM后,在电流为零的斩波状态下再确认一次零点是否偏移。
第二个坑是采样时刻。中心对齐PWM下,采样点必须放在PWM的中间位置。G431的高级定时器可以用触发信号直接启动ADC,我们只要在定时器配置里把ADC触发源指向对应的定时器更新事件,并且把ADC采样时间设置好,就能保证每次采样都落在电流纹波最小的时刻。不要在中断里软件触发ADC,这样容易受中断抖动影响。
第三是电流标定增益。读到的ADC码值要换算成安培值,公式很简单:电流(A) = (ADC码值 - 零点码值) × 参考电压 / (采样电阻 × 运放增益 × ADC分辨率)。但这个增益必须实测,不要只用理论值。方法是用一个高精度电流源或者串一个标准电阻通电流,逐点验证20%、50%、100%额定电流下的换算误差。
4.2 电机参数的获取与误差影响
观测器的准确性直接依赖Rs、Ls、ψpm三个参数。这三个参数不准确,观测器在高负载时就会出现固定方向的角度偏差,而且不容易察觉,因为空载下角度是准的,一带负载就偏。
Rs最好通过直流法测:给电机绕组通一个很小的直流电流,测量相电压和相电流,算得相电阻。但注意运行中铜耗发热会让电阻变化,尤其在低速大扭矩场景,电阻误差会导致低速段角度偏差变大。所以实际代码里我会把当前绕组温度的估算纳入考虑,粗略用温度系数修正Rs。
Ls不能用万用表量,要在转子固定的状态下施加一个电压阶跃,观察电流上升速率。电感越大,电流上升越慢。我常用的方法是给d轴或α轴施加一个固定占空比脉冲,记录电流从10%上升至90%的时间,再反算电感。更准确的可以在转动状态下用高频小信号注入测量,但对大多数贴片式电机,阶跃法已经够用。
ψpm可以通过反电动势常数换算:手动把电机拖到一个稳定转速,测相间电动势的峰值,再折算到相电压幅值。没有条件手拖的话,可以在已知电流环参数的前提下,用堵转力矩换算,但精度要低一些。
这三个参数对观测器角度的影响模式不一样:Rs不准,低速和零速角度偏差大;Ls不准,带载后的角度偏差随转矩变化;ψpm不准,则角度偏差随电流和负载同时漂移。所以参数标定这一步做得越精细,后面调试越顺利。
4.3 用虚拟角度验证电流环,再接入观测器
很多工程师在调试无感FOC时,一上来就直接把观测器接入闭环,结果系统不稳定,到处找原因却找不到。我更推荐分步验证。
第一步,先把速度环禁用,角度给定一个斜坡信号,让电流环以这个虚拟角度运行。此时电机确实是转的,但不是闭环转速,而是跟随一个开环角度旋转。这一步验证的是电流采样、坐标变换、电流PI、SVPWM整条链路是否正确。如果电流环响应正常,说明底层没问题。
第二步,把观测器接入,但让观测器只作“旁路观察”,不给FOC供角度,而是把观测器输出角度和斜坡给定角度同时用调试通道导出来。这样可以在不闭环的情况下看观测器角度收敛得准不准,避免了系统不稳定时“锅都甩给观测器”的尴尬。
第三步,再做切换闭环。通过观测器角度和斜坡角度的偏差逐步收窄的过程,可以判断切换条件是否合理。
4.4 观测器增益和系统带宽的匹配
Kobs的选取直接影响观测器动态和噪声抑制。Kobs大,反馈校正强,磁链会被电流模型强力拉回,抗漂移能力好,但会把电流噪声高频分量注入磁链,角度会细微抖动;Kobs小,电压模型主导,高速段性能好,但低速段容易漂。
我把Kobs看作一个“信任分配旋钮”。常规取值在电机电气频率的几倍到十几倍之间。比如采用20kHz采样率,电气频率最高200Hz左右,Kobs可以取30到80rad/s。如果电机极对数多、额定转速低,可以把Kobs调低;如果启动频繁、低速维持时间长,就调高一点。
系统带宽匹配上,电流环带宽一般远高于观测器带宽,锁相环速度估计带宽低于电流环带宽1到2个数量级,避免多个环路频率交叠产生振荡。具体带宽数值可以通过阶跃响应和电流波形来观察调整。
5. 常见问题与排障实践实录
5.1 启动时电机反转一下或卡死
这种问题九成出在预定位环节。可能原因包括:对齐时间太短,转子还没稳定就被切走;观测器初值注入的角度和实际对齐方向不一致;永磁体磁链方向理解反了,导致后续角度与电流方向反相,电机自然反向。
排查步骤是先延长预定位时间,观察对齐过程中的电流波形和转子运动,确认定子磁场方向。如果电机反转,可以把给定角度反向或者把电角度的符号取反,但需要确认电机相序和编码标识。做无感时没有编码器,最好的验证方法是从U相和V相工装探针看反电动势相位,确认方向与观测量符号一致。
5.2 观测器角度缓缓漂移
角度漂移的最常见原因是积分器直流偏移。电压采样、ADC零漂、电流采样偏置、三相电流重建误差,任何一个直流分量都会在积分过程中线性累积。解决思路有三个方向:
第一,对积分器输出加饱和限幅;第二,提高电流模型反馈项的权重;第三,在静止或极低速工况下,让磁链强制跟踪电流模型,而不是继续自由积分。
我还在代码里增加了一个低通校正项,把磁链向电流模型参考值缓慢拉回,相当于给纯积分加了一个“软束缚”。这个校正项的带宽一般设得很低,比如0.5Hz到2Hz,避免影响高速动态。
5.3 切换时“打齿”和电流冲击
切换跳变主要是角度源切换时出现的相位不连续,以及速度给定在切换瞬间突变。解决方法是平滑融合。我采用的流程是:先让给定角度的角速度实时同步到与观测器估计速度一致,再把当前给定角度逐步偏向观测器角度,完成“锁相”,最后才把角度源切到观测器。
如果切换后q轴电流出现周期性波动,大概率是切换时角度还残余偏差。可以把切换阈值收紧到15度甚至10度,同时检查收敛稳定时间是否需要拉长。不要拿阈值太激进,否则切换条件永远不满足,电机一直处于强拖状态,带负载时可能顶不住。
5.4 带负载后角度偏、力矩不稳
这个现象多半不是算法问题,而是参数不准。我之前在一次试验中,Ls实测值和铭牌值差了15%,空载下电机运行很平稳,一带半载就出现明显的q轴电流周期性波动,后来重新辨识Ls,角度偏差消除。
死区补偿也要重点检查。死区产生的电压误差不是正弦量,而是一个随电流方向变化的方波误差,会造成6次脉动的角度扰动。方法是在SVPWM输出前根据三相电流符号补偿死区电压。G431的定时器可以配置死区时间,补偿量根据实际死区、开关管压降和电流方向动态估算。
5.5 常见问题速查表
| 现象 | 可能原因 | 优先排查动作 |
|---|---|---|
| 启动就反转 | 预定位角度错误、相序接反 | 检查给定角方向、延长对齐时间 |
| 启动抖一下才转 | 观测器初值未注入或角度不匹配 | 预定位后同步磁链初值 |
| 切闭环时冲击大 | 角度源切换无过渡 | 先锁相再切换,修正速度前馈 |
| 空载稳、负载偏 | Ls或ψpm参数不准 | 重新辨识参数,检查死区补偿 |
| 角度缓慢漂移 | 积分漂移或ADC零漂未校准 | 加饱和限幅、软束缚校正项 |
| 低速噪声大 | 电流采样噪声大、Kobs过高 | 检查采样时刻,降低Kobs |
| 速度估计抖动 | 锁相环带宽太高 | 降低锁相环带宽或增加滤波 |
6. 我个人调试这套方案的一点体会
这套STM32G431FOC线性磁链观测器方案,我从把第一个例程跑通到最终在样机上稳定带载,前前后后花了将近三周。最大的体会就是:无感FOC不等于简单地把传感器去掉,而是要把整个系统的“可观测性”重新设计一遍。观测器代码本身很简单,最花时间的永远是参数标定、采样噪声治理、切换平滑这些工程细节。
如果让我给后来者一句话,我会说:先把电流采样和预定位做好,再去纠结观测器算法选型,这是无感FOC成功的地基。观测器只是把好的数据加工成角度的工具,数据源不干净,再好的算法也救不回来。
另外,调无感FOC一定要保留一个示波器通道看波形,尤其是角度收敛过程和dq电流变化,比看任何数值列表都直观。我最后试出的那组参数,就是在示波器上反复观察电流切换波形,一点点调整Kobs和锁相环带宽得到的。
这套方案对中小功率PMSM是够用的,但如果你要应用在零速极强载荷或者需要真正意义上零速高频注入的场合,那就该考虑把高频信号注入模块加进来了。线性磁链观测器的强项是中高速和快速启动场景,把它的性价比发挥到极致,比一味追求复杂算法更实际。