3. C2000硬件架构速览:CPU内核与CLA、PWM、ADC、eQEP模块
做电机控制,说白了就是跟硬件打交道。你算法写得再漂亮,最后都得落到寄存器上。C2000系列我用了快十年,从早期的2812到现在的28379D,架构一直在进化,但核心思路没变——实时控制。这一章咱们把几个关键模块过一遍,不抠寄存器细节,重点讲清楚它们怎么协同工作。
核心观点:C2000不是通用MCU,它是为“在一个控制周期内完成采样、计算、输出”而生的。理解这一点,后面的FOC代码你才能看懂为什么这么写。
3.1 CPU内核与CLA:谁干粗活,谁干细活
C2000的CPU内核是C28x,32位定点/浮点处理器。主频从100MHz到200MHz不等。我个人习惯把它当成“大脑”——负责主循环、通信、故障处理这些需要复杂逻辑的任务。
但电机控制有个痛点:中断里不能待太久。PWM触发ADC,ADC完了进中断算FOC,算完更新占空比。这一串活儿如果全让CPU干,主频再高也扛不住。尤其是双电机或者三电机项目,中断嵌套能把人逼疯。
CLA(Control Law Accelerator)就是干这个的。它是个独立的32位浮点协处理器,跟CPU共享内存,但能独立取指、执行。我最早接触CLA是在28377上,当时项目要求一个芯片控两个PMSM电机,主频200MHz,单靠CPU根本跑不满20kHz的电流环。后来把其中一个电机的FOC算法扔给CLA,CPU只做位置环和通信,问题就解决了。
| 特性 | CPU (C28x) | CLA |
|---|---|---|
| 指令集 | 完整C28x指令集 | 子集(无除法、浮点超越函数需查表) |
| 触发方式 | 中断(PWM、ADC等) | 任务(由PWM、ADC或软件触发) |
| 内存访问 | 通过总线矩阵 | 直接访问共享RAM(LSx RAM) |
| 典型用途 | 主循环、通信、故障处理 | 电流环、速度环、滤波 |
我的经验:CLA编程用C语言就行,但要注意——它不支持除法运算符,也不支持sin/cos库函数。我一般提前算好正余弦表放在RAM里,CLA直接查表。另外,CLA任务里不要写while循环,它没有看门狗,卡住了只能复位。
3.2 PWM模块:电机控制的“手”
PWM模块是C2000的看家本领。别的MCU也有PWM,但C2000的ePWM模块是为电机控制量身定做的。每个ePWM模块包含两个输出(A/B),可以配置成互补、死区插入、相位偏移、跳周期等等。
我印象最深的是死区插入。刚入行那会儿,我写了个简单的开环V/F控制,死区设得太小,结果MOS管上下桥臂直通,板子直接冒烟。后来学乖了,死区时间至少留200ns,还得根据驱动芯片的传播延迟调整。
ePWM模块还有一个很实用的功能——时基同步。多电机项目里,你需要让几个PWM模块的载波对齐,否则会产生差频噪声。C2000通过SYNCI/SYNCO信号链,可以把所有ePWM模块同步到同一个时基上。
避坑指南:我曾经在28379D上遇到过PWM模块输出毛刺的问题。排查了半天,发现是EPWMCLK分频设置不对,导致时基计数器在边界处产生了竞争。解决办法是:配置完所有PWM寄存器后,再统一使能时基时钟。别一个一个使能。
3.3 ADC模块:采样的精度与速度
电机控制对ADC的要求很明确:同步、快速、准确。C2000的ADC模块是逐次逼近型(SAR),12位分辨率,转换时间一般在200ns~400ns之间。但真正厉害的是它的触发与排序机制。
每个ADC模块有多个SOC(Start-of-Conversion)通道,每个SOC可以独立配置触发源和采样引脚。你可以让SOC0由PWM1触发,采样相电流A;SOC1由PWM2触发,采样母线电压。这样就能实现“在PWM载波的特定时刻采样”,避免开关噪声。
我记得有个项目,客户反映电机低速时电流波形有毛刺。我查了ADC采样时序,发现采样窗口刚好落在MOS管开关瞬间。后来把采样点往后移了1μs,波形就干净了。这就是采样窗口偏移的典型应用。
| 参数 | 典型值 | 说明 |
|---|---|---|
| 分辨率 | 12位 | 部分型号支持16位(过采样模式) |
| 转换时间 | 200ns~400ns | 取决于时钟分频和采样窗口 |
| 触发源 | PWM、CPU、软件 | PWM触发最常用 |
| 采样窗口 | 可编程(1~16个ADC时钟周期) | 窗口越大,采样越准,但转换时间变长 |
我的习惯:采样窗口我一般设8个ADC时钟周期。太短了采样电容充不满,太长了浪费转换时间。另外,ADC的参考电压一定要用外部精密基准,内部基准温漂太大,做FOC会飘。
3.4 eQEP模块:读懂编码器的“语言”
eQEP(Enhanced Quadrature Encoder Pulse)模块,说白了就是解码增量编码器信号的。A、B两路正交信号进来,它帮你算出位置和速度。C2000的eQEP模块支持三种模式:正交计数、方向计数、时钟计数。
正交计数模式最常用。A相和B相相位差90°,eQEP内部有个状态机,根据边沿顺序判断正反转。我刚开始用的时候,总搞不清为什么编码器转一圈,计数值不是整的。后来发现是索引脉冲(Index)没处理好。索引脉冲每转一圈出现一次,用来校准零位。如果你不用索引脉冲,每次上电位置都是随机的。
速度测量有两种方法:M法(测频法)和T法(测周期法)。M法适合高速,T法适合低速。C2000的eQEP模块内置了速度计算单元,可以直接读出速度值,不用自己算。
关键点:eQEP模块的输入信号一定要加硬件滤波。编码器线缆长,容易引入噪声。我一般在A、B、Z三路上各加一个RC低通滤波(100Ω+1nF),再进GPIO。别指望软件滤波,硬件滤波能省掉你80%的调试时间。
3.5 模块协同:一个控制周期的完整流程
说了这么多模块,它们怎么配合?我画个流程图你就明白了。
你看,整个流程是硬件自动触发的。PWM计数到特定值,自动触发ADC;ADC转换完,自动触发CLA任务;CLA算完FOC,自动更新PWM比较寄存器。CPU全程不参与,只在需要的时候读一下结果。这就是C2000的实时控制精髓。
注意:CLA任务里不要做printf、GPIO翻转这些耗时操作。我见过有人把调试用的GPIO翻转放在CLA任务里,结果PWM周期被拉长,电机直接啸叫。调试信息用CPU主循环打印,别干扰实时控制。
嗯,这一章就到这儿。C2000的硬件模块远不止这些,但PWM、ADC、eQEP、CLA这四个是电机控制的基石。后面的章节我们会基于这些模块,一步步搭建FOC代码框架。你先把这几个模块的框图和数据手册翻一翻,有个印象就行。