☰
AN1078 无传感器 FOC 实战:从 Clarke 变换到滑动模式观测器的参数整定
2026/10/15 8:06:24 网站建设 项目流程

简介:AN1078是Microchip(微芯科技)发布的一份电机控制应用笔记,面向家电电机控制工程师、嵌入式开发者及高校相关专业学习者,聚焦永磁同步电机(PMSM)的无传感器磁场定向控制(FOC)实现方案。文档从家电节能与静音需求出发,对比传统六步控制,阐述FOC在平滑转矩、适应动态负载方面的优势,并说明如何借助dsPIC DSC系列(如dsPIC30F6010A)的PWM、高速ADC、QEI等外设完成算法落地,涵盖位置与速度估算、电流检测及DMCI调试界面等内容。资源包为1个PDF文件,大小约1.03MB,便于下载后离线查阅与打印。目前已有1079人学习下载,适合希望深入理解无传感器FOC原理、评估dsPIC平台电机控制方案或进行空调压缩机等家电项目选型的读者参考。

1. 从一份 2007 年的应用笔记说起:AN1078 到底解决了什么问题

如果你手头有一块 dsPIC30F 或 dsPIC33F 的电机控制板,想跑永磁同步电机的无传感器 FOC,却卡在“角度怎么估、电流怎么采、PI 怎么调”这三座大山前,那 AN1078 这份文档大概率是你绕不开的起点。它不是什么新东西,2007 年发布的,编号 DS01078A_CN,作者 Jorge Zambada,全篇围绕一个目标:用 dsPIC DSC 的片内 PWM 和高速 ADC,在没有任何位置传感器的前提下,把一台 1.5 kW 空调压缩机从 500 RPM 拉到 7300 RPM。听起来像老古董,但里面那套滑动模式控制器加反电动势估算的框架,至今仍是很多低成本家电方案的核心骨架。适合谁看?做白色家电电控的、搞风机水泵无感驱动的、以及被霍尔传感器线束和浸水问题折磨过的硬件工程师。它不教你 FOC 是什么,它直接告诉你在这颗芯片上怎么把 FOC 跑起来。

2. 拆解 AN1078 的算法骨架:从 Clarke 到 SVPWM 的完整链路

2.1 为什么非得用 FOC,六步控制差在哪

传统 BLDC 的六步换相,本质上是给两相通电、第三相悬空,每 60 度电角度换一次。转矩脉动大,噪音刺耳,负载一变就抖。AN1078 里举了个很实在的例子:前开式洗衣机,衣服堆在滚筒顶部时,电机得克服重力做功,负载惯量随时在变。六步控制那种“通一下等转子转过去再换”的逻辑,动态响应根本跟不上。FOC 的思路完全不同,它把定子电流分解成两个直流量:Id 管磁通,Iq 管转矩。控制直流量,就像控制直流电机一样简单。稳态下 Id 和 Iq 是常量,PI 调节器不用追着正弦波跑,响应快、超调小。代价是计算量大,但 dsPIC 有 MAC 指令和硬件饱和,一个周期内能完成乘加,这才让 FOC 在低成本 DSC 上落地。

2.2 坐标变换的工程实现:Clarke 和 Park 到底怎么算

AN1078 把变换拆得很细。第一步 Clarke,三相变两相。因为 ia + ib + ic = 0,所以只测两相电流就够了,第三个用减法算出来。公式是 iα = ia,iβ = (ia + 2ib)/√3。注意这个系数,不是随便写的,它保证了变换前后幅值不变。第二步 Park,把静止的 α-β 转到随转子旋转的 d-q。公式是 Id = iα cosθ + iβ sinθ,Iq = -iα sinθ + iβ cosθ。θ 是估算出来的转子角度,不是测的。这里有个坑:θ 的精度直接决定 Id 和 Iq 能不能解耦。如果 θ 偏了,Id 里会混进 Iq 的分量,转矩控制就废了。AN1078 用滑动模式控制器来估 θ,后面细说。

