FOC电流环程序实现:从采样时刻到PI整定的PMSM调试实战
1. 从"升魂浩荡"说起:这套FOC电流环到底在解决什么问题
第一次看到"升魂浩荡"这四个字,我以为是哪个游戏里的技能名。后来跟几个做电控的朋友聊,才反应过来这是圈子里对那种"电流环一跑起来,电机声音顺滑得像换了个灵魂"的戏称。说白了,就是FOC(磁场定向控制)里电流环调得好,整个驱动系统的动态响应和噪声表现会有质的飞跃。
这篇东西不讲虚的,就围绕PMSM(永磁同步电机)的FOC电流环程序实现来展开。适合谁看?如果你正在用STM32或者类似MCU写FOC代码,电流环PI参数整定总是靠试凑,或者Clarke/Park变换写完了但不知道采样时刻怎么对齐,那这篇就是给你准备的。如果你只是听说过FOC但没动过手,也能从里面搞清楚电流环在整个控制链路里到底扮演什么角色。
先给一个最朴素的认知框架:FOC的核心思想是把三相交流电机的定子电流,通过坐标变换解耦成两个直流量——d轴电流(励磁分量)和q轴电流(转矩分量)。解耦之后,控制交流电机就像控制直流电机一样直观。而电流环就是这套解耦控制的最内环,它直接决定了对电流指令的跟踪速度和精度。电流环跑不好,外面的速度环、位置环全是空中楼阁。
我见过太多人把FOC的电流环当成"调个PI就完事"的东西,结果电机一转起来要么啸叫,要么响应迟钝,要么低速抖动。问题往往不在PI参数本身,而在于采样时机、解耦补偿、限幅策略、以及程序执行时序这些细节上。下面我按实际调试中会遇到的顺序,把电流环程序从原理到落地拆一遍。
2. 电流环在FOC链路里的位置与采样时刻的致命细节
2.1 三环嵌套中电流环为什么必须最快
FOC的典型控制结构是电流环(最内环)→ 速度环(中间环)→ 位置环(最外环)。电流环的带宽通常要求是速度环的5到10倍,速度环又是位置环的5到10倍。这个倍数关系不是随便定的,它来自控制理论里"内环必须比外环快得多,才能把内环近似成外环的一个比例环节"这个基本原则。
具体到数字实现,假设PWM开关频率是10kHz,那电流环的控制周期就是100微秒。速度环可能跑1kHz(1毫秒),位置环可能跑100Hz到500Hz。电流环在每个PWM周期都要执行一次完整的ADC采样→Clarke变换→Park变换→PI运算→反Park变换→SVPWM输出这条链路。这条链路的执行时间必须严格小于PWM周期,否则整个控制时序就崩了。
我在STM32G070上实测过,用C语言写的浮点版本,这条链路大概要30到40微秒。如果用定点或者用硬件FPU加速,能压到15微秒以内。这个时间余量决定了你能把开关频率推到多高。
2.2 ADC采样时刻:为什么必须在PWM中点触发
这是电流环程序里最容易踩坑的地方,没有之一。ADC采样时刻必须对齐到PWM周期的中点,也就是下桥臂全部导通、电流在采样电阻上稳定流动的那个时刻。
原因很直接:在中心对齐PWM模式下,一个周期内上桥臂先导通再关断,电流在开关瞬间会有振铃和尖峰。如果你在开关动作附近采样,采到的值全是噪声。只有在PWM周期的中点,也就是计数器到达峰值或者谷值的时候,三相下桥臂同时导通,电流通过采样电阻续流,这时候的电流值才最接近真实的相电流平均值。
具体操作上,用STM32的高级定时器(比如TIM1)产生中心对齐PWM,把ADC的触发源配置成定时器的更新事件或者比较事件,确保触发点落在计数器峰值处。我一般用TIM1的CH4比较事件来触发ADC,把CCR4的值设成ARR的一半,这样触发点就精确落在PWM中点。
注意:如果你用的是单电阻采样,采样时刻还要考虑电流重构的问题,一个PWM周期内可能需要多次采样。三电阻采样就简单得多,在PWM中点采一次就行。
2.3 采样到执行的延迟补偿
从ADC采样到SVPWM输出,中间有一个PWM周期的延迟(采样在周期中点,但新的占空比要到下一个周期才生效)。这个延迟在电流环里相当于一个纯滞后环节,会吃掉相位裕度。高速运行时,这个延迟可能导致电流环振荡。
补偿的办法有两种:一是在Park变换时用预测角度,也就是把转子角度往前推1.5个PWM周期;二是在PI输出后加一个超前补偿。我一般用第一种,实现简单,效果也够用。具体做法是:如果当前电角度是θ,电角速度是ω,那Park变换用的角度就是θ + ω × 1.5 × Tpwm。这个补偿在高速时特别明显,低速时可以忽略。
3. Clarke、Park与反Park:程序里怎么写才不出错
3.1 Clarke变换的等幅值形式与系数陷阱
Clarke变换把三相电流ia、ib、ic变成两相静止坐标系下的iα、iβ。程序里最常用的等幅值形式是:
i_alpha = ia; i_beta = (ia + 2 * ib) / sqrt(3);这里有个坑:很多教材用的是等功率形式,系数里带根号2/3,跟等幅值形式混用会导致PI参数整定出来完全不对。等幅值形式下,电流幅值不变,但功率不守恒;等功率形式下,功率守恒但幅值变了。我建议统一用等幅值形式,因为电流环的给定值直接来自速度环输出,用等幅值更直观。
还有一个细节:三相电流之和理论上为零,所以只需要采两相就能算出第三相。但实际中由于采样误差和电机不对称,ia+ib+ic不一定严格为零。我一般还是采三相,然后做一下零序抑制,把三相电流减去它们的平均值,这样能消除共模干扰。
3.2 Park变换的角度来源与对齐
Park变换把iα、iβ旋转到转子坐标系下的id、iq:
id = i_alpha * cos(theta) + i_beta * sin(theta); iq = -i_alpha * sin(theta) + i_beta * cos(theta);这里的theta是转子电角度,必须和电机的实际磁极位置对齐。如果角度有偏差,id和iq就会耦合,表现为id不为零、iq跟踪不上给定值。
角度来源分有感(带编码器或霍尔)和无感(用观测器估算)两种。有感的情况下,编码器安装偏差需要做角度自学习:给d轴通一个固定电流,让转子转到d轴对齐位置,然后读编码器值作为零偏。无感的情况下,角度来自滑模观测器或者龙伯格观测器,初始位置检测是另一个大话题,这里不展开。
提示:调试时可以先强制theta=0,给id一个固定值,看iq是否接近零。如果iq明显不为零,说明角度对齐有问题。
3.3 反Park变换与SVPWM的衔接
PI运算输出的ud、uq经过反Park变换回到αβ坐标系:
u_alpha = ud * cos(theta) - uq * sin(theta); u_beta = ud * sin(theta) + uq * cos(theta);然后uα、uβ送给SVPWM模块生成六路PWM。这里要注意电压限幅:SVPWM的线性调制区最大输出电压是Vdc/√3(相电压幅值)。如果ud、uq算出来的合成矢量超过这个值,就会进入过调制区,波形失真。我一般在反Park之前做圆限幅,把uα、uβ的模值限制在Vdc/√3以内,保持角度不变。
4. 电流环PI整定的实操逻辑与解耦补偿
4.1 从电机参数算出PI初值
电流环的PI参数不是盲调出来的,可以从电机参数算出一个合理的初值。d轴和q轴的被控对象近似为一阶惯性环节:
- d轴:R + sLd
- q轴:R + sLq
其中R是定子电阻,Ld、Lq是dq轴电感。按照零极点对消的方法,PI控制器的零点设成被控对象的极点,也就是:
- Kp_d = Ld × ωc
- Ki_d = R × ωc
- Kp_q = Lq × ωc
- Ki_q = R × ωc
其中ωc是期望的电流环带宽,一般取PWM角频率的1/10到1/5。比如10kHz开关频率,ωc取2π×1000 rad/s左右。
这样算出来的PI参数,理论上能让电流环的闭环传递函数变成一个一阶惯性环节,带宽就是ωc。实际中由于延迟和采样误差,带宽要打点折扣,但作为初值非常靠谱。
4.2 交叉耦合项的解耦补偿
PMSM的dq轴电压方程里有交叉耦合项:
- ud = R×id + Ld×did/dt - ωe×Lq×iq
- uq = R×iq + Lq×diq/dt + ωe×Ld×id + ωe×ψf
其中ωe是电角速度,ψf是永磁体磁链。-ωe×Lq×iq和+ωe×Ld×id这两项就是交叉耦合,它们让d轴和q轴互相影响。如果不管这两项,电流环在高速时会出现明显的耦合振荡。
解耦补偿的做法很简单:在PI输出上直接加上这两项的前馈:
ud_ref = pid_d_out - omega_e * Lq * iq; uq_ref = pid_q_out + omega_e * Ld * id + omega_e * psi_f;这样就把耦合项抵消掉了,d轴和q轴可以独立控制。我在实际项目里,低速时解耦补偿可以不加,但转速超过额定转速的20%以后,不加解耦补偿电流环就开始抖了。
4.3 抗积分饱和与限幅策略
PI控制器必须有抗积分饱和机制。当电压输出达到限幅值时,积分器不能再继续累积,否则一旦误差反向,积分器需要很长时间才能退饱和,表现为电流响应迟钝。
我常用的做法是反计算抗饱和:当输出饱和时,把积分器的输入减去一个与饱和量成比例的值。具体实现:
if (u_out > u_max) { u_out = u_max; integral -= (u_out_raw - u_max) * Ki_anti; } else if (u_out < -u_max) { u_out = -u_max; integral -= (u_out_raw + u_max) * Ki_anti; }其中Ki_anti是抗饱和增益,一般取Ki的0.5到1倍。这个机制在电机启动和突加负载时特别重要,没有它,电流环会表现出明显的过冲和恢复延迟。
5. 程序时序与中断优先级:那些让电流环崩溃的隐藏问题
5.1 电流环中断里绝对不能做的事
电流环中断服务函数(ISR)必须短小精悍。我见过有人在电流环ISR里做串口打印、做浮点除法、甚至调用printf,结果PWM周期根本跑不满,电流环时序全乱。
电流环ISR里只做这几件事:读ADC值、做Clarke/Park、跑PI、做反Park、更新PWM比较寄存器。其他所有事情——速度环计算、位置环计算、通信、故障处理——全部放到主循环或者低优先级中断里。
注意:如果用了RTOS,电流环ISR的优先级必须是最高的,而且不能调用任何可能阻塞的RTOS API。
5.2 中断优先级与ADC触发时序的配合
STM32的ADC触发和定时器中断之间有时序配合问题。如果ADC触发和定时器更新中断同时发生,中断响应可能会延迟ADC读取,导致采到的值不是PWM中点时刻的。解决办法是用定时器的比较事件触发ADC,而不是更新事件,并且把ADC转换完成中断的优先级设得比定时器更新中断高。
我一般这样配置:TIM1的CH4比较事件触发ADC,ADC转换完成产生DMA请求,DMA把数据搬到内存,DMA传输完成中断里执行电流环计算。这样整条链路都是硬件触发,CPU只负责计算,时序最稳。
5.3 浮点运算的时间预算
如果你的MCU没有硬件FPU(比如STM32F0系列),浮点运算会非常慢。一次sin/cos查表加插值大概要几微秒,一次浮点乘法要几十个时钟周期。这种情况下,电流环必须用定点运算,把电流和电压都归一化成Q格式。
即使有FPU(比如STM32F4、G4系列),也要注意sin/cos的计算。我一般用查表加线性插值,表长1024点,精度足够,速度比调用math.h的sinf快好几倍。
6. 实测中遇到的典型问题与排查路径
6.1 电流波形有尖刺:先查采样时刻再查硬件
电机运行时用示波器看相电流,如果波形上有周期性的尖刺,第一反应是采样时刻不对。把ADC触发点从PWM边沿移到中点,尖刺一般就消失了。
如果移到中点还有尖刺,那就要查硬件:采样电阻的走线是不是太长、运放带宽够不够、RC滤波截止频率是不是太高。我遇到过一次,采样电阻到运放的走线有10厘米长,引入了大量开关噪声,后来把运放直接放在采样电阻旁边就好了。
6.2 电流跟踪不上给定:从PI限幅和母线电压找原因
给定iq=5A,实际iq只能到3A,怎么调PI都没用。这种情况先查电压限幅:如果母线电压只有24V,电机反电动势在高速时已经接近24V,那电流环根本没有足够的电压余量去跟踪给定。这时候要么降低转速,要么提高母线电压。
如果电压余量够,那就查PI输出限幅是不是设得太小。我见过有人把PI输出限幅设成母线电压的一半,结果高速时电流根本推不上去。
6.3 低速时电流抖动:角度精度和死区补偿
低速时电流抖动,尤其是无感FOC,大概率是角度估算精度不够。滑模观测器在低速时反电动势很小,估算角度噪声大。解决办法是低速时切换到高频注入或者I/F启动,等转速起来再切回观测器。
另外,死区补偿没做好也会导致低速电流抖动。逆变器上下桥臂的死区时间会导致输出电压偏差,低速时这个偏差占比很大。我一般根据电流方向给占空比加一个固定的补偿量,正电流加、负电流减,能明显改善低速波形。
6.4 高速时电流环振荡:延迟补偿和解耦
高速时电流环振荡,先查采样到执行的延迟补偿有没有加。如果没加,把Park变换的角度往前推1.5个PWM周期试试。如果加了还振荡,查解耦补偿是不是符号搞反了。解耦项的符号跟电机参数和坐标变换方向有关,搞反了会加剧耦合而不是消除耦合。
7. 代码框架与关键函数实现参考
7.1 电流环ISR的整体骨架
下面是一个基于STM32 HAL库的电流环ISR骨架,用DMA搬运ADC数据,在DMA传输完成中断里执行:
void DMA1_Channel1_IRQHandler(void) { if (DMA1->ISR & DMA_ISR_TCIF1) { DMA1->IFCR = DMA_IFCR_CTCIF1; // 1. 读取三相电流 ia = adc_buf[0] * current_scale; ib = adc_buf[1] * current_scale; ic = adc_buf[2] * current_scale; // 2. Clarke变换 i_alpha = ia; i_beta = (ia + 2*ib) * ONE_BY_SQRT3; // 3. 读取电角度(带延迟补偿) theta = encoder_theta + omega_e * 1.5f * TPWM; // 4. Park变换 sin_t = sin_lookup(theta); cos_t = cos_lookup(theta); id = i_alpha * cos_t + i_beta * sin_t; iq = -i_alpha * sin_t + i_beta * cos_t; // 5. PI运算(含解耦和抗饱和) pid_d(&pid_id, id_ref, id, &ud); pid_q(&pid_iq, iq_ref, iq, &uq); ud -= omega_e * Lq * iq; uq += omega_e * Ld * id + omega_e * psi_f; // 6. 反Park变换 u_alpha = ud * cos_t - uq * sin_t; u_beta = ud * sin_t + uq * cos_t; // 7. SVPWM输出 svpwm(u_alpha, u_beta, vdc); } }这个骨架里,每一步都有前面讲的细节:Clarke用等幅值、Park用补偿角度、PI带解耦和抗饱和、SVPWM前做圆限幅。
7.2 PI控制器的结构体实现
typedef struct { float Kp; float Ki; float integral; float out_max; float out_min; float anti_gain; } PI_Controller; float pi_calc(PI_Controller *pi, float ref, float fdb) { float err = ref - fdb; float out = pi->Kp * err + pi->integral; float out_raw = out; if (out > pi->out_max) { out = pi->out_max; pi->integral -= (out_raw - pi->out_max) * pi->anti_gain; } else if (out < pi->out_min) { out = pi->out_min; pi->integral -= (out_raw - pi->out_min) * pi->anti_gain; } else { pi->integral += pi->Ki * err; } return out; }这个实现里,积分器只在输出不饱和时才累积,饱和时用反计算退饱和。anti_gain一般取Ki的0.5到1倍。
7.3 查表法sin/cos的实现
#define TABLE_SIZE 1024 float sin_table[TABLE_SIZE]; void sin_table_init(void) { for (int i = 0; i < TABLE_SIZE; i++) { sin_table[i] = sinf(2.0f * PI * i / TABLE_SIZE); } } float sin_lookup(float theta) { // 归一化到[0, 2π) while (theta < 0) theta += 2*PI; while (theta >= 2*PI) theta -= 2*PI; float idx_f = theta * TABLE_SIZE / (2*PI); int idx = (int)idx_f; float frac = idx_f - idx; int idx_next = (idx + 1) % TABLE_SIZE; return sin_table[idx] + frac * (sin_table[idx_next] - sin_table[idx]); } float cos_lookup(float theta) { return sin_lookup(theta + PI/2); }查表加线性插值,精度足够电流环用,速度比调用sinf快很多。表长1024点,在STM32G4上一次查表大概0.5微秒。
8. 从能跑到跑好:几个提升电流环品质的进阶技巧
8.1 电流环带宽的实测方法
想知道你的电流环带宽到底是多少,可以给iq一个阶跃给定,用示波器或者DAC输出实际iq的波形,看上升时间。带宽约等于0.35除以上升时间。比如上升时间1毫秒,带宽大概350Hz。
如果实测带宽远低于设计值,检查这几个地方:PWM频率是不是够高、ADC采样延迟是不是太大、PI参数是不是被限幅了、解耦补偿是不是没加。
8.2 弱磁区的电流环处理
电机转速超过基速以后,需要弱磁来扩展转速范围。弱磁的本质是给d轴一个负电流,抵消永磁体磁链,降低反电动势。这时候电流环的d轴给定不再是零,而是负值。
弱磁区的电流环要注意电压限幅和电流限幅的协调。d轴和q轴电流的合成矢量不能超过逆变器容量和电机额定电流。我一般用电压椭圆和电流圆的交点来算d轴和q轴的给定值,保证在弱磁区也能稳定运行。
8.3 参数辨识与在线自适应
电机参数(R、Ld、Lq、ψf)会随温度变化,导致PI参数和解耦补偿失配。高端应用里会做在线参数辨识,用递推最小二乘法或者模型参考自适应来实时更新参数。
对于大多数工业应用,离线辨识加温度补偿就够了。我一般会在电机冷态和热态各测一次R和ψf,然后根据温度传感器做线性插值。Ld和Lq随温度变化不大,可以固定。
8.4 电流环的频域验证
有条件的话,用频率响应分析仪测一下电流环的闭环波特图。看幅频特性在带宽处的下降斜率是不是-20dB/dec,相位裕度是不是大于45度。如果相位裕度不够,减小Kp或者增大Ki;如果带宽不够,增大Kp。
没有频响仪的话,可以用白噪声注入加FFT分析,也能得到大致结果。这个方法在MATLAB里很容易实现,把实际电流和给定电流的频谱做比值就行。
9. 一些零散但重要的经验
调试电流环的时候,先开环再闭环。开环给固定占空比,看电流波形对不对,确认采样和变换没问题了,再闭合电流环。我见过有人直接上闭环,结果电流环一跑就炸,查了半天发现是Clarke变换的系数写错了。
示波器是必须的。看电流波形、看PWM波形、看采样触发信号,没有示波器调电流环就是盲人摸象。我一般用四通道示波器,一路看相电流、一路看PWM、一路看ADC触发、一路看DAC输出的iq实际值。
记录每一次参数修改。电流环调试是个反复迭代的过程,今天调好的参数明天可能就忘了为什么这么设。我习惯用表格记录每次修改的PI参数、对应的波形表现、以及修改理由,回头查的时候一目了然。
不要迷信仿真。MATLAB/Simulink里跑得再好,实际硬件上由于延迟、噪声、死区、参数偏差,表现可能完全不一样。仿真用来验证算法逻辑,实际参数必须在硬件上调。
温度对电流环的影响。电机冷态和热态的电阻差可能到30%以上,如果PI参数是按冷态整定的,热态时电流环带宽会明显下降。工业应用里要么做温度补偿,要么把PI参数整得保守一点,保证全温度范围内都稳定。
不同电机的电流环参数不能通用。即使功率相同,不同厂家的电机电感可能差一倍。换电机必须重新整定电流环,至少要把PI参数按新电机的R和L重新算一遍。
注意电流传感器的量程和偏置。电流传感器的偏置会直接导致id、iq有直流分量,表现为电机发热和转矩脉动。上电时要做偏置校准,把电机关掉,采几百次电流值取平均作为零偏。
SVPWM的死区和最小脉宽。死区时间一般设1到2微秒,太大影响低速性能,太小可能直通。最小脉宽限制是为了保证自举电容能充电,一般设1微秒左右。这两个参数在SVPWM模块里要处理好,否则低速时波形会畸变。
电流环的启动策略。电机启动时,如果直接给iq阶跃给定,电流会过冲。我一般用斜坡给定,让iq在几十毫秒内从零升到目标值,这样启动更平滑,对电流环的冲击也小。
故障保护要独立于电流环。过流保护不能只靠电流环的限幅,必须有独立的硬件比较器或者快速软件保护,在电流超过阈值时直接关断PWM。电流环的限幅是控制手段,不是保护手段。
代码优化的小技巧。把常用的系数(比如1/√3、2/√3)定义成宏或者const变量,避免重复计算。把sin/cos查表的索引计算用位运算代替除法(表长取2的幂次)。把PI控制器的结构体放在RAM里,避免频繁访问Flash。
调试用的DAC输出。STM32的DAC可以用来实时输出id、iq、theta等变量,用示波器看非常方便。我一般把DAC1输出iq实际值,DAC2输出iq给定值,两个波形一对比,跟踪性能一目了然。
电流环和速度环的配合。速度环的输出是iq给定,速度环的带宽要明显低于电流环。如果速度环带宽接近电流环,两个环会互相干扰,表现为转速振荡。我一般把速度环带宽设成电流环的1/5到1/10。
无感FOC的电流环特殊性。无感FOC的角度来自观测器,观测器的噪声会直接进入电流环。所以无感FOC的电流环带宽一般比有感低一些,PI参数也要更保守。另外,无感FOC在低速时观测器不准,电流环的id、iq会有较大脉动,这是正常现象,不要试图用PI参数去消除。
电流环的离散化方法。连续域的PI控制器要离散化才能在实际中实现。我一般用后向差分,积分项写成integral += Ki * err * Ts,微分项一般不用(电流环PI就够了,不需要D)。离散化会引入额外的相位延迟,所以实际带宽会比设计值低一些。
母线电压波动的影响。SVPWM的输出电压和母线电压成正比,如果母线电压波动,同样的占空比对应的实际电压就变了。我一般会在SVPWM里做母线电压前馈,把占空比除以实际母线电压,这样母线波动就不会影响电流环。
电流环的启动顺序。上电后先做电流传感器偏置校准,然后初始化PWM和ADC,再使能电流环中断,最后才给电流环使能信号。顺序错了可能导致启动瞬间电流冲击。
不同PWM模式的影响。中心对齐PWM比边沿对齐PWM的谐波性能好,但中心对齐模式下ADC触发时刻更讲究。我一般用中心对齐,配合定时器比较事件触发ADC。
电流环的调试工具。除了示波器,我还会用串口或者CAN把电流环的内部变量传到上位机,用Python或者MATLAB画波形。这样能看到示波器看不到的细节,比如PI积分器的累积过程、解耦补偿的实时值。
电流环的鲁棒性测试。调好参数后,要做突加突卸负载测试,看电流环的恢复时间和过冲。还要做转速阶跃测试,看电流环在转速变化时的跟踪性能。这些测试能暴露PI参数和解耦补偿的不足。
电流环的噪声抑制。电流采样噪声会直接进入PI控制器,导致输出电压抖动。我一般会在ADC采样后加一个一阶低通滤波,截止频率设成电流环带宽的5到10倍。滤波会引入相位延迟,所以截止频率不能太低。
电流环的启动电流限制。电机启动时,如果iq给定太大,电流会超过逆变器容量。我一般会设一个启动电流限幅,让iq给定在启动阶段不超过额定电流的1.5倍,等转速起来再放开。
电流环和MTPA的配合。对于凸极电机(Ld不等于Lq),存在最大转矩电流比(MTPA)的工作点,也就是同样的转矩下电流最小。MTPA会给d轴一个负电流,这时候电流环的d轴给定不再是零。MTPA的公式是id = (ψf - sqrt(ψf^2 + 4*(Lq-Ld)^2iq^2)) / (2(Lq-Ld)),实际中一般用查表法实现。
电流环的弱磁和MTPA切换。低速时用MTPA,高速时用弱磁,中间需要一个平滑的切换策略。我一般用电压反馈法,当电压利用率超过某个阈值时,逐渐增加d轴负电流,直到电压回到阈值以内。
电流环的过调制处理。当电压给定超过SVPWM线性区时,进入过调制。过调制会导致电流波形失真,但能提高电压利用率。我一般会在过调制区做电压矢量角度保持、幅值限幅,保证波形尽量不失真。
电流环的容错控制。如果一相电流传感器故障,可以用另外两相重构第三相。如果两相故障,就只能停机。容错控制需要额外的故障检测和重构逻辑,一般工业应用里不做,但高端应用里会有。
电流环的EMC考虑。PWM开关会产生EMI,可能干扰电流采样。我一般会在采样电阻两端加RC滤波,在运放输入端加共模扼流圈,在PCB布局上让采样走线尽量短、尽量远离功率走线。
电流环的热设计。电流环本身不发热,但电流环控制的电流会导致功率器件发热。如果电流环带宽太高,开关损耗会增加。我一般会在效率和带宽之间做折中,开关频率取10kHz到20kHz,电流环带宽取1kHz到2kHz。
电流环的标准化。不同项目的电流环代码应该尽量标准化,把电机参数、PI参数、限幅值都做成可配置的宏或者结构体。这样换电机时只需要改配置,不用改代码。我一般会把电流环封装成一个模块,对外只暴露初始化、使能、给定设置这几个接口。
电流环的版本管理。电流环代码的每次修改都要用Git管理,commit信息写清楚改了什么、为什么改、实测效果如何。这样出问题可以回退,也能积累经验。
电流环的文档。每个项目的电流环参数都要写文档,记录电机型号、参数、PI值、实测波形、调试过程。下次遇到类似电机,可以直接参考,省很多时间。
电流环的持续学习。FOC电流环的技术在不断发展,新的观测器、新的调制策略、新的参数辨识方法层出不穷。我一般会关注几个电控领域的会议和期刊,看看有没有新的思路可以借鉴。
电流环的实践社区。国内做电控的圈子不大,但有几个活跃的论坛和微信群,里面有很多实战经验。遇到搞不定的问题,去社区里问问,往往能得到意想不到的提示。
电流环的调试心态。电流环调试是个耐心活,有时候一个参数改一点,波形就完全不一样。不要急,一步一步来,每次只改一个参数,记录波形,分析原因。调好了之后,那种电机顺滑运转的声音,确实配得上"升魂浩荡"这四个字。