TMS320F28335主控 EtherCAT伺服方案 EtherCAT低压伺服,提供TI DSP和FPGA源码和PDF原理图。
最近在搞EtherCAT伺服方案,用到了TI的TMS320F28335这块DSP。这货主频150MHz还带FPU,跑实时控制确实给力。今天重点聊聊咱们实现的低压伺服方案,直接把DSP和FPGA源码摊开说。
硬件上,电源部分用了TPS7A4701做3.3V转换。这个LDO的PSRR做到78dB,实测伺服电机启停时数字电源纹波控制在20mV以内。ECAT物理层用的LAN9252,通过SPI接口和DSP通信。这里有个坑:SPI时钟必须配置成8MHz才能满足ECAT的同步要求,刚开始用默认的5MHz直接导致从站丢包。
DSP端的ECAT初始化代码有点讲究:
c
void InitEcat(void) {
ECAT_REGS->ECCR1 |= 0x0001; // 使能ECAT时钟
while(!(ECAT_REGS->ECCR1 & 0x0002)); // 等待时钟稳定
SpiRegWrite(0x0000, 0x8000); // 复位LAN9252
DELAY_US(100);
SpiRegWrite(0x0000, 0x0000);
// 配置分布式时钟
EcatDcConfig(0x7000, 0x01);
EcatPdoMap(0x1600, 0x01, (uint16_t*)&ServoParam, 8); // 映射8个参数对象
}
这段代码里有几个关键点:ECAT控制器的时钟源必须选外部晶振,DC同步偏移量寄存器设成0x7000是实测出来的最优值。PDO映射函数里的0x1600对应对象字典里的控制字区域,调试时发现如果映射长度不是8的整数倍,从站会报SM配置错误。
FPGA这边主要处理PWM生成和编码器解码。Verilog代码里有个巧妙的设计:
verilog
always @(posedge clk_50M) begin
if(sync_pulse) begin
pwm_counter <= 0;
position_reg <= encoder_raw;
end else begin
pwm_counter <= pwm_counter + 1;
end
pwm_out <= (pwm_counter < duty_cycle) ? 1'b1 : 1'b0;
end
这个同步逻辑确保PWM周期严格对齐EtherCAT的SYNC信号。实测时发现,如果不做位置寄存器的同步采样,速度环计算会引入约2us的抖动。FPGA的时钟管理模块用了Xilinx的MMCM,把50MHz输入时钟倍频到200MHz驱动PWM逻辑,分辨率直接干到5ns。
原理图里有个容易翻车的地方:DSP的GPIO24/25复用成了SPI片选信号,但默认上电是PWM输出功能。必须在系统初始化时先执行:
c
GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 3; // SPI_CS1功能
GpioCtrlRegs.GPAMUX2.bit.GPIO25 = 3; // SPI_CS2功能
否则SPI通信压根起不来。之前因为这个配置顺序问题,折腾了一整天------DSP的复用功能配置必须在外设初始化之前完成,这个在TI手册里其实有写,但字体小得跟蚂蚁似的。
整个方案实测效果:500W电机在0-3000rpm范围内,位置跟踪误差±1 pulse(17位编码器)。EtherCAT周期设1ms时,CPU占用率约35%,主要消耗在电流环计算上。建议做FOC时把PWM频率设在15kHz以上,否则电机高频噪音明显。
源码包里有个ecat_diag.c文件,里面的总线诊断函数特别实用:
c
void EcatDiag(void) {
uint16_t status = SpiRegRead(0x0130);
if(status & 0x0004) {
DebugPrint("ESC检测到物理层错误");
// 自动复位PHY
SpiRegWrite(0x0014, 0x0040);
}
// 统计丢包率
static uint32_t err_cnt = 0;
if(ECAT_REGS->EPCIRQ & 0x01) {
err_cnt++;
}
}
这个函数在后台任务里每10ms调用一次,能实时监测链路质量。遇到网络闪断时,自动复位PHY芯片比整个系统复位靠谱多了。实际部署时,建议把err_cnt统计值通过SDO上传给主站做健康度监控。
最后提一嘴原理图里的TVS阵列:ECAT网口用了Bourns的CDSOT23-SM712,比常规的二极管方案节省70%的PCB面积。但布局时要注意,TVS到RJ45的距离不能超过5mm,否则ESD防护效果打折扣。
