TMS320F28P55 CAN总线Bus-Off自动恢复配置详解及代码实现
## 🚗 F28P55 芯片 CAN Bus-Off 自动恢复配置代码 以下是基于 **TI C2000 F28P55** 的 CAN 总线离线(Bus-Off)自动恢复配置代码,使用 **DCAN(Dual CAN)模块**。代码采用 **寄存器直接操作** 方式,适用于 TMS320F28P55 系列芯片。 ### 1️⃣ 核心配置流程 ```c #include "F28P55x_device.h" #include "F28P55x_Examples.h" // 全局变量 volatile Uint16 canBusOffFlag = 0; // Bus-Off 标志位 // CAN 消息对象结构体 struct DCAN_MSG_OBJ { Uint32 msgID; Uint32 msgIDMask; Uint32 flags; Uint32 msgLen; Uint32 msgData[2]; }; // 函数声明 void InitCAN_Gpio(void); void InitDCAN_Module(void); void ConfigureBusOffAutoRecovery(void); __interrupt void CAN_ISR(void); /** * @brief 初始化 GPIO 引脚(CAN 收发器控制) */ void InitCAN_Gpio(void) { EALLOW; // CAN-A 引脚配置(GPIO30 = CANA_RX, GPIO31 = CANA_TX) GpioCtrlRegs.GPAMUX1.bit.GPIO30 = 1; // 设置为 CANA_RX GpioCtrlRegs.GPAMUX1.bit.GPIO31 = 1; // 设置为 CANA_TX GpioCtrlRegs.GPADIR.bit.GPIO30 = 0; // 输入 GpioCtrlRegs.GPADIR.bit.GPIO31 = 1; // 输出 // 使能 CAN 模块时钟 CpuSysRegs.PCLKCR10.bit.CAN_A = 1; EDIS; } /** * @brief 初始化 DCAN 模块(波特率、时序等) */ void InitDCAN_Module(void) { EALLOW; // 1. 复位 CAN 模块 CanaRegs.CAN_CTL.bit.INIT = 1; // 进入初始化模式 while (CanaRegs.CAN_CTL.bit.INIT == 0); // 等待初始化模式激活 // 2. 配置位时序(假设 SYSCLK=200MHz, 期望波特率500kbps) // Bit Time = (BRP+1) * (TSEG1+1+TSEG2+1+1) / SYSCLK // 示例:BRP=9, TSEG1=13, TSEG2=2, SJW=1 → 500kbps CanaRegs.CAN_**R.bit.BRP = 9; // 波特率预分频器 (实际分频 = BRP+1) CanaRegs.CAN_**R.bit.TSEG1 = 13; // 时间段1 (采样点前) CanaRegs.CAN_**R.bit.TSEG2 = 2; // 时间段2 CanaRegs.CAN_**R.bit.SJW = 1; // 同步跳转宽度 // 3. 设置接收超时和中断使能 CanaRegs.CAN_INT.bit.IE0 = 1; // 使能中断线0 CanaRegs.CAN_CTL.bit.EIE = 1; // 错误中断使能 CanaRegs.CAN_CTL.bit.IE = 1; // 模块级中断使能 // 4. 配置自动恢复功能 ConfigureBusOffAutoRecovery(); EDIS; } /** * @brief ⭐ 关键函数:配置 Bus-Off 自动恢复 * * 核心设置: * - CAN_CTL.RM:复位模式(需在INIT=1时配置) * - CAN_CTL.ABO:自动恢复使能 * - 错误状态寄存器 ERRC 用于检测状态 */ void ConfigureBusOffAutoRecovery(void) { EALLOW; // 1. 确保处于初始化模式 CanaRegs.CAN_CTL.bit.INIT = 1; while (CanaRegs.CAN_CTL.bit.INIT == 0); // 2. ⭐ 使能 Bus-Off 自动恢复 (ABO = Auto Bus-On) CanaRegs.CAN_CTL.bit.ABO = 1; // 设置自动恢复位 // 注:当设置为1时,CAN控制器在检测到Bus-Off后 // 会自动等待128个总线空闲周期后重新上线 // 3. 配置错误中断(可选,用于监控状态) CanaRegs.CAN_ERR_INT.bit.ERR_INT_EN = 1; // 错误中断全局使能 // 4. 退出初始化模式,进入正常模式 CanaRegs.CAN_CTL.bit.INIT = 0; while (CanaRegs.CAN_CTL.bit.INIT != 0); EDIS; } /** * @brief CAN 中断服务函数(用于监控Bus-Off事件) */ __interrupt void CAN_ISR(void) { // 读取中断状态 Uint32 intFlags = CanaRegs.CAN_INT_REG.all; // 检查错误中断 if (intFlags & DCAN_INT_ERR) { // 读取错误状态寄存器 Uint32 errStatus = CanaRegs.CAN_ERR.all; // 检查Bus-Off状态 if (errStatus & DCAN_ERR_BUS_OFF) { canBusOffFlag = 1; // 设置标志位 // 注意:即使设置了ABO=1,仍建议在此处记录事件 } } // 清除中断标志 CanaRegs.CAN_INT_REG.all = intFlags; // 应答中断 PieCtrlRegs.PIEACK.all = PIEACK_GROUP9; } ``` --- ### 2️⃣ 主函数调用示例 ```c void main(void) { // 系统初始化 InitSysCtrl(); InitGpio(); // 初始化CAN GPIO InitCAN_Gpio(); // 初始化DCAN模块 InitDCAN_Module(); // 配置中断(PIE向量表) EALLOW; PieVectTable.CAN_A_INT = &CAN_ISR; // CAN-A中断向量 EDIS; // 使能PIE中断组9 IER |= M_INT9; EINT; // 主循环 while(1) { // 检查Bus-Off标志 if (canBusOffFlag) { // Bus-Off已发生,且已自动恢复 canBusOffFlag = 0; // TODO: 在此执行恢复后的处理(如重新初始化消息对象) } // 正常运行CAN通信 // SendCANMessage(); // ReceiveCANMessage(); } } ``` --- ### 3️⃣ 📌 关键配置详解 | 配置项 | 寄存器/位 | 说明 | |--------|----------|------| | **自动恢复使能** | `CAN_CTL.ABO` | 设为1时,Bus-Off后自动恢复 | | **初始化控制** | `CAN_CTL.INIT` | 必须在`INIT=1`时修改ABO位 | | **恢复时机** | 硬件自动处理 | 等待128个总线空闲位后重新参与通信 | | **错误监测** | `CAN_ERR` 寄存器 | 可读取错误状态和错误计数 | **⚠️ 重要注意点:** - **ABO 位必须在初始化模式(INIT=1)下配置**,否则写入无效 - 自动恢复后 **TX 错误计数器清零**,但 RX 错误计数器保持 - 若需手动恢复,可设置 `CAN_CTL.RM = 1` 触发复位 --- ### 4️⃣ 🔧 开发建议 1. **完善错误处理机制**:在 Bus-Off 后,建议重新初始化消息对象,并检查是否有待发送数据丢失。 2. **使用中断配合轮询**:尽管设置了自动恢复,仍建议在中断中监测 Bus-Off 事件,以便上层应用了解通信中断情况。 3. **波特率验证**:使用示波器或逻辑分析仪验证实际波特率是否与预期相符。 4. **注意总线拓扑**:如果总线上有多个节点同时 Bus-Off,自动恢复可能导致同步问题,建议错开恢复时间。 --- ######[AI写代码神器 | 2004点数解答 | 2026-08-10 15:36:52]
- 冰雕台阶通关大考验:C++程序精准判断成员能否安全通过!(DeepSeek | 120点数解答 | 2025-12-28 14:47:37)102
- 深度揭秘 Oracle Workarea Size Policy:参数调优助力数据库性能飞升(阿里通义 | 372点数解答 | 2024-05-13 10:54:45)343
- 蓝牙设备信息大揭秘:类型、地址、状态等全知晓!(讯飞星火 | 45点数解答 | 2024-06-14 10:12:29)297
- Python 实现球类:精准计算半径、表面积与体积,附输入验证与异常处理!(阿里通义 | 261点数解答 | 2024-11-28 21:19:39)558
- Python 编程:输入三边判断能否成三角形并算周长面积(DeepSeek | 236点数解答 | 2025-03-13 10:55:39)418
- Python:输入三边判断能否成三角形并算周长面积(字节豆包 | 243点数解答 | 2025-03-13 10:55:58)394
- C++程序:判断成员能否通过危险冰雕台阶(字节豆包 | 395点数解答 | 2025-11-28 19:47:22)113
- 冰雕台阶危机!程序判断成员能否安全通过(字节豆包 | 411点数解答 | 2025-12-27 21:20:54)112
- 惊险冰雕台阶:程序判断成员能否安全通关!(字节豆包 | 97点数解答 | 2026-01-10 19:30:30)77
- 冰雕台阶通行判断程序的实现(字节豆包 | 393点数解答 | 2026-03-07 19:40:41)57
- 冰雕台阶通过条件判断程序实现(字节豆包 | 257点数解答 | 2026-04-18 19:55:00)34
- 冰雕台阶通过判断:根据体重与体力输出通过结果(DeepSeek | 162点数解答 | 2026-05-08 19:17:06)41