PIC18F2580 CAN模块发送故障求助:TXB0CONbits.TXREQ无法清零
PIC18F2580 CAN模块发送故障排查与解决
问题总结
- 硬件:PIC18F2580,目标发送250kbps、ID=0x202的8字节CAN消息,首字节设为0xFF,无需接收功能
- 故障现象:CANTX(RB2)引脚输出始终为0V;首次发送后
TXB0CONbits.TXREQ无法复位,无法继续发送消息 - 开发环境:MPLABX v6.00、XC8 V3.00
核心故障原因
1. 系统时钟频率过低,无法支持250kbps波特率
当前设置的内部振荡器为1MHz,而CAN总线位时间至少需要8个时间量子(TQ)。按1MHz时钟计算,即使预分频设为1,最小位时间也会达到16μs,对应波特率仅62.5kbps,远低于目标值。波特率不匹配会导致CAN模块无法正常同步,发送请求位永远不会自动清除,引脚也无法输出有效电平。
2. 波特率寄存器配置错误
基于1MHz的错误时钟,现有BRGCON1/2/3配置计算出的波特率仅62.5kbps,完全不符合要求,进一步导致模块工作异常。
3. 潜在引脚配置风险
虽然代码中设置了TRISBbits.TRISB2=0,但如果ADCON1将RB2配置为模拟输入,也会导致引脚输出异常——不过当前ADCON1=0b00000100已将AN8(RB2)设为数字输入,这部分无需调整,但需确认配置生效。
分步解决方法
1. 提升系统时钟到8MHz
PIC18F2580内部振荡器支持最高8MHz,这是支持250kbps波特率的最低可行时钟。修改配置宏与寄存器:
#pragma config FOSC = INTOSCIO // 启用内部8MHz振荡器,带IO功能 #pragma config PWRT = ON // 开启电源复位定时器,稳定供电 #pragma config WDT = OFF // 关闭看门狗(按需调整) // 其他配置根据需求补充 #define _XTAL_FREQ 8000000 // 更新时钟频率宏为8MHz
2. 修正CAN波特率寄存器配置
基于8MHz时钟,计算出250kbps对应的寄存器值:
- 预分频系数
BRP=0(BRGCON1=0x00) - 传播段设为6TQ(
PROPSEG=5),相位段1设为6TQ(SEG1PH=5),采样模式设为3次采样(SAM=1)→BRGCON2=0xAD - 相位段2设为3TQ(
SEG2PH=2)→BRGCON3=0x02
修正后的CAN_Init函数:
void CAN_Init() { // 确保CAN引脚为数字IO ADCON1 = 0b00000100; // AN8-AN12设为数字,避免RB2/RB3被识别为模拟引脚 TRISBbits.TRISB2 = 0; // CANTX设为输出 TRISBbits.TRISB3 = 1; // CANRX设为输入 // 进入配置模式 CANCON = 0x80; while ((CANSTAT & 0xE0) != 0x80); // 等待模式切换完成 // 配置250kbps波特率(Fosc=8MHz) BRGCON1 = 0x00; BRGCON2 = 0xAD; BRGCON3 = 0x02; TXB0CON = 0x00; // 设置发送缓冲为高优先级 // 切换到正常工作模式 CANCON = 0x00; while ((CANSTAT & 0xE0) != 0x00); }
3. 完善发送函数的错误处理
添加超时后的错误指示,方便排查:
void CAN_Transmit(unsigned int ID, unsigned char *message, unsigned char length) { unsigned int timeout = 5000; // 等待发送缓冲空闲 while (TXB0CONbits.TXREQ && timeout--) { __delay_us(10); } if (timeout == 0) { PORTCbits.RC0 = 1; // 用RC0引脚指示发送超时(可自行调整) return; } // 设置标准ID TXB0SIDH = (ID >> 3) & 0xFF; TXB0SIDL = (ID << 5) & 0xE0; // 标准帧,IDE位清零 TXB0DLC = length & 0x0F; // 复制数据到发送缓冲 TXB0D0 = message[0]; TXB0D1 = message[1]; TXB0D2 = message[2]; TXB0D3 = message[3]; TXB0D4 = message[4]; TXB0D5 = message[5]; TXB0D6 = message[6]; TXB0D7 = message[7]; // 触发发送 TXB0CONbits.TXREQ = 1; }
额外硬件排查要点
- 检查CAN收发器(如SN65HVD230)的供电是否为5V,引脚连接是否正确:TX接RB2,RX接RB3,CANH/CANL接总线,GND接地。
- 确保CAN总线两端接有120Ω终端电阻,否则会出现信号反射,导致发送失败。
- 检查PIC的电源和复位电路是否稳定,避免模块工作异常。
内容的提问来源于stack exchange,提问作者Nik Name
相关产品推荐
相关产品推荐

