You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 21:47:32