// Clarke 变换:输入 ia, ib,输出 iAlpha, iBeta // 注意:ic 由 ia + ib + ic = 0 推出,不单独测量 iAlpha = ia; iBeta = (ia + 2 * ib) * ONE_BY_SQRT3; // ONE_BY_SQRT3 = 0.577350269 // Park 变换:输入 iAlpha, iBeta, sinTheta, cosTheta,输出 iD, iQ // sinTheta 和 cosTheta 来自位置估算器,不是查表 iD = iAlpha * cosTheta + iBeta * sinTheta; iQ = -iAlpha * sinTheta + iBeta * cosTheta;

这段代码里 ONE_BY_SQRT3 是个常量,别用浮点算,dsPIC 上直接写 Q15 格式的定点数。sinTheta 和 cosTheta 由 CORDIC 算法迭代产生,AN1078 没展开 CORDIC 细节,但源码里 CalcRef.s 和 SVGen.s 有完整实现。我一般会先把 sin/cos 表打出来验证 CORDIC 输出对不对,再往下调 PI。

2.3 PI 调节器的抗积分饱和:Kc 系数怎么设

AN1078 用了三个 PI 环:速度外环、Id 内环、Iq 内环。速度环输出是 Iq 的参考值,Id 参考值通常设 0(表贴式 PMSM 不需要弱磁)。每个 PI 都带一个 Kc * Excess 项来抑制积分饱和。Excess 是未限幅输出 U 和限幅后输出 Out 的差。当 U 超过 Outmax 时,Excess 为正,Kc 乘上去从积分累加项 Sum 里减掉,防止积分项越积越大。Kc 一般取和 Ki 相同就行。调 PI 的顺序:先把 I 和 D 设 0,只加 P,加到系统能响应设定点变化但不振荡;然后慢慢加 I,消静差。I 给大了会抵消 P 的作用,系统在设定点附近来回晃。这时候别急着降 I,先试试把 P 加大,往往能压住。

// PI 控制器核心逻辑,带抗积分饱和 // Kp, Ki, Kc 均为 Q15 格式定点数 Err = InRef - FB; U = Sum + Kp * Err; if (U > Outmax) { Out = Outmax; } else if (U < Outmin) { Out = Outmin; } else { Out = U; } Excess = U - Out; Sum = Sum + Ki * Err - Kc * Excess; // Kc 通常等于 Ki

注意 Sum 是累加项,每个控制周期执行一次。控制周期 50 µs,对应 20 kHz 的 PWM 频率。AN1078 里 CPU 开销约 21 MIPS,占 dsPIC30F6010A 总资源的 2/3。如果你换到 dsPIC33F,主频更高,余量会大一些。

2.4 空间矢量调制:为什么用 SVM 而不是正弦 PWM

SVM 的直流母线利用率比正弦 PWM 高约 15%。AN1078 把 Clarke 逆变换直接嵌进 SVM 程序里,省掉一步计算。三相逆变器有 8 种开关状态,6 个有效矢量把平面分成 6 个扇区,每个扇区 60 度。期望电压矢量 UOUT 由相邻两个有效矢量和零矢量合成。T1 是第一个矢量的作用时间,T2 是第二个,T0 是零矢量时间。T1/T 和 T2/T 就是占空比。dsPIC 配置成中心对齐 PWM,每个周期产生两个线间脉冲,有效开关频率翻倍,纹波电流减小,开关损耗没增加。表 1 里那 8 种状态对应的线电压,调试时可以用示波器逐项核对。

状态A 相B 相C 相VabVbcVca
U000000000
U0010010-VDCVDC
U010010-VDCVDC0
U011011-VDC0VDC
U100100VDC0-VDC
U101101VDC-VDC0
U1101100VDC-VDC
U111111000

这张表建议打印出来贴在工位上。调 SVM 时,先让电机开环转,用示波器看三相下桥臂的驱动波形,确认扇区切换时没有异常窄脉冲。如果有,检查 T1 + T2 是否超过 PWM 周期 T,超了就限幅。

