我先把话说在前头,这篇不是科普文,是我自己在F103平台上把无感FOC从零跑到量产的实战记录。中间踩过的坑、走过的弯路、想明白的原理,全在里面,你照着做不敢说一次成功,但至少能少熬几个通宵。
1. F103跑无感FOC到底行不行:资源账与成本账
1.1 72MHz/64KB的底子够干什么
很多人一听STM32F103就皱眉——Cortex-M3内核,主频72MHz,没有FPU,64KB Flash,20KB SRAM,这配置能跑FOC加滑模观测器?我刚开始也这么想,但实际跑下来,F103不仅够用,而且绰绰有余。
先算一笔时间账。电流环控制频率按16kHz算,一个控制周期是62.5微秒。在这62.5微秒里,要完成三相电流ADC读取、Clarke变换、Park变换、电流环PI(d轴和q轴各一个)、反Park变换、SVPWM计算、SMO观测器更新,整套下来浮点运算量大概五六百次乘加。F103没有FPU,浮点运算全靠编译器软浮点库,一次float乘法大概要几十个周期,整套算下来一个周期大约需要35到40微秒。也就是说,16kHz电流环下CPU占用大概60%,剩下40%给速度环、通信和显示逻辑,完全够用。
如果要把电流环推到20kHz甚至更高,那F103确实吃力,这时候有两条路:要么把电流环降到10kHz到12kHz,要么把核心运算改写成Q格式定点数学。我在量产版本里用的是16kHz,整机跑得很稳。
再说存储。无感FOC的代码量其实没有想象中大,观测器加电流环加SVPWM,核心文件也就千行左右,加上速度环、通信协议和UI,全部下来40KB Flash以内能装下。SRAM方面,主要吃内存的是ADCDMA缓冲区、几个控制结构体变量表,加起来不超过2KB,20KB的SRAM相当宽裕。
最后看外设。F103最值钱的资源是TIM1高级定时器,有6路互补PWM输出,带硬件死区插入,这个做三相逆变桥驱动是量身定做的。ADC有12位分辨率,支持注入组,可以硬件触发同步采样。这两样凑齐了,做FOC硬件基础就成立了。
1.2 无感相比有感的成本优势有多明显
很多人问一个问题:既然无感FOC这么麻烦,为什么不直接装个霍尔传感器或者编码器?
道理很简单——算一笔账。一个线性霍尔传感器模组价格几块钱到十几块不等,一个光电编码器动辄几十上百块,磁编码器芯片倒是便宜些,但安装结构、磁铁、线束、接插件配套下来,成本直接拉高一个量级。而且传感器属于机械件,有磨损、有温漂、有安装偏差,在振动环境下故障率还高。
无感方案把传感器整个砍掉,硬件上只保留三路电流采样加一路母线电压采样,其余的转子位置和速度全部靠软件估算。这一刀砍下去,物料成本和系统可靠性同时受益。我在量产BOM里做过统计:去掉霍尔传感器及其附属电路,单板物料成本每套省下十几到二十几块钱,批量上万套之后,这笔账相当可观。
1.3 整机BOM里哪些钱可以再抠
既然说成本,我直接把一个典型的低成本无感FOC驱动器物料清单摊开算给你看:
| 物料 | 选型示例 | 单件成本(批量价) |
|---|---|---|
| 主控MCU | STM32F103C8T6 | 约5-8元 |
| 三相栅极驱动 | EG2134或IR2103 | 约2-5元 |
| 功率MOSFET | 低压N沟道MOS,6只 | 约6-12元 |
| 电流采样运放 | LMV358或OPA4377 | 约1-3元 |
| 采样电阻 | 10毫欧毫欧级合金电阻,3只 | 约1-2元 |
| 无源器件与接口 | 电阻电容接插件 | 约5-10元 |
| PCB | 双面板小批量摊薄 | 约3-5元 |
整机下来,元件成本大概在25到45元之间,具体看功率等级和MOS选型。这个价格和带传感器的FOC驱动器比,差距一下子就出来了。而且F103开发资料多,遇到问题随便一搜就能找到参考,不用像某些专用电机控制芯片那样绑死在原厂工具链上,这也是我用它做低成本方案的核心理由。
2. 硬件设计:采样增益、栅极驱动与PCB上的毫伏级信号
2.1 三电阻采样为什么是最稳的低成本方案
电流采样方案有三个流派:单电阻、双电阻、三电阻。
单电阻最省,只在母线低端放一个采样电阻,靠PWM不同开关状态下母线电流重构三相电流。听起来很美,但在低调制比区域以及死区附近,某些开关状态持续时间太短,重构出来的电流畸变严重,需要复杂的补偿算法,对ADC采样窗口要求也苛刻。我一开始想省这个钱,调试阶段就放弃了,白白浪费了两周。
双电阻方案在任意时刻只能采集两相电流,第三相靠基尔霍夫定律相电流之和为零来算。算法比三电阻简单不少,成本也只少一个采样电阻和一路运放,是性价比之选。
三电阻方案采样电阻和运放各三个,BOM成本高几块钱,但换来的是任意时刻都能直接得到三相电流,观测器拿到的电流质量最好。对于SMO这种对电流噪声敏感的算法,多花这几块钱非常值。我量产板最终用的就是三电阻采样。
2.2 运放增益计算:从分流电阻到ADC满量程
电流采样回路的设计目标很明确:把采样电阻上的压降放大到ADC输入范围,同时留出足够的过流裕量。我以我常用的24V/15A电机驱动器为例一步步算给你看。
采样电阻选10毫欧,峰值相电流15A,那么采样电阻上的最大压降是:
U_peak = I_peak × R_shunt = 15A × 0.01Ω = 150mV
这个信号太小,ADC直接采不了,必须放大。我设计目标是把最大20A的电流映射到ADC的3.3V满量程(留了33%的过流裕量),那么运放的增益应该是:
Gain = 3.3V / (20A × 0.01Ω) = 16.5
实际取整为16.5倍,用典型的同相放大电路,反馈电阻取51kΩ,对地电阻取3.3kΩ,增益约为1 + 51/3.3 ≈ 16.45,基本满足要求。如果采样电阻用5毫欧,增益就要翻倍到33倍,此时运放的失调电压和噪声会被同比例放大,对运放选型要求更高。
单电源供电下运放输出不能到0,所以要把信号抬高到1.65V中点偏置。做法是用电阻分压把参考电压抬到1.65V,再加一个RC低通滤波放在ADC输入前端。这里有个细节:偏置电压的噪声会被直接叠加到采样信号上,所以偏置电阻的滤波电容一定要加,而且要靠近运放引脚。
运放选型上,低成本方案里我比较推荐轨到轨输入输出运放,LMV358虽然便宜但带宽偏低,在16kHz PWM下增益误差会偏大。OPA4377带宽高一些,价格也不贵,我在量产板上用的就是它。
2.3 自举电容和死区:栅极驱动最常见的两个坑
三相桥的高侧MOS需要自举供电,这是半桥驱动芯片的典型做法。自举电容的容量选择是个关键:容量太小,高侧导通期间电压跌落过大,驱动能力不足;容量太大,充电时间变长,高压侧启动时可能来不及建立电压。
实际计算时,自举电容的最小容量可以按这个思路估算:
C_bs = Q_g / ΔV_bs
其中Q_g是MOSFET栅极总电荷,从规格书里查;ΔV_bs是允许的压降,一般控制在0.5V以内。举个例子,我用的MOSFET栅极电荷是25nC,允许压降0.3V,那么:
C_bs = 25nC / 0.3V ≈ 83nF
实际取100nF,再并联一个10μF电解电容稳定供电。这个组合在绝大多数低压电机驱动器上都能正常工作,具体数值还要确认你选的MOS管参数。
死区时间同样不能拍脑袋。我实测过几种MOS管的关断延迟,通常在50到150纳秒之间。死区设太短,上下管直通烧管子;设太长,电流波形畸变明显,SMO观测器的角度估计误差会变大。我建议起始值取1微秒,再根据示波器实测的开关波形做微调,在保证不死区穿越的前提下尽量缩短。
2.4 PCB布局:让采样回路和功率回路各走各的
PCB布局是整个项目里最容易“看起来没问题、一上电就崩溃”的环节。核心原则就一句话:采样信号回路和功率电流回路必须物理隔离。
先说采样电阻的布局。采样电阻要尽量靠近运放输入端,采样信号的走线要采用Kelvin连接,也就是从采样电阻的两个焊盘单独拉两根细线到运放,不要贪方便直接在焊盘上连到功率走线。否则负载大电流流经PCBCopper时产生的压降会直接叠加到采样信号上,小电流时无所谓,大电流时电流波形上会出现一条条毛刺,SMO观测器直接发散给你看。
功率回路的布局也有讲究。三相桥的输入电容到MOS管的环路面积要尽量小,这个环路面积决定了开关瞬态的寄生电感,环路越小,尖峰越低。母线电容要放在三相桥的电源输入端,而不是随意摆在PCB的角落里。我在第一版板上把母线电容放远了5厘米,满载测试时波形上的高频振荡怎么都压不下去,后来把电容挪到MOS管旁边,问题当场消失。
还有一个常见错误是模拟地和功率地混在一起。正确做法是:采样运放的参考地单独走一小块模拟地,然后通过一个磁珠或直接单点连接到功率地。这样做是为了避免功率地线上的大电流噪声窜进运放参考端,造成采样偏移。
3. SMO滑模观测器原理推导与代码落地
3.1 表贴式永磁电机的αβ轴模型
SMO滑模观测器的推导起点是表贴式PMSM在静止αβ坐标系下的电压方程:
u_α = R·i_α + L·di_α/dt + e_α
u_β = R·i_β + L·di_β/dt + e_β
这里e_α和e_β是反电动势,它们的表达式是:
e_α = -ψ_f·ω_e·sin(θ_e)
e_β = ψ_f·ω_e·cos(θ_e)
其中ψ_f是转子磁链,ω_e是电角速度,θ_e是转子电角度。也就是说,反电动势里天然带着转子位置信息,只要能从电压电流中把反电动势估计出来,转子的位置和速度就都能拿到了。
这个模型能做SMO的物理前提是:表贴式电机的电感L在d轴和q轴上基本相等,所以αβ坐标系下的方程形式干净,不需要处理凸极效应带来的位置相关电感。如果你手里是内置式永磁电机,这个方法就不能直接用,需要换用基于电感矩阵的扩展反电动势观测器,那是另一个话题。
3.2 滑模观测器在干什么:从电流残差中逼出反电动势
SMO的思路很直接:既然电机的电流动态方程里包含反电动势,那就构造一个电流观测器,让观测电流去跟踪实测电流。当两者有偏差时,用一个符号函数开关控制项把偏差拉回零,而这个开关控制项的平均值,恰好就等于反电动势。
观测器的方程写成这样:
L·d(î_α)/dt = u_α - R·î_α - K·sgn(î_α - i_α)
L·d(î_β)/dt = u_β - R·î_β - K·sgn(î_β - i_β)
K是滑模增益,sgn是符号函数,sgn(x)=1当x>0,-1当x<0。
用生活化的类比理解:你把观测电流想象成一辆车,实测电流是前面带路的车。符号函数项就是一个油门/刹车控制器,观测电流落后了就猛踩油门追上去,超前了就猛踩刹车拉回来。只要油门够大,两辆车就能死死贴在一起跑。当观测电流始终贴着实测电流时,那个油门/刹车的平均输出正好等于阻碍电流变化的反电动势。
当滑模运动建立后,等效控制量就出来了:
z_α = K·sgn(î_α - i_α) ≈ e_α
z_β = K·sgn(î_β - i_β) ≈ e_β
但问题是符号函数的输出是高频抖动的方波,直接拿来算角度会抖得没法用,所以后面必须接低通滤波器,把开关频率分量滤掉,剩下的就是连续平滑的反电动势估计值。
3.3 反电动势到转子角度:atan2还是PLL
拿到反电动势估计值之后,转子角度有两种提取方式。
第一种最直接,用atan2反正切:
θ_e = atan2(-e_α, e_β)
代码简单,计算量小,但缺点是对噪声敏感,反电动势稍有畸变角度就会抖动。而且atan2自带反正切计算,在F103的软浮点库下也是有一次开销的。
第二种是锁相环PLL方式。构造一个角度误差量:
err = e_α·cos(θ_hat) + e_β·sin(θ_hat)
当θ_hat接近真实θ_e时,这个误差量近似等于ψ_f·ω_e·sin(θ_hat - θ_e),也就是一个小角度误差信号。把它送进PI控制器,输出就是估计的电角速度,再积分就得到估计角度。PLL天然就是一个滤波器,输出的角度和速度比atan2加低通滤波平滑得多,而且PLL带宽可以按需调节,兼顾动态响应和滤波效果。
我实测下来的经验是:低速场景下atan2加低通滤波也能用,但转速动态变化大或者负载扰动明显时,PLL的表现明显更好。量产代码里我用的是PLL方案。
3.4 一段可以在F103上跑的SMO参考代码
前面原理讲了这么多,最后都要落到代码上。下面这段是我在F103上跑通的SMO观测器核心代码,为了便于理解,我去掉了工程里的优化细节,保留了完整逻辑:
typedef struct { float R; // 定子电阻, 欧姆 float L; // 定子电感, 亨 float K; // 滑模增益 float lpf_coef; // 低通滤波系数, 0~1 float i_alpha_est; float i_beta_est; float e_alpha; // 滤波后的反电动势 float e_beta; float theta_est; // 转子电角度估计值 float omega_est; // 电角速度估计值(rad/s) } SMO_Handle_t; void SMO_Update(SMO_Handle_t *smo, float u_alpha, float u_beta, float i_alpha, float i_beta, float dt) { float err_alpha = i_alpha - smo->i_alpha_est; float err_beta = i_beta - smo->i_beta_est; // 用sigmoid边界层代替纯符号函数, 减轻抖振 float sw_alpha = err_alpha / (0.001f + fabsf(err_alpha)); float sw_beta = err_beta / (0.001f + fabsf(err_beta)); // 电流观测器更新 smo->i_alpha_est += ((-smo->R * smo->i_alpha_est + u_alpha - smo->K * sw_alpha) / smo->L) * dt; smo->i_beta_est += ((-smo->R * smo->i_beta_est + u_beta - smo->K * sw_beta ) / smo->L) * dt; // 一阶低通从开关控制量中提取等效反电动势 smo->e_alpha += smo->lpf_coef * (smo->K * sw_alpha - smo->e_alpha); smo->e_beta += smo->lpf_coef * (smo->K * sw_beta - smo->e_beta); } void SMO_UpdateAngle(SMO_Handle_t *smo) { float norm = sqrtf(smo->e_alpha * smo->e_alpha + smo->e_beta * smo->e_beta); if (norm < 0.001f) return; // 转速过低时不做角度更新 // 等效反电动势 / 磁链, 得到电角速度 smo->omega_est = norm / FLUX_LINKAGE; // PLL角度跟踪 float err = smo->e_alpha * cosf(smo->theta_est) + smo->e_beta * sinf(smo->theta_est); // 简化: 直接用比例积分更新角度和速度 // Ki_pll和Kp_pll按实际带宽需求整定 smo->omega_est += pll_Ki * err * CONTROL_PERIOD; smo->theta_est += (smo->omega_est + pll_Kp * err) * CONTROL_PERIOD; }两点提醒。第一,e_alpha/e_beta的符号和前面公式里角度提取的对应关系取决于你的电机绕组方向和坐标变换约定,不同工程定义不同,调试时如果发现跟着转速的变化角度貌似正确但符号反了,先检查这里。第二,上面代码里用sigmoid替代了纯符号函数,能在一定程度抑制抖振,但如果边界层系数设太大,会降低观测器的鲁棒性,负载突变时可能失去滑模条件,这个参数要根据电机噪声水平折中。
3.5 滑模增益K怎么定:理论边界与实践经验
K是SMO里最敏感的参数,没有之一。理论上,为了保证滑模运动能够建立,K必须大于反电动势的幅值上界:
K > |e_α|, |e_β|
也就是K要大于ψ_f·ω_e的最大值。反电动势幅值随转速线性增长,所以K必须按最高工作转速来定。但K又不能取得太大,否则开关控制量幅值太大,抖振能量强,低通滤波之后依然会留下残余的高频分量污染电流环。
我调参时的做法是:先根据电机额定转速计算最大反电动势幅值,取1.2到1.5倍作为K的初始值,然后在额定转速下观察电流波形和角度估计的平稳度。如果电流上叠加了明显的高频毛刺,就减小K;如果出现低速抖动或带载时失步,就增大K。实际量产参数往往比理论下界高出不少,我见过有人取到反电动势幅值的2倍还能稳定工作,这取决于你的采样噪声水平和PWM频率。
4. 16kHz电流环是如何在一个M3内核上挤出来的
4.1 双环控制框架:电流环快、速度环慢
无感FOC的软件框架是经典的级联双环:内环是电流环,采样频率和PWM载波同步,16kHz;外环是速度环,在电流环基础上降频,一般1kHz到2kHz就够了。
电流环的作用是让d轴电流和q轴电流快速跟踪给定值。d轴电流给定一般为0,q轴电流给定来自速度环输出,也就是转矩电流指令。电流环PI的输出经过反Park变换得到αβ轴的电压指令,再由SVPWM生成三相占空比。
速度环慢的原因有两个:一是速度本身是位置角度的微分,高频分量基本没有,没必要跑快;二是外环容易与机械结构的谐振频率耦合,跑太快反而容易激发抖动。
两个环的执行顺序要明确:每个电流环周期里,先执行SMO观测器更新得到最新角度,再执行Park变换和电流环PI,最后反Park变换和SVPWM。观测器必须在电流环变换之前跑,不然你用的角度是上一拍的旧值,高速时会产生明显的相位滞后。
4.2 TIM1中心对齐PWM与注入组ADC采样的配合
F103的TIM1在中心对齐模式下,计数器的计数方向在ARR顶点和0点翻转,输出PWM的脉宽中心始终在计数器达到ARR的时刻对称。这个模式天然适合电流采样:当三相的低侧MOS都在导通时,电流是线性续流状态,没有开关动作,此刻采样得到的电流最干净。
我采用的方案是:把ADC触发源配置为TIM1的更新事件,让ADC在PWM周期顶点自动触发注入组采样。ADC注入组配置为4个通道,按顺序采样三路电流和一路母线电压,每个通道之间有固定的采样保持时间,通过调整ADC的采样时间参数,确保整个采样窗口都落在低侧MOS全部导通的区间。
这里有个容易踩的坑:采样时刻如果稍微偏移到开关切换沿上,采出来的电流会有严重的毛刺。解决办法是在TIM1的CC4事件上做触发,通过CCR4寄存器值精确调节触发相位,把采样窗口平移到开关状态最稳定的区间。实测下来,采样相位偏移超过1.5微秒就可能导致电流波形明显变差,偏移3微秒以上时SMO基本没法收敛。
F103的ADC是12位,共4083个码值。如果你的电压范围是0到3.3V,那么1个LSB对应约0.8mV的电压,对应到10毫欧采样电阻上是80mA电流分辨率。这个分辨率对低速性能影响很大,如果你做的是小电流高精度的应用,建议用外部高精度运放把增益调大,或者在ADC采样时做多次平均,用时间换分辨率。
4.3 SVPWM的实现路径与选择
有很多人一提到SVPWM就头大,觉得扇区判断和矢量作用时间计算很复杂。其实工程里有一个等效的简易实现,效果和标准SVPWM几乎一样,但在代码上简单得多。
原理不复杂:SVPWM的实质是在三相正弦调制波上注入零序分量,让调制波在1/6基频周期内钳位在正负母线。等效的实现方式是,先由反Park变换得到三相正弦电压指令v_a、v_b、v_c,然后计算中点偏移:
offset = -(max(v_a, v_b, v_c) + min(v_a, v_b, v_c)) / 2
把offset分别加到三相电压指令上,再根据母线电压标定出占空比,写入TIM1的比较寄存器。就这么简单,效果和教科书里的七段式SVPWM完全等价,还能自动实现中点钳位,降低开关损耗。
这个实现方式有两个好处:一是没有扇区判断和三角函数查表,计算量小很多,适合F103;二是输出是三相互补的对称PWM,电流纹波小。我用这个方法替代标准SVPWM之后,CPU占用率直接下降了8%左右,电流波形没有任何可感知的劣化。
4.4 中断优先级、时序余量与浮点优化
F103的中断系统不支持分组抢占时随意嵌套,优先级配置要谨慎。我的做法很简单:TIM1更新中断(或者ADC注入组转换完成中断)设为抢占优先级0,也就是最高优先级;串口和外部信号设为1或2;速度环放在主循环里用节拍标志触发,不进中断。
这样做的原因是:电流环必须严格周期执行,哪怕被一个抢占打断一两个微秒,都会在电流波形上留下毛刺。把速度环放主循环,就算偶尔被电流中断打断,也不至于影响电流环的稳定。
浮点优化方面,F103没有FPU,float运算都是调用软浮点库函数完成的。我的经验是:
- 能提前算的常量全部在初始化时算好,不要在控制循环里重复计算。比如1/L、1/Vdc这种除法,每次循环算一次就是几十个周期的浪费。
- 尽量避免使用sinf、cosf这类带库调用的函数。角度转正弦余弦可以用查表加线性插值,精度足够,速度快好几倍。
- 开编译器最高级别优化,实测Keil O3比O0快25%左右。
- 如果还是觉得紧,可以考虑把SMO里的更新代码写成定点版本,用Q15格式表示电流和反电动势。定点化后的SMO在F103上循环耗时能缩短将近一半。
我最终量产版的电流环中断执行时间实测稳定在38微秒左右,16kHz周期里留了接近24微秒的裕量,稳得很。
5. 启动流程:对齐、强拖、切换的衔接自己不能乱
5.1 转子初始位置检测:为什么FOC启动前要先对齐
无感FOC在零速时没有反电动势,观测器拿不到任何位置信息,这就是业内说的“观测器零速盲区”。所以在启动之前,必须先想办法把转子位置确定下来。
最省事的办法是强制对齐:给电机施加一个固定的电压矢量,让d轴电流指令为恒定值,q轴电流指令为0。此时定子产生的磁场会把转子拉到一个已知的固定位置,这个位置就是你要的初始零度角。对齐过程一般持续几百毫秒,有没有位置传感器的情况下都适用。
对齐法的缺点是转子会转动一小段角度,如果系统要求严格,也可以用脉冲注入法:在多个方向上施加短暂的电压脉冲,通过检测电流响应的幅度差异来估算转子位置。但这个办法对采样精度要求高,实现复杂度更高,我实测下来,百分之九十的场合强制对齐完全够用。
对齐过程中有一个细节:对齐电流不能太大,否则启动力矩会把转子猛地拽过去,造成机械冲击;也不能太小,否则在摩擦负载比较大的场合可能对不齐。我一般取额定电流的30%到50%,对齐时间为300到500毫秒,通过电流闭环让转子平滑地转到目标位置。
5.2 开环强拖参数怎么给
对齐结束后,转子停在零度位置,但还不会转。接下来需要开环强拖:让电流矢量的角度从零开始匀速递增,转子就会被旋转磁场“拖”着转起来。
开环强拖有两个关键参数:电流幅值和角度加速度。电流幅值取值参考电机额定电流,一般从50%到100%之间;角度加速度决定了转子能不能跟得上。加速度太慢,启动时间长;太快,转子惯性跟不上,容易丢步,表现为电机发出明显的顿挫声甚至不转。
我的启动流程是:先让电流矢量在一个固定角度停留100毫秒左右,防止对齐结束后立即加速导致瞬时冲击;然后以恒定的电角加速度斜坡加速,加速时间根据目标转速设定,比如在200毫秒内从0加速到额定转速的10%,然后等待速度环接管。
这里有个重要技巧:开环强拖阶段,SMO观测器要持续运行,但它的输出不参与控制。我们利用这段时间让观测器逐渐收敛,同时可以内部比较开环角度和估计角度的偏差。当转速上升到反电动势足够大的区域时,角度偏差会逐渐减小,这就是切换闭环的依据。
5.3 闭环切换的判断条件与平滑过渡技巧
开环强拖切换到闭环FOC是整个启动流程里最容易出问题的一步。切快了,观测器角度还不准,电流环把转矩方向弄错,电机会猛震一下;切慢了,开环电流角度和真实位置偏差越来越大,切换瞬间一样会有冲击。
我的判断条件有两个,必须同时满足:
- 转速高于某个阈值,比如额定转速的8%到10%,确保反电动势够大,观测器估计可靠。
- 估计角度与开环角度的偏差连续一段时间稳定在10度以内。
满足条件后,切换也不是硬切。我用的平滑过渡方法:在切换后200毫秒内,实际控制角度从开环角度线性过渡到估计角度,过渡系数从0慢慢涨到1。转速环的给定也逐步从当前开环速度斜坡到大目标速度,避免给速度环一个阶跃指令导致电流突变。
切换完成后如果有轻微的声音变化或电流尖峰,属于正常现象;但如果出现转速掉回零或者电机剧烈抖动,大概率是切换时刻角度偏差太大,建议把第一个切换条件放松到更低转速,或者加快开环到闭环的角度过渡时间。
6. 调参实战:从乱震到稳转的完整过程
6.1 电流环PI参数计算与实测对比
电流环PI参数有两种标定思路:理论计算和实测法。理论计算很简单,基于电机的电时间常数做极点对消。对于表贴式电机,d轴和q轴的电感、电阻相同,电流环PI可以写成:
Kp = L · ω_c
Ki = R · ω_c
其中ω_c是电流环的期望带宽,单位弧度每秒。想跑到1kHz带宽,ω_c取2π×1000约6283。假设电机电感1.2mH,电阻0.5Ω,那么:
Kp = 1.2e-3 × 6283 ≈ 7.54
Ki = 0.5 × 6283 ≈ 3141
这个结果是理想电机模型下的初始值,电压单位是伏,电流单位是安培,实际数字会根据你的坐标变换系数和ADC标定有细微差别。
我实测的建议是:先把Ki设成理论值的70%左右,Kp保持不变;运行后观察q轴电流的阶跃响应,超调大就降Kp,稳态误差大就加Ki。反复几次就能找到手感。记住一个原则:电流环宁可响应慢一点也不能有超调,因为速度环在前面会用到电流给定的微分,电流环超调会放大成速度抖动。
6.2 观测器参数的“药效”与“副作用”
SMO的参数有三个,各管一件事,但互相关联。
第一个是滑模增益K。K太小,滑模失效,观测电流跟踪不上实测电流,角度估计出现周期性的飘移;K太大,抖振严重,角度估计高频抖动,电流波形上出现低频毛刺。理想的K应该刚好满足反电动势幅值上界,留少量余量。
第二个是低通滤波器系数lpf_coef。这个系数影响反电动势的平滑程度,太小滤波太强,反电动势被严重滞后,角度滞后也跟着变大;太大滤波不足,抖振残留明显。lpf_coef和PWM频率相关,通常取0.05到0.2之间,需要配合调试。
第三个是PLL带宽,我用的PLL方案里PI参数决定带宽。PLL带宽越高,角度跟踪越快,但抗噪能力越差;带宽越低,角度平滑,但动态响应慢。我调试时先放开PLL带宽,确保动态跟得上,再逐步降低直到角度抖动可接受。
这三者的调试顺序我建议是:先定K,让观测器收敛;再调LPF,让反电动势波形平滑;最后压PL带宽抑制剩余噪声。每调一步都通过串口把估计角度和开环角度放出来看,不要直接靠耳朵听。
6.3 几个典型故障波形与排查路径
我把调试中遇到频率最高的几类故障现象整理成了一张表,方便排查时对照:
| 现象 | 可能原因 | 排查方向 |
|---|---|---|
| 启动时电机抖动一下但不动 | 对齐电流过小,转子没被拉到固定位置 | 增大对齐电流,延长对齐时间 |
| 开环强拖时电机发出嗡嗡声且不转 | 角度加速度过大,转子丢步 | 降低加速度,增大开环电流,在启动初期加更长的静止停留 |
| 切换到闭环瞬间电流尖峰 | 切换时刻角度偏差大或过渡速度过快 | 检查切换条件,加长角度过渡时间,提前切换点 |
| 空载运行平稳,带载时抖动 | K偏小或PLL带宽不足,负载扰动下观测器失步 | 增大K,提高PLL带宽 |
| 高速时电流波形畸变且啸叫 | 低通滤波引起的角度滞后过大 | 提高LPF截止频率,或加角度滞后补偿 |
| 油门稳定时转速缓慢波动 | 速度环比例太小或积分太慢 | 增加速度环Ki,检查速度反馈滤波是否过度 |
| ADC电流波形上有规律毛刺 | 采样窗口覆盖到了开关切换边沿 | 微调ADC触发相位,检查采样时间窗口 |
高速时的角度滞后补补偿值得单独说一下。LPF在提取反电动势时引入的相位滞后随转速增加而增大,如果无视它,角度估计永远比真实位置超前或滞后(取决于坐标变换方向约定),导致电流矢量和反电动势不再垂直,浪费转矩,还容易失步。简单的补偿方法是在估计角度上叠加一个随转速变化的补偿角:
θ_comp = θ_est + K_comp · ω_est
K_comp 的取值用实测法标定:在额定转速下,逐步增大补偿角直到电流电流幅值最小,因为此时磁场定向最准。
6.4 低成本调试环境怎么搭
没有高端设备也能调试无感FOC,我整套开发环境加起来不超过三百块钱,基本就是一台逻辑分析仪加一个便宜示波器。
示波器主要看两种信号:PWM开关节点波形,用来检查死区设置和开关是否正常;电流采样点波形,用来确认采样时刻是否正确。这两类波形都是低频触发就能看清楚的,不需要高带宽示波器。存储示波器调到单次触发模式,捕捉启动瞬间的暂态波形,能发现很多稳态下隐藏不了的问题。
逻辑分析仪用来抓控制器的内部变量。把FOC控制循环里的关键变量通过串口以文本格式输出,或者用DMA打包成二进制帧加时间戳,逻辑分析仪解码后就能在电脑上画出波形。比如把估计角度、开环角度、电流环输出同时打出来,切换闭环瞬间的突变一目了然。
串口输出的频率不用太高,1kHz到2kHz够看大多数问题了。注意串口输出代码不要放在电流环中断里,否则会严重干扰控制时序,正确做法是放到主循环里,用节拍标志控制输出频率,某几个控制变量存在环形缓冲区里,由主循环定时取出发送。
调试器方面,ST-Link V2就行,能把SMO的内部状态实时读出来。我给SMO结构体里专门加了一个调试字段,记录最近几拍的观测器估算误差,这样即使电机已经停了,也能回看最后几拍到底发生了什么,定位问题快很多。