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初始化代码有点讲究:
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代码里有个巧妙的设计:
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输出功能。必须在系统初始化时先执行:
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文件,里面的总线诊断函数特别实用:
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防护效果打折扣。