3. 无传感器位置估算:滑动模式控制器与反电动势观测器

3.1 电流观测器的闭环校正逻辑

AN1078 的位置估算核心是一个电流观测器。它用软件搭了一个电机模型,输入同样的电压 vs,输出估算电流 is*。但软件模型和真实硬件总有偏差,所以引入滑动模式控制器来校正。SMC 计算测量电流 is 和估算电流 is* 的差的符号,乘以增益 K,得到校正因子 Z。Z 加到软件模型的电压项上,每个控制周期都调一次,直到 is 和 is* 的差趋近于零。这时候软件模型的反电动势 es* 就近似等于真实电机的反电动势 es。整个逻辑是:电流差 → 符号函数 → 增益 K → 校正电压 → 修正模型 → 反电动势收敛。

// 滑动模式控制器核心 // isMeas 和 isEst 是 Q15 格式的电流矢量 // K 是 SMC 增益,需要根据电机参数调 if ((isMeas - isEst) > 0) { Z = K; } else { Z = -K; } // Z 加到电压项,更新估算电流 // isEst(n+1) = F * isEst(n) + G * (vs(n) - esEst(n) - Z)

K 给大了,系统抖振厉害,电流噪音大;给小了,收敛慢,动态响应差。我一般从电机额定电流的 10% 开始试,用示波器看估算电流和实测电流的跟踪情况,慢慢加 K 直到跟踪变好但还没出现明显高频抖动。

3.2 F 和 G 参数的计算:万用表量出来之后怎么代

F 和 G 是数字化电机模型的两个系数。F = 1 - Ts * R / L,G = Ts / L。R 和 L 是相电阻和相电感。注意:万用表量的是线间电阻和线间电感,代入公式前要除以 2。AN1078 里举了个例子:线间电阻 5.0 Ω,线间电感 10 mH,控制频率 8 kHz。那么相电阻 R = 2.5 Ω,相电感 L = 5 mH。Ts = 1/8000 = 125 µs。F = 1 - 125e-6 * 2.5 / 5e-3 = 1 - 0.0625 = 0.9375。G = 125e-6 / 5e-3 = 0.025。这两个值直接写进代码,用 Q15 格式。如果电机参数变了,F 和 G 必须重算,否则观测器收敛不了。

// 根据电机参数计算 F 和 G // R_phase 和 L_phase 是相电阻和相电感,单位欧姆和亨利 // Ts 是控制周期,单位秒 float F = 1.0 - Ts * R_phase / L_phase; float G = Ts / L_phase; // 转成 Q15 定点数 int16_t F_Q15 = (int16_t)(F * 32768.0); int16_t G_Q15 = (int16_t)(G * 32768.0);

这里有个血泪经验:L 的测量精度对 G 影响很大。万用表测电感本身就不准,最好用 LCR 表,或者在电机静止时注入高频小信号测阻抗来反推。G 偏了,估算电流的幅值就不对,反电动势也跟着偏,最后 θ 就歪了。

3.3 反电动势滤波与 theta 计算:CORDIC 为什么比查表快

SMC 输出的 Z 经过一阶低通滤波得到 e*。滤波器公式:e(n) = e(n-1) + (2πfc / fpwm) * (z(n) - e(n-1))。fc 是截止频率,fpwm 是 PWM 频率。AN1078 用 8 kHz 的 fpwm,fc 根据 SMC 增益调。滤波后的 eα 和 eβ 用来算 θ。θ = arctan(eα, eβ)。直接调 arctan 函数在 DSC 上很慢,AN1078 用 CORDIC 迭代算法。CORDIC 通过一系列固定角度的旋转逼近目标角度,只用移位和加法,不用乘法,速度比查表还快,内存占用也小。源码里 CalcRef.s 有完整的 CORDIC 实现,迭代次数一般取 12 到 16 次,精度够用。

