3. CAN控制器与收发器:SJA1000/MCP2515介绍、TJA1050收发器、硬件接口设计
好,咱们进入第三章。前面聊了CAN协议的基础,说白了就是一堆电信号在总线上跑。那这些信号是谁产生的?又是谁把它变成差分电压的?答案就是今天的主角——CAN控制器和收发器。
我经常跟学员说一句话:控制器是大脑,收发器是嘴巴和耳朵。大脑想说什么,嘴巴把它喊出去;耳朵听到声音,再传给大脑。就这么简单。
3.1 CAN控制器:SJA1000 vs MCP2515
先看控制器。市面上主流的独立CAN控制器,绕不开两个型号:NXP的SJA1000和Microchip的MCP2515。我两个都用过,各有脾气。
3.1.1 SJA1000——老将出马
SJA1000是飞利浦(现NXP)的经典产品,从90年代就开始服役了。它支持两种模式:BasicCAN和PeliCAN。PeliCAN是扩展模式,支持2.0B协议,也就是29位标识符。
| 特性 | SJA1000 | MCP2515 |
|---|---|---|
| 接口 | 并行(8位) | SPI(最高10MHz) |
| 支持协议 | CAN 2.0A/B | CAN 2.0A/B |
| 接收缓冲 | 64字节FIFO | 2个接收缓冲 + 3个掩码 |
| 工作电压 | 5V | 3.3V / 5V |
| 封装 | DIP28 / SO28 | SOIC18 / DIP18 |
SJA1000最大的特点就是并行接口。这意味着你需要至少8根数据线加若干控制线才能跟MCU通信。我记得第一次用SJA1000搭电路,光布线就折腾了半天,引脚太多,走线绕来绕去。
3.1.2 MCP2515——后起之秀
MCP2515是Microchip推出的SPI接口CAN控制器。它只有18个引脚,通过SPI跟MCU通信,只需要4根线:SCK、MOSI、MISO、CS。省引脚,省布线,省心。
我做过一个项目,MCU只有20个IO口,还要控制LCD、按键、传感器。如果用SJA1000,IO口根本不够分。换成MCP2515,只用了4个SPI引脚,剩下的全给外设。嗯,这就是它存在的意义。
MCP2515内部有2个接收缓冲器和3个验收滤波掩码。你可以配置只接收特定ID的报文,减少MCU的负担。这一点在网关项目中特别有用——比如只让发动机相关的报文通过,其他的一律过滤掉。
- MCU引脚多、要求实时性高 → SJA1000(并行访问速度快)
- MCU引脚少、追求布线简单 → MCP2515(SPI接口省引脚)
- 需要多路CAN → 两个都能用,但MCP2515更容易扩展
3.2 TJA1050收发器——信号的中转站
控制器输出的是逻辑电平(0或1),但CAN总线需要的是差分信号(CAN_H和CAN_L之间的电压差)。这个转换工作,就交给收发器。
TJA1050是NXP出品的高速CAN收发器,支持最高1Mbps的速率。它替代了早期的TJA1040和PCA82C250,在电磁兼容性上做了优化。
3.2.1 TJA1050的引脚功能
| 引脚 | 名称 | 功能 |
|---|---|---|
| 1 | TXD | 发送数据输入(来自控制器) |
| 2 | GND | 地 |
| 3 | VCC | 电源(5V) |
| 4 | RXD | 接收数据输出(给控制器) |
| 5 | VREF | 参考电压输出(一般悬空) |
| 6 | CANL | CAN低电平总线 |
| 7 | CANH | CAN高电平总线 |
| 8 | STB | 待机模式控制(低电平待机) |
TJA1050有个待机模式,通过STB引脚控制。拉低STB,收发器进入低功耗状态,电流降到微安级。这在车载ECU休眠时特别有用。我曾经调试过一个项目,总线上的节点在休眠后还在发报文,查了半天发现是STB引脚没拉高,收发器根本没睡。
3.3 硬件接口设计——从原理图到PCB
好了,芯片选完了,怎么把它们连起来?我画个结构图给你看。
3.3.1 典型电路设计
下面是一个MCP2515 + TJA1050的典型电路。我直接给你看关键部分。
// MCP2515与TJA1050连接示意
// MCU (SPI) → MCP2515 → TJA1050 → CAN总线
// MCP2515引脚分配
// CS → PB0 (片选)
// SCK → PB1 (SPI时钟)
// SI → PB2 (MOSI)
// SO → PB3 (MISO)
// INT → PD2 (中断输出)
// TJA1050连接
// TXD → MCP2515 TXCAN
// RXD → MCP2515 RXCAN
// STB → GND (正常模式)
// VREF → 悬空
// 总线终端电阻
// CAN_H 与 CAN_L 之间接 120Ω 电阻
// 总线两端各一个,不能少
这里有个细节:终端电阻。CAN总线两端必须各接一个120Ω电阻,作用是匹配阻抗、消除信号反射。我见过有人偷懒只接一个,结果总线在高速通信时波形乱七八糟,丢帧严重。
3.3.2 电源与去耦
CAN收发器工作时会产生瞬态电流,电源必须做好去耦。我的习惯是:
- 每个芯片的VCC引脚旁边放一个100nF陶瓷电容,尽量靠近引脚
- 再加一个10μF电解电容做储能
- 电源走线要宽,至少20mil
- CAN_H和CAN_L走线要平行,远离时钟线
嗯,这些看起来是小细节,但往往就是这些小细节决定了产品能不能过EMC测试。
3.3.3 共模扼流圈与保护
车载环境很恶劣,总线可能会受到各种干扰。我建议在CAN_H和CAN_L上串联共模扼流圈(Common Mode Choke),它能抑制共模干扰,同时不影响差分信号。
另外,别忘了加ESD保护管。我选的是NUP2105L,专门用于CAN总线,结电容低,不影响信号质量。
3.4 实战案例:一个双节点CAN通信系统
最后,我带你走一遍实际搭建过程。假设我们要做两个节点:
- 节点A:STM32F103 + MCP2515 + TJA1050
- 节点B:STM32F103 + MCP2515 + TJA1050
- 总线:双绞线,两端各一个120Ω电阻
接线步骤:
- 两个节点的CAN_H接在一起,CAN_L接在一起
- 总线两端各并联一个120Ω电阻
- 所有节点共地(GND连在一起)
- 上电,用示波器看CAN_H和CAN_L的波形
正常波形应该是:隐性时CAN_H≈2.5V,CAN_L≈2.5V;显性时CAN_H≈3.5V,CAN_L≈1.5V。如果你看到波形不对,先检查终端电阻和电源。
- 波形不对 → 查终端电阻
- 通信丢帧 → 查电源去耦
- 节点不上线 → 查TXD是否被拉低
- 速率上不去 → 查共模扼流圈和ESD管