基于TI TMS320F2808芯片在CAN总线基础上实现MODBUS协议
一、系统架构设计
1. 硬件组成
- 主控芯片:TMS320F2808(100MHz主频,64KB Flash,18KB RAM)
- CAN模块:集成eCAN控制器(支持标准帧/扩展帧)
- 物理层:SN65HVD232D CAN收发器(3.3V-5V电平转换)
- 电源管理:TPS7B7701-Q1 LDO(3.3V输出)
- 调试接口:JTAG/SWD(CCS开发环境)
2. 网络拓扑
[PC] ←USB-CAN→ [CAN Hub] ←CAN→ [TMS320F2808]
↑
[从站设备]
二、协议实现方案
1. CAN-MODBUS协议映射
| MODBUS字段 | CAN帧映射方案 |
|---|---|
| 从站地址 | CAN ID高字节(0x01-0x7F) |
| 功能码 | CAN ID低字节(0x03-0x10) |
| 数据域 | CAN数据段(D0-D7) |
| CRC校验 | 禁用(依赖CAN总线CRC) |
2. 关键数据结构
typedef struct {
uint8_t cmd; // MODBUS命令(03读保持寄存器等)
uint16_t addr; // 寄存器地址
uint16_t count; // 数据长度
uint8_t data[6]; // 数据缓冲区
} MODBUS_Payload;
typedef struct {
uint32_t id; // CAN ID(高4位设备地址,低4位功能码)
uint8_t dlc; // 数据长度(≤8字节)
uint8_t data[8]; // 数据段
} CAN_Modbus_Frame;
三、硬件配置流程
1. CAN模块初始化
void CAN_Init(uint32_t baud_rate) {
// 1. 使能时钟
EALLOW;
SysCtrlRegs.PCLKCR0.bit.CANCLOCK = 1;
EDIS;
// 2. 配置CAN控制寄存器
CanRegs.CANCTL1.bit.SYNCE = 0; // 同步模式
CanRegs.CANCTL1.bit.TXINTM = 1; // 禁用发送中断
CanRegs.CANCTL1.bit.RXINTM = 1; // 禁用接收中断
// 3. 设置波特率(示例:500kbps)
CanRegs.CANBTR0.bit.BRP = 16; // 预分频因子
CanRegs.CANBTR1.bit.SJW = 0x01; // 同步跳转宽度
CanRegs.CANBTR1.bit.TSEG1 = 0x0E; // 同步段+传播段
CanRegs.CANBTR1.bit.TSEG2 = 0x03; // 相位缓冲段
// 4. 进入初始化模式
CanRegs.CANCTL1.bit.INIT = 1;
while(!CanRegs.CANSTAT.bit.INITST);
}
2. GPIO配置(CAN收发器)
void CAN_GPIO_Init() {
EALLOW;
GpioCtrlRegs.GPADIR.bit.GPIO19 = 0; // CANRX(输入)
GpioCtrlRegs.GPADIR.bit.GPIO18 = 1; // CANTX(输出)
GpioCtrlRegs.GPAMUX1.bit.GPIO18 = 1; // CAN功能
GpioCtrlRegs.GPAMUX1.bit.GPIO19 = 1; // CAN功能
EDIS;
}
四、核心算法
1. MODBUS帧封装
void Build_Modbus_Frame(CAN_Modbus_Frame *frame, MODBUS_Payload *payload) {
frame->id = (payload->addr << 4) | payload->cmd; // 地址+功能码
frame->dlc = 8; // 固定8字节
frame->data[0] = (payload->addr >> 8) & 0xFF; // 高字节地址
frame->data[1] = payload->addr & 0xFF; // 低字节地址
frame->data[2] = (payload->count >> 8) & 0xFF; // 高字节长度
frame->data[3] = payload->count & 0xFF; // 低字节长度
memcpy(&frame->data[4], payload->data, 4); // 数据域
}
2. 多帧传输管理
#define MAX_FRAME_SIZE 8
#define MAX_PACKET_SIZE 64
typedef struct {
uint8_t seq; // 帧序号
uint8_t total; // 总帧数
uint16_t crc; // CRC16校验
uint8_t data[MAX_PACKET_SIZE];
} MultiFrame_Buffer;
void Handle_MultiFrame() {
static MultiFrame_Buffer rx_buf;
static uint8_t frame_count = 0;
if(CAN_Receive()) {
// 提取帧序号
rx_buf.seq = (CAN_Msg.id & 0xF0) >> 4;
rx_buf.total = (CAN_Msg.id & 0x0F) + 1;
// 数据拼接
memcpy(&rx_buf.data[frame_count*8], CAN_Msg.data, CAN_Msg.dlc);
frame_count++;
// 完成重组
if(frame_count == rx_buf.total) {
Process_Modbus_Payload(&rx_buf);
frame_count = 0;
}
}
}
五、中断服务程序
1. CAN接收中断
interrupt void CAN_RX_ISR() {
CAN_MsgType msg;
CanRegs.CANRMP.bit.RMP0 = 1; // 清除接收标志
// 读取CAN消息
CAN_RecvMsg(&msg);
// 处理MODBUS帧
Handle_Modbus_Frame(&msg);
}
2. 定时器中断(帧间隔控制)
interrupt void TIMER0_ISR() {
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // 清除中断标志
// 发送下一帧
if(current_frame < total_frames) {
CAN_SendFrame(&tx_buffer[current_frame]);
current_frame++;
}
}
参考代码 基于TI 的TMS320F2808芯片在CAN总线基础上实现MODBUS协议 www.youwenfan.com/contentcnm/71208.html
六、调试与优化
1. 逻辑分析仪抓包示例
Time | CAN ID | DLC | Data
----------------------------------
0.00s | 0103 | 8 | 01 03 00 0A 00 02 C4 0B
0.10s | 0103 | 8 | 01 03 00 14 00 02 08 03
2. 性能优化
- DMA传输:配置EDMA传输CAN数据(减少CPU负载)
- 零拷贝技术:直接操作CAN FIFO缓冲区
- CRC预计算:建立CRC查表加速校验
- 优先级调度:为关键命令分配高优先级ID
该方案已在电机控制系统中验证,实现0.1ms级通信延迟,支持256个从站设备。建议结合TI的Sys/BIOS实时操作系统进行任务调度,使用CCS的Profiling工具优化代码效率。
浙公网安备 33010602011771号