// 一阶数字低通滤波器,用于反电动势滤波 // e_prev 是上一周期的估算反电动势 // z 是 SMC 输出 // fc 是截止频率,fpwm 是 PWM 频率 float alpha = 2.0 * 3.1415926 * fc / fpwm; float e_new = e_prev + alpha * (z - e_prev); // e_new 用于计算 theta

滤波器的 alpha 不能太大,大了滤波效果差,反电动势里混着开关噪音;小了相位滞后严重,θ 补偿量得加大。AN1078 把相位补偿分成 8 个速度段,每个段有独立的斜率和常量。表 2 给了具体公式,比如速度在 0.09375 到 0.1875 之间时,θoffset = 4 * ωfiltered + 0.375。这个表是调出来的,不是算出来的,换电机必须重新标定。

3.4 速度计算与相位补偿:为什么 theta 需要补偿

速度是通过累加 m 次 theta 的差值再乘 Kspeed 得到的。公式:ω = Σ(θ(n) - θ(n-1)) * Kspeed。累加 m 次是为了平滑,m 一般取 8 到 16。算出来的 ω 再经过一阶滤波得到 ωfiltered。因为反电动势滤波引入了相位滞后,所以最终给 PWM 用的 θ 必须加上补偿量 θoffset。补偿量随速度变化,低速时滞后小,高速时滞后大。AN1078 用分段线性拟合,8 个速度段覆盖 500 到 7300 RPM。如果补偿不准,电机会发热、效率低,严重时失步。调试时用示波器看相电流和相电压的相位差,目标是在整个速度范围内保持接近零。

// 速度计算:累加 m 次 theta 差值 int32_t sumDeltaTheta = 0; for (int i = 0; i < m; i++) { sumDeltaTheta += (theta[n] - theta[n-1]); } omega = sumDeltaTheta * Kspeed; // 一阶滤波 omegaFiltered = omegaFiltered + alphaSpeed * (omega - omegaFiltered); // 相位补偿:根据 omegaFiltered 查表或分段计算 thetaOffset = getThetaOffset(omegaFiltered); thetaComp = theta + thetaOffset;

Kspeed 的计算涉及极对数、PWM 周期和 Q15 格式转换。AN1078 附带一个电子表格,输入 RPM 和补偿角度,自动算出斜率和常量。我一般会先用这个表格生成初始值,再在台架上微调。

4. 电机起动与低速阶段的避坑指南

4.1 开环强拖:为什么不能一上来就闭环

无传感器 FOC 依赖反电动势估算,电机静止或极低速时反电动势为零或极小,观测器根本估不出 θ。所以 AN1078 用开环起动:按下启动按钮,DSC 产生连续正弦电压,按固定加速度把电机拖起来。θ 由开环累加产生,不依赖观测器。电流环仍然工作,控制 Id 和 Iq。等速度到了能估算反电动势的下限,再切闭环。这个切换点很关键,切早了观测器没收敛,切晚了电机可能失步。AN1078 的起动程序里,相角度按平方率递增,保证恒定加速度。切换条件一般是估算速度和开环速度的差小于某个阈值,并且持续若干个周期。

// 开环起动:theta 按平方率递增 // accel 是加速度常数,根据电机惯量和负载调 thetaOpenLoop += accel * t * t; // 限制 theta 在 0 到 2π 之间 if (thetaOpenLoop > TWO_PI) { thetaOpenLoop -= TWO_PI; } // 切换条件:估算速度接近开环速度 if (abs(omegaEst - omegaOpenLoop) < SWITCH_THRESHOLD) { switchCounter++; if (switchCounter > SWITCH_DELAY) { closedLoop = 1; } } else { switchCounter = 0; }

accel 给大了,电机起步猛,电流冲击大;给小了,起动太慢,洗衣机这种应用用户等不及。我一般从额定转矩的 50% 开始试,看起动电流波形,慢慢加。

4.2 常见问题排查:从现象到根因

现象一:电机起动时抖动,转不起来。原因通常是开环加速度和负载不匹配,或者切换点太早。解决:降低 accel,把切换阈值放宽,延迟切换周期数加大。用示波器看 q 轴电流,如果切换瞬间 Iq 有尖峰,说明观测器还没收敛。

