独立can控制器sja1000采用


SJA1000是Philips(现NXP)推出的一款经典独立CAN控制器,广泛应用于工业控制、汽车电子、嵌入式系统等领域。它支持CAN 2.0A/B协议,提供灵活的配置选项和强大的错误处理能力。以下是围绕SJA1000的详细应用说明,涵盖硬件接口、软件配置、通信流程及常见问题解决。
**1. SJA1000核心特性
**(1) 主要功能
协议支持:兼容CAN 2.0A(11位标识符)和CAN 2.0B(29位标识符)。
通信速率:最高支持1Mbps(与总线长度和负载相关)。
错误处理:内置错误计数器(TEC/REC)、错误警告和总线关闭恢复机制。
接收过滤:支持单滤波器(BasicCAN模式)或双滤波器(PeliCAN模式)。
**(2) 工作模式
BasicCAN模式:兼容PCA82C200,适合简单应用。
PeliCAN模式:扩展功能(如可编程错误限制、接收FIFO增强等)。
**(3) 硬件接口
并行总线接口:8位数据总线(AD0-AD7)、地址总线(A0-A4)、控制信号(RD、WR、CS、ALE等)。
CAN总线接口:TXD、RXD(需外接CAN收发器,如TJA1050)。
中断输出:INT引脚,用于通知MCU处理CAN事件。
**2. 硬件连接与外围电路
**(1) 典型连接图
MCU (如STM32) <--> SJA1000 <--> CAN收发器 (如TJA1050) <--> CAN总线
MCU与SJA1000:
数据总线:MCU的8位数据线(如PA0-PA7)连接SJA1000的AD0-AD7。
地址总线:MCU的地址线(如PC0-PC4)连接SJA1000的A0-A4(通过译码器或直接连接)。
控制信号:MCU的GPIO控制SJA1000的RD、WR、CS、ALE等引脚。
SJA1000与CAN收发器:
TXD(SJA1000)→ TXD(TJA1050)
RXD(SJA1000)← RXD(TJA1050)
CAN总线端接:
总线两端各接一个120Ω终端电阻。
**(2) 关键注意事项
电气隔离:
在工业环境中,建议使用数字隔离器(如ADuM1201)隔离MCU与SJA1000,防止地电位差损坏芯片。
静电保护:
在CAN_H和CAN_L上添加TVS二极管(如PESD1CAN),防止ESD冲击。
时钟源:
SJA1000需外接16MHz晶振,确保时钟稳定。
**3. 软件配置与通信流程
**(1) 初始化流程
复位SJA1000:
通过控制寄存器(CR)的复位位(CR.0=1)将SJA1000置于复位模式。
配置时钟分频寄存器(CDR):
选择工作模式(BasicCAN/PeliCAN)、关闭CLKOUT引脚等。
设置验收滤波器(ACR/AMR或ACR0-ACR3/AMR0-AMR3):
在BasicCAN模式下配置ACR和AMR;在PeliCAN模式下配置4组滤波器。
配置总线定时寄存器(BTR0/BTR1):
设置波特率(如500kbps)、同步跳转宽度(SJW)、采样点等。
配置输出控制寄存器(OCR):
设置CAN总线的输出模式(正常、斜率控制等)。
退出复位模式:
将CR.0置0,SJA1000进入工作模式。
**(2) 发送报文流程
检查发送缓冲区状态:
读取命令寄存器(CMR)的
TR
位或状态寄存器(SR)的TBS
位,确认发送缓冲区空闲。写入报文到发送缓冲区:
将标识符、数据长度(DLC)、数据字节写入发送缓冲区(地址0x00-0x09)。
启动发送:
向CMR写入
TR
位(0x01),触发发送。监控发送状态:
通过SR的
TCS
位(发送完成)和TBS
位(缓冲区空闲)确认发送结果。
**(3) 接收报文流程
检查接收缓冲区状态:
读取SR的
RBS
位(接收缓冲区状态)或中断寄存器(IR)的RI
位(接收中断)。读取报文:
从接收缓冲区(地址0x10-0x19)读取标识符、DLC和数据字节。
释放接收缓冲区:
向CMR写入
RRB
位(0x04),释放缓冲区以接收下一帧。
**(4) 错误处理
监控错误计数器:
通过读取接收错误计数器(REC)和发送错误计数器(TEC)的值,判断节点状态。
若TEC > 127,节点进入消极错误状态;若TEC > 255,节点进入总线关闭状态。
错误恢复:
在总线关闭状态下,需等待128个总线空闲周期(11位隐性位)后自动恢复,或通过软件复位强制恢复。
**4. 代码示例(基于51单片机)
**(1) 初始化SJA1000
void SJA1000_Init(void) { // 进入复位模式 SJA1000_WriteReg(CR, 0x01); // CR.0 = 1 // 配置时钟分频寄存器(PeliCAN模式,关闭CLKOUT) SJA1000_WriteReg(CDR, 0x88); // 配置验收滤波器(接收所有报文) SJA1000_WriteReg(ACR0, 0x00); SJA1000_WriteReg(AMR0, 0x00); // 配置总线定时寄存器(500kbps,假设晶振16MHz) SJA1000_WriteReg(BTR0, 0x01); // SJW=1, BRP=1 SJA1000_WriteReg(BTR1, 0x1C); // TSEG1=13, TSEG2=2, SAM=1 // 配置输出控制寄存器(正常输出模式) SJA1000_WriteReg(OCR, 0xAA); // 退出复位模式 SJA1000_WriteReg(CR, 0x00); // CR.0 = 0 }
**(2) 发送报文
void SJA1000_SendMsg(uint32_t id, uint8_t *data, uint8_t len) { // 等待发送缓冲区空闲 while (!(SJA1000_ReadReg(SR) & 0x04)); // TBS=1 // 写入标识符(标准帧) SJA1000_WriteReg(TXB_ID0, (id >> 3) & 0xFF); SJA1000_WriteReg(TXB_ID1, (id << 5) & 0xE0); // 写入数据长度和数据 SJA1000_WriteReg(TXB_DLC, len); for (uint8_t i = 0; i < len; i++) { SJA1000_WriteReg(TXB_DATA0 + i, data[i]); } // 启动发送 SJA1000_WriteReg(CMR, 0x01); // TR=1 }
**(3) 接收报文
uint8_t SJA1000_ReceiveMsg(uint32_t *id, uint8_t *data) { // 检查接收缓冲区状态 if (!(SJA1000_ReadReg(SR) & 0x01)) return 0; // RBS=0,无报文 // 读取标识符(标准帧) *id = ((SJA1000_ReadReg(RXB_ID1) >> 5) & 0x07) << 8; *id |= SJA1000_ReadReg(RXB_ID0); // 读取数据长度和数据 uint8_t len = SJA1000_ReadReg(RXB_DLC) & 0x0F; for (uint8_t i = 0; i < len; i++) { data[i] = SJA1000_ReadReg(RXB_DATA0 + i); } // 释放接收缓冲区 SJA1000_WriteReg(CMR, 0x04); // RRB=1 return len; }
**5. 常见问题与解决方案
问题现象 | 可能原因 | 解决方案 |
---|---|---|
无法发送报文 | 发送缓冲区未释放 | 确保上一帧发送完成后(TCS=1)再发送 |
接收不到报文 | 验收滤波器配置错误 | 检查ACR/AMR寄存器,或临时设为全接收 |
频繁进入总线关闭状态 | 物理层问题(如终端电阻缺失) | 添加120Ω终端电阻,检查布线 |
波特率不匹配 | BTR0/BTR1配置错误 | 根据晶振频率和目标波特率重新计算 |
中断未触发 | 中断使能位未设置 | 在ICR寄存器中使能接收中断(RIE=1) |
**6. 总结与建议
适用场景:
SJA1000适合对成本敏感、对CAN功能需求较基础的应用(如工业传感器网络)。
升级替代:
若需更高级功能(如CAN FD、时间触发通信),可考虑MCP2515或NXP的TJA1145。
调试技巧:
使用CAN分析仪(如PCAN-USB)实时监控总线报文,快速定位问题。
通过以上内容,可系统性地掌握SJA1000的硬件连接、软件配置和通信流程。SJA1000虽为经典芯片,但通过合理设计仍能满足许多现代CAN总线应用的需求。
责任编辑:Pan
【免责声明】
1、本文内容、数据、图表等来源于网络引用或其他公开资料,版权归属原作者、原发表出处。若版权所有方对本文的引用持有异议,请联系拍明芯城(marketing@iczoom.com),本方将及时处理。
2、本文的引用仅供读者交流学习使用,不涉及商业目的。
3、本文内容仅代表作者观点,拍明芯城不对内容的准确性、可靠性或完整性提供明示或暗示的保证。读者阅读本文后做出的决定或行为,是基于自主意愿和独立判断做出的,请读者明确相关结果。
4、如需转载本方拥有版权的文章,请联系拍明芯城(marketing@iczoom.com)注明“转载原因”。未经允许私自转载拍明芯城将保留追究其法律责任的权利。
拍明芯城拥有对此声明的最终解释权。