3、CAN控制器与收发器:常用CAN控制器芯片(SJA1000、MCP2515)、CAN收发器(TJA1050、SN65HVD230)、硬件电路设计要点
好,咱们接着聊。前面我们把CAN总线的协议层和物理层拆开讲了一遍,现在该聊聊真正干活的芯片了。
CAN控制器和收发器,说白了就是一对搭档。控制器负责“动脑子”——处理协议、打包数据、管理错误;收发器负责“跑腿”——把控制器的数字信号变成总线上的差分电平,或者反过来。我这些年调试过的板子,十有八九的问题都出在这俩芯片的搭配和外围电路上。今天就把我踩过的坑和积累的经验,一次性倒给你们。
3.1 常用CAN控制器芯片
先说说控制器。市面上主流的独立CAN控制器,其实就那么几款。我挑两个最典型的讲:一个是老当益壮的SJA1000,另一个是SPI接口的MCP2515。
3.1.1 SJA1000:经典中的经典
SJA1000是NXP(原Philips)的产品,这芯片年头不短了,但至今还在大量使用。为什么?因为它稳定、皮实、资料多。
核心特点:
- 支持CAN 2.0A和CAN 2.0B协议
- 并行接口,直接挂在MCU的地址/数据总线上
- 内置64字节的接收FIFO
- 支持多种工作模式:BasicCAN、PeliCAN
我个人习惯用PeliCAN模式。BasicCAN模式太老了,帧格式受限,现在基本没人用。PeliCAN模式下,你可以访问到所有扩展帧、错误计数器、仲裁丢失捕获这些高级功能。
重要提醒:SJA1000的复位引脚/RST是低电平有效。我见过有人把它直接悬空,结果芯片偶尔不工作,查了半天才发现是复位引脚没拉高。记住,不用的复位引脚一定要接VCC。
典型电路连接:
MCU (如STM32) SJA1000
----------------- -------------
FSMC/并行总线 <---> AD0-AD7 (地址/数据复用)
FSMC/NOE ---> /RD (读使能)
FSMC/NWE ---> /WR (写使能)
FSMC/NCS ---> /CS (片选)
GPIO ---> /RST (复位,接上拉)
GPIO ---> INT (中断输出,可选)
嗯,这里要注意:SJA1000的时钟输入最高16MHz,一般用16MHz晶振。如果你用MCU的时钟输出直接驱动,记得检查频率对不对。我在一个项目里就吃过这个亏——MCU输出的是12MHz,SJA1000也能跑,但波特率计算会出偏差,导致通信不稳定。
3.1.2 MCP2515:SPI接口的灵活之选
MCP2515是Microchip的产品。它最大的优势就是SPI接口。如果你的MCU引脚不够,或者不想用并行总线占用太多IO,MCP2515就是救星。
核心特点:
- 支持CAN 2.0A和CAN 2.0B
- SPI接口,最高时钟10MHz
- 内置两个接收缓冲器、三个发送缓冲器
- 支持单次发送、回环模式(调试利器)
我的小技巧:调试MCP2515时,先把芯片设成回环模式。这样发送的数据自己就能收到,不用接其他节点。我曾经用这个模式在实验室里一个人调通了整个协议栈,省了不少联调时间。
SPI通信时序要点:
// MCP2515 SPI指令示例
// 读寄存器
uint8_t mcp2515_read_reg(uint8_t addr) {
uint8_t data;
CS_LOW();
spi_transfer(MCP_READ); // 发送读指令 0x03
spi_transfer(addr); // 发送寄存器地址
data = spi_transfer(0x00); // 读取数据
CS_HIGH();
return data;
}
// 写寄存器
void mcp2515_write_reg(uint8_t addr, uint8_t data) {
CS_LOW();
spi_transfer(MCP_WRITE); // 发送写指令 0x02
spi_transfer(addr); // 发送寄存器地址
spi_transfer(data); // 发送数据
CS_HIGH();
}
你想想看,SPI接口虽然方便,但有个缺点:每次读写都需要MCU主动发起。如果CAN总线突然来了一帧紧急数据,MCP2515只能通过INT引脚通知MCU。所以INT中断引脚一定要接,别省。
3.2 常用CAN收发器
控制器搞定了,接下来是收发器。收发器直接面对总线,环境最恶劣。我选收发器时,主要看三点:速率、耐压、EMC性能。
3.2.1 TJA1050:高速CAN的标杆
TJA1050也是NXP的产品,是TJA1040的升级版。它支持最高1Mbps的速率,适合高速CAN应用。
关键参数:
| 参数 | 典型值 | 说明 |
|---|---|---|
| 电源电压 | 4.75V ~ 5.25V | 标准5V供电 |
| 总线引脚耐压 | -27V ~ +40V | 短时保护能力 |
| 循环延迟 | 典型150ns | 影响最大总线长度 |
| 待机模式电流 | < 10μA | 低功耗场景有用 |
TJA1050有个很贴心的设计:它的CANH和CANL引脚在芯片内部做了限流和ESD保护。我曾经不小心把24V电源搭到CANH上,芯片居然没烧,只是通信断了。断电重启后一切正常。嗯,别学我,这只是运气好。
3.2.2 SN65HVD230:3.3V系统的福音
如果你的MCU是3.3V的,比如STM32F4系列,那SN65HVD230就是绝配。它不需要额外的电平转换,直接和3.3V控制器对接。
核心特点:
- 3.3V单电源供电
- 支持1Mbps速率
- 低功耗待机模式
- 总线引脚耐压-4V ~ +7V(比TJA1050弱一些)
注意:SN65HVD230的耐压范围比TJA1050窄。如果你的总线可能受到外部高压干扰(比如在工业现场),建议在总线入口加TVS管。我曾经在一个项目中没加保护,结果一次雷击浪涌测试,烧了三个节点的收发器。从那以后,TVS管成了我的标配。
3.3 硬件电路设计要点
芯片选好了,电路设计才是真正见功夫的地方。我总结了几条铁律,你们记好。
3.3.1 终端电阻:必须加,位置要对
CAN总线两端各需要一颗120Ω的终端电阻。为什么是120Ω?因为CAN总线用的双绞线特性阻抗大约是120Ω。终端电阻的作用是吸收信号反射,防止波形畸变。
常见错误:
- 只在总线一端加电阻——反射没消除干净
- 电阻值用100Ω或150Ω——阻抗不匹配,信号质量差
- 电阻放在节点内部,但节点离总线末端很远——等效于没加
我建议的做法是:在PCB上预留1206封装的120Ω电阻位置,调试时用示波器看CANH和CANL的差分波形。如果波形边沿有过冲或振铃,再调整电阻位置或阻值。
3.3.2 电源去耦:别省那几颗电容
CAN收发器在工作时,瞬间电流变化很大。特别是从隐性到显性切换时,电流可能跳变几十毫安。如果电源去耦不好,总线波形上会出现毛刺,严重时会导致误码。
我的标准配置:
// 每个CAN收发器的电源去耦
// 靠近VCC引脚
C1: 10μF 电解电容 // 低频去耦
C2: 0.1μF 陶瓷电容 // 高频去耦
// 如果空间允许,再加一个
C3: 0.01μF 陶瓷电容 // 超高频去耦
你想想看,这三颗电容加起来不到一毛钱,但能省掉你多少调试时间。我在一个项目里遇到过CAN通信偶尔丢帧,查了两天才发现是0.1μF电容虚焊了。补焊后问题消失。
3.3.3 共模扼流圈:EMC的守护神
如果你的产品要做CE认证,或者要过EMC测试,共模扼流圈几乎是必须的。它串联在CANH和CANL上,能抑制共模干扰,同时不影响差模信号。
选型建议:
| 参数 | 推荐值 | 说明 |
|---|---|---|
| 共模电感 | 51μH ~ 100μH | 太大会影响信号上升时间 |
| 额定电流 | > 100mA | 留足余量 |
| 直流电阻 | < 0.5Ω | 压降不能太大 |
我的经验:共模扼流圈要放在靠近总线连接器的位置。如果放在收发器旁边,效果会打折扣。因为从扼流圈到连接器之间的走线,仍然可能耦合干扰。
3.3.4 保护电路:不怕一万,就怕万一
CAN总线经常要拉到车外或者设备外部,难免遇到静电、浪涌、甚至电源搭错。保护电路就是最后一道防线。
推荐保护方案:
// 从总线连接器到收发器的路径
// 1. 先过共模扼流圈
// 2. 然后接TVS管到GND
// 3. 再经过限流电阻(10Ω~22Ω)
// 4. 最后到收发器的CANH/CANL引脚
// TVS管选型
// 双向TVS,工作电压5V~7V
// 钳位电压< 20V
// 功率> 400W (8/20μs波形)
// 推荐型号:PESD1CAN、NUP2105L
我曾经在一个项目中,客户要求总线能承受±60V的误接。我们加了TVS管和PTC自恢复保险丝,实测通过了。虽然成本增加了两块钱,但换来了产品的可靠性,值。
3.3.5 PCB布局布线要点
最后说说PCB设计。这部分容易被忽略,但往往是成败的关键。
布局原则:
- 收发器尽量靠近总线连接器,走线越短越好
- 控制器和收发器之间的距离也要短,减少数字噪声耦合
- 去耦电容紧贴芯片VCC引脚,地线先过电容再到芯片
布线原则:
- CANH和CANL走差分线,线宽10mil,间距10mil
- 差分线两侧包地,每隔1cm加一个地过孔
- 避免在差分线下方走其他高速信号
- 如果必须换层,成对打过孔,保持等长
核心总结:CAN硬件设计,说白了就是三件事:选对芯片、加好保护、布好走线。控制器和收发器的搭配要匹配,电源去耦不能省,终端电阻位置要对,保护电路要留余量。做到这几点,你的CAN总线就能稳定工作。
好了,这一章的内容就到这里。下一章我们聊聊CAN总线的软件协议栈实现,包括报文过滤、错误处理、以及如何用状态机管理CAN通信。到时候我会分享一个我自己写的轻量级CAN协议栈,你们可以直接拿去用。