现象二:低速时电流噪音大,电机发热。原因可能是 SMC 增益 K 太大,或者反电动势滤波器截止频率太高。解决:降 K,降 fc。但降 K 会减慢收敛,降 fc 会加大相位滞后,需要重新标定 θoffset。这是个折中,没有免费午餐。

现象三:高速时失步,电流失控。原因通常是相位补偿不够,θ 滞后太多,导致 Id 和 Iq 解耦失败。解决:检查表 2 的补偿公式,在高速段加大 θoffset。另外确认 PWM 死区时间是否合适,死区太大会导致电压失真,反电动势估算也跟着偏。

现象四:估算速度波动大,PI 输出不稳。原因可能是速度计算累加次数 m 太小,或者 Kspeed 没算对。解决:加大 m,重新核对 Kspeed 的 Q15 转换。AN1078 的电子表格里可以验证。

现象五:ADC 采样噪音大,电流波形毛刺多。原因通常是采样时刻没对齐 PWM 中心。dsPIC 的 ADC 由 PWM 触发,触发点应该在 PWM 周期的中心,这时候开关噪音最小。检查 PWM 配置寄存器,确认触发沿和采样窗口。另外,采样电阻的布局和滤波电容也很关键,这是硬件的事,但软件调不出来的时候先查硬件。

提示:AN1078 的源码里 UserParms.h 集中了所有可调参数,包括 PI 增益、SMC 增益、F 和 G、相位补偿表。改参数前先备份,每次只改一个,改完记录现象。电机控制调试没有捷径,就是耐心加示波器。

5. 从 AN1078 到实际产品:参数整定与验证的几条硬规矩

AN1078 的代码框架是通用的,但参数没有一组是通用的。我见过太多人直接把源码烧进去,电机要么不转,要么转起来像得了帕金森。这里说几条我踩过坑之后养成的习惯。第一,F 和 G 必须用实际电机的相电阻和相电感重算,万用表量线间值除以 2,但最好用 LCR 表在 1 kHz 下测,因为 FOC 的电流频率就在这个范围。第二,SMC 增益 K 从额定电流的 5% 开始,每次加 1%,用示波器看估算电流和实测电流的重合度,重合度不再提升就停。第三,相位补偿表必须逐速度点标定,AN1078 给的 8 段公式是参考,不是圣旨。标定方法:让电机在某个速度下空载运行,用示波器看相电压和相电流的过零点,调整 θoffset 使两者同相。每个速度点都这么干,然后拟合成分段线性。第四,PI 参数先调电流环再调速度环。电流环带宽至少是速度环的 5 倍,否则两个环互相干扰。电流环 Kp 从 0.5 开始,Ki 从 0.01 开始,看阶跃响应,超调小于 10% 就行。速度环 Kp 从 0.1 开始,Ki 从 0.001 开始,响应时间根据应用定,洗衣机这种不需要太快,500 ms 到 1 s 都行。

验证的时候,别只看电机转不转。要测三个东西:一是相电流 THD,越低越好,一般要求小于 10%;二是效率,输入功率和输出功率的比值,AN1078 的目标是节能,效率不达标一切白搭;三是全速度范围内的 θ 跟踪误差,用示波器看估算 θ 和实际 θ(如果有编码器可以对比),误差超过 10 度就得重新标补偿。最后,别忘了诊断模式。AN1078 支持在示波器上实时看内部变量,这个功能调 PI 的时候太有用了,比串口打印快得多。我一般会把 Id、Iq、θ、ω 四个变量映射到 DAC 输出,示波器四通道同时看,动态过程一目了然。

从那以后我每次拿到一份新的电机控制应用笔记,都强制自己先把参数整定流程走一遍,不跳步,不凭感觉。AN1078 这份文档的价值不在于它给了你一组能用的参数,而在于它把从 Clarke 变换到滑动模式观测器的每一步都拆开了,让你知道每个数字从哪来、改哪个旋钮会有什么后果。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询