简介:基于28335的电机FOC控制工程源码包,面向电机驱动、嵌入式控制和电力电子相关开发人员,定位为基于TI TMS320F28335实现FOC+SVPWM控制策略的完整参考工程。压缩包共135个文件、1.25MB,主要包含DSP2833x标准库的C源文件与头文件,用于启动初始化的ASM汇编代码,链接配置CMD文件,GEL初始化脚本以及算法库等。已有2171人学习,读者可参照其中完整的FOC软件包结构,快速掌握28335平台下的电机控制开发要点。包内代码层次清晰、模块划分明确,电流环与速度环的PI参数配置、Clarke/Park坐标变换和SVPWM开关序列生成等关键模块均可对照硬件外设进行验证,适合进行算法二次开发和调试排错,既为入门者提供可直接运行的样例,也为进阶开发者提供定制化修改的骨架。此外,包内文件相互关联清晰,方便在CCS中建立工程并单步跟踪关键中断服务程序,有助于建立对FOC实际工程实现的整体认识。 做电机控制的这些年,绕不开TI的C2000系列,特别是TMS320F28335。这颗芯片算是实验室里的常青树了,我做FOC(磁场定向控制)项目时,第一套能稳定转起来的系统就是用28335搭的。后台也经常有人问:28335的PWM死区寄存器DBFED、DBRED到底怎么配?主源选择有要求吗?电流采样为什么要放下桥?Clarke变换为什么只采两相电流?这些问题其实都是FOC落地时最容易被绊住的点。这篇文章就围绕“基于28335的电机FOC控制”这条线,把我实际调试中的思路、配置和踩坑记录都整理出来,给正准备上手的同学当一份参考。
1. 为什么大家都拿28335做FOC
1.1 28335这颗DSP到底强在哪
先聊芯片选型。现在做电机控制的方案很多,STM32、国产MCU、FPGA都能跑FOC,但28335在中小功率电机驱动项目里依然有不可替代的位置。核心原因有三个:150MHz主频、硬件浮点单元(FPU)、完整的外设组合。FOC算法本身运算量不算小,电流环如果跑到20kHz,一个周期里要做Clarke变换、Park变换、两个PI调节器、SVPWM,还要处理速度环和转子位置估算。如果是定点芯片,所有小数都得做Q格式换算,光是处理溢出和精度问题就能让人头大。28335是浮点DSP,直接用float写PI指令,省掉大量移植和调试成本。
外设方面,28335的ePWM模块可以生成带死区的互补PWM,12位ADC支持多通道同步采样,还有编码器接口、QEP等模块。做FOC需要的“高频PWM+同步ADC采样+角度反馈”这三件事,它都能用硬件完成,不占用CPU太多资源。相比用通用MCU靠定时器中断模拟PWM和采样时序,28335的开发体验明显顺滑。当然现在也有更新的芯片,但28335的例程、技术文档、参考设计最多,碰到问题能找到的答案也最多,对新手相当友好。
1.2 FOC系统的整体框架与三环考虑
FOC这套东西听着玄乎,本质就是把三相交流电机的控制问题,通过坐标变换,变成类似直流电机的控制问题。28335在系统里的角色是核心控制器:采集电流和转子位置,运行FOC算法,输出六路PWM驱动三相逆变器。整个控制结构从外到内通常分三层——位置环、速度环、电流环,也就是常说的三环。位置环在最外面,输出速度给定;速度环在中间,输出电流给定;电流环在最里面,直接控制电机绕组电流。
电流环是FOC的根基,电流环带宽要足够高,才能让实际电流快速跟随给定值,一般放在PWM中断里跑,频率和PWM一致,常见10kHz到20kHz。速度环在电流环外面,带宽要比电流环低一个数量级,否则两个环会互相干扰,典型值1kHz到2kHz。位置环最慢,几百赫兹就够。这个频率搭配不是随便定的,频带拉开才能保证每一层环路对上层是“透明”的,不然系统容易振荡。
2. 硬件配置里的两个关键细节:PWM死区与电流采样
2.1 DBFED和DBRED怎么配,死区主源选择有什么要求
三相逆变器的上下桥臂是互补导通的,如果上管还没完全关断下管就导通了,母线直接被短路,器件瞬间烧毁。所以互补PWM必须插入死区时间,也就是让上下桥都关断一小段时间。28335的ePWM模块里专门有死区子模块,DBFED对应上升沿死区延迟,DBRED对应下降沿死区延迟,单位是TBCLK计数个数,不是纳秒。这个细节很多人会搞错,我在代码里看到过直接把DBFED写500,以为是500纳秒,实际还要看TBCLK频率是多少。
死区主源选择的关键在于,要让互补输出的上升沿和下降沿基于同一个信号源做延迟,这样上下桥的开关时刻才是对称的。EPwm1Regs.DBCTL的IN_MODE位就是干这个的,一般配置为上升沿和下降沿都使用EPWMxA作为输入,再通过POLSEL设置输出极性,形成A高有效、B低有效的互补对。如果主源选择混乱,比如上升沿用A、下降沿用B,插入的死区会不对称,输出的波形会莫名其妙地出现窄脉冲,甚至失去死区保护作用。
死区时间的具体数值,和功率器件、驱动电路强相关。小功率MOS管的开关时间通常在几十到几百纳秒,死区设300ns到500ns就够;IGBT模块或大功率MOS管,关断延迟可能到微秒级,死区要放宽到2us甚至3us。我见过不少初学者为了追求波形理想把死区设得很小,结果上电就炸管。调死区最可靠的方式是示波器同时测上下管栅极波形,确认关断完成后再开通,留出20%到30%的余量。代码配置大致这样:
// 以20kHz PWM、TBCLK=150MHz为例 EPwm1Regs.TBPRD = 3750; // 150MHz/20kHz=7500,增减计数时周期减半 EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL; // 上升沿和下降沿均从EPWMxA输入 EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // DBA高有效,DBB低有效 EPwm1Regs.DBFED = 45; // 约300ns(1/150MHz*45 ≈ 300ns) EPwm1Regs.DBRED = 45; // 约300ns这里TBCLK是150MHz,一个计数周期约6.67ns,45个计数差不多300ns。如果你的CLKDIV或HSPCLKDIV不是1分频,计算时要先算出实际TBCLK。
2.2 电流采集为什么要放下桥,如何采得准
FOC电流采样最常见的方案是低端采样,也就是在逆变器下桥臂MOS管源极和地之间串采样电阻,三相各放一个,电流流过采样电阻产生压降,经运放放大后送到28335的ADC。为什么放下桥而不放上桥?因为下桥采样电阻一端接地,共模电压低,运放电路简单可靠;而且在下桥导通期间,绕组电流会流过采样电阻,只要在下桥导通的窗口中采样,就能准确还原相电流。上桥采样需要处理很高的共模电压,隔离和放大的成本高很多。
但“放下桥”也带来一个采样时刻的问题。MOS管开关瞬间会有很高的dv/dt,会在采样电阻上耦合出尖峰噪声,所以不能在开关沿附近采样。正确做法是用ePWM的SOC触发ADC,把采样点放在PWM载波的波峰或波谷处,此时各相占空比相对稳定,且最好避开死区时间,因为死区期间下桥续流状态不确定,采到的电流不可信。28335的ADC支持事件触发,配置SOCA由CTR=PRD或CTR=ZERO触发即可。实际项目中,采样点还要考虑ADC采样保持时间和转换时间,保证在中断处理FOC算法时拿到的电流值对应的是本周期中点的电流。
还有一个工程细节:双电阻采样方案里,某相占空比接近0%或100%时,下桥导通时间太短,采样电阻上的信号还没稳定就关了,采样值会失真甚至完全采不到。处理办法有几种,一是把PWM限制在5%到95%范围内(会牺牲一点母线利用率),二是用移相法把采样窗口错开,三是在那些边界扇区改用三电阻采样补偿。28335的ePWM支持相位偏移,可以实现移相方案,但代码复杂度会上去。初学者建议先用限幅方式把系统跑通,后面再优化。
3. FOC算法核心:Clarke变换与dq轴电流的控制逻辑
3.1 Clarke变换为什么只用两相电流,选哪两相有讲究吗
FOC的第一步是电流采样,然后做Clarke变换,把三相静止坐标系下的电流变换到两相静止坐标系。很多初学者看到公式里只用了i_a和i_b,就会问:第三相电流不需要吗?答案是确实不需要,因为电机三相绕组通常是星形连接且中性点不引出,根据基尔霍夫电流定律,i_c = -i_a - i_b,知道任意两相,第三相自然就算出来了。这也就是为什么工程上常采用“双电阻+下桥采样”方案,两个采样电阻加上一个KCL计算就能得到三相电流。
那采哪两相有要求吗?理论上是任取两相,只要不是同一相就行。工程习惯采A相和B相,或者A相和C相,取决于采样电阻布局和ADC通道分配。但要特别留意采样时刻的一致性:两相电流必须是同一时刻的值。如果两个ADC通道是顺序采样,时间上有一点错开,对于低频电流影响不大,在电流频率较高或者电流环带宽较高时,会引入相位误差。28335的ADC可以配置同步采样模式,或者在中断里计算补偿,实际做的时候要先确认采样对齐。
Clarke变换还有一个系数问题,常见的是2/3系数等幅变换和sqrt(2/3)等功率变换。FOC算法中用的系数必须与反Park变换、SVPWM的幅值基准一致,否则电流环跑出来会有增益误差。我的习惯是统一采用等幅变换,因为SVPWM的输出电压基准是母线电压的一半,等幅变换下计算更直观。
3.2 Iq是怎么产生磁场的,弱磁控制又是什么
Clarke变换之后是Park变换,用转子的电角度把静止坐标系下的电流旋转到转子dq坐标系。dq坐标系里,d轴和转子永磁体磁场方向对齐,q轴与磁场方向正交。变换后,i_d是励磁分量,i_q是转矩分量。永磁同步电机的电磁转矩公式可以简化为T_e = 1.5p[ψ_f i_q + (L_d - L_q)i_d i_q],其中ψ_f是永磁体磁链,p是极对数。可以看出,转矩主要由i_q和永磁体磁链相互作用产生,i_q对应的电枢反应磁场始终与转子磁场保持90度电角度,这就是FOC的核心——把定子电流解耦成“励磁”和“转矩”两个分量后,就能像控制直流电机那样,用调节i_q来控制转矩。
i_d在表贴式永磁电机里通常控制为0,因为L_d与L_q接近,i_d对转矩贡献很小,反而会增加铜耗。但在内埋式永磁电机或者需要高速运行时,i_d就有大用了,这就是弱磁控制。转速升高后,电机反电动势接近母线电压,SVPWM可输出的电压幅值到达了极限,此时再想提高转速,就需要给i_d一个负值,产生去磁作用,降低气隙磁链,从而在电压受限的条件下提高转速范围。
在28335上实现弱磁,常见做法是在电压环外面加一个PI调节器,把SVPWM所需电压幅值作为反馈,限制在线性区以内,比如母线电压Vdc的1/√3倍,PI输出作为i_d的负向给定。调弱磁参数时要特别小心,负i_d会让电机永磁体面临去磁风险,不能为了追求极限转速一味加大负Id,要查器件的退磁曲线。28335的浮点算力跑这套逻辑绰绰有余,不会给CPU造成负担。
4. 无感FOC的启动与堵转处理
4.1 转子初始位置检测:启动前必须解决的事
FOC的Park变换依赖转子角度,如果初始角度不对,上电启动时可能把电机往错误的方向拉,甚至产生过流。有编码器时可以直接读角度,但无感FOC没有位置传感器,启动前必须想办法确定转子初始位置。简单粗暴的方法是预定位:给一个固定的电压矢量,比如把转子拉到某个已知的d轴方向,等待几百毫秒让机械振荡衰减,然后把当前角度记录为参考零点。这个方法实现简单,适合风机、水泵这类允许启动前轻微转动的负载,但不适合不允许反转、带重载的设备。
如果要求转子不能动,就需要用高频注入法:在估计的d轴方向叠加高频正弦电压,通过检测高频电流响应来判断转子磁极位置。原理是利用永磁电机的凸极效应或磁路饱和差异,转子位置不同,高频电流的幅值和相位会不一样。28335跑高频注入完全没有性能压力,难点在信号处理,需要数字滤波器提取高频分量,再通过锁相环或反正切运算解算角度。做起来比预定位复杂,但在零速和低速场合可靠性高很多。还有一种折中方案是初始段用开环强拉,把转子“拖”到同步后再切换闭环观测器,但启动过程粗暴,负载稍重就容易失步,我只在简单验证时这么干。
4.2 堵转检测思路与保护策略
无感FOC最头疼的异常工况之一是堵转。电机不转时,反电动势为零,速度观测器估算出来的转速会掉到接近零;如果此时控制环还在输出大电流,绕组和功率管会迅速过热。堵转检测的基本逻辑就是组合判断:连续若干控制周期内估算转速都低于某个阈值,同时转矩电流i_q(或者电流矢量的模)长时间超过设定值,就判定为堵转。只判断电流而不判断时间也不行,电机正常启动或大惯量负载加速时电流也可能很大,所以时间窗和滞环必须加进去。
保护动作要分级。第一级先限制电流给定,把电流指令削到安全值以下,防止过热;如果“堵转”信号持续几百毫秒到一秒,再执行停机,封锁PWM输出,并记录故障标志。停机后重新启动时,需要重新做一次转子初始位置检测,因为堵转期间转子位置可能已经变化了。还有一个容易忽略的点:有些负载(比如压缩机)启动时转子在抖振,估算转速可能短暂为负,这不一定是真的堵转,检测逻辑里要区分正反向堵转,并留出合理的判定窗口。
另外有人问FOC电调会不会开同步整流。同步整流常见于BLDC方波驱动,用来替代体二极管续流,降低损耗;FOC是正弦驱动,PWM本身就是连续的同步调制,续流路径一般直接利用MOS管体二极管或并联的快恢复二极管,工程上很少单独做“同步整流”这个动作。如果你关注的是轻载效率,方向应该放在优化SVPWM死区和调制方式上,而不是套用方波驱动的思路。
5. 三环频率选配与常见问题排查
5.1 三环频率怎么选
三环频率的选取直接影响系统稳定性。电流环必须跑得最快,它和PWM频率绑定,10kHz到20kHz都很常见。选20kHz还有个好处是超出了人耳可听范围,电机噪音明显降低。速度环频率放1kHz到2kHz,也就是每10个或20个电流环周期执行一次速度环计算。位置环再低一档,一般500Hz以下就行。这样分层的原因很简单:内环带宽必须远高于外环,否则外环给一个突变指令,内环跟不上,整个系统就会出现相位滞后和振荡。
调试顺序上,我始终坚持从内向外。先把电流环单独跑起来:给一个固定的i_q给定,用示波器看相电流幅值和相位是否和给定一致,确认电流环PI参数稳定。然后闭合速度环,最后才加位置环。如果一上来就三板斧全调,出了问题根本分不清是哪一环出的。
5.2 常见问题速查表
| 现象 | 可能原因 | 排查思路 |
|---|---|---|
| 上电后母线过流,MOS管发烫 | 死区时间过短,上下桥直通 | 示波器测上下管栅极波形,检查死区配置,DBFED/DBRED加大 |
| 相电流波形畸变、毛刺大 | 采样时刻靠近开关沿,采到了噪声 | 用ePWM同步触发ADC,把采样点移到载波中点,避开死区 |
| 电流读数有一个固定偏置 | 运放零点漂移 | 上电且电机静止时采样N次取平均,作为零点偏移量在软件里扣除 |
| 电机启动“咯咯”响或反转 | 转子初始角度不准 | 暂停输出,做预定位,或改用高频注入法检测初始位置 |
| 高速段转速上不去,转矩掉得厉害 | 到达电压极限 | 在电流环外增加弱磁PI调节器,输出负i_d给定 |
| 空载正常,带负载容易报堵转 | 堵转判定时间窗太短 | 延长确认时间,加入滞环,区分堵转和大惯量启动 |
遇到模糊问题时,我的习惯是先在代码里加一个状态变量,用28335的DAC模块或者空闲IO输出到示波器,把转速估算值、i_q给定、堵转标志这些关键量实时导出来看。FOC的问题往往不是单独一个环节的错误,而是多个条件叠加造成的,能可视化调参会快很多。
最后分享一个我在28335上调FOC养成的小习惯:永远从低压小电流开始验证。第一次上电时母线电压限制在安全范围,电流限幅设得很保守,再逐步放宽。确认SVPWM波形正常、电流采样零点校准OK、驱动板不炸管之后,再接编码器闭环跑电流环,最后才切到无感。很多人觉得这一步一步来太慢,但实际踩过几次坑之后你会发现,慢才是快。
本文还有配套的精品资源,点击获取