第3章 CAN控制器与收发器:SJA1000/MCP2515介绍、TJA1050收发器、硬件电路设计要点

好,咱们进入硬件层面。很多做BMS的工程师,软件写得飞起,一碰到硬件电路就头大。其实CAN通信的硬件没那么玄乎,核心就两个东西:控制器收发器。搞明白这俩家伙,电路设计就稳了一半。

3.1 CAN控制器:协议栈的“大脑”

控制器负责处理CAN协议的数据链路层。说白了,它帮你把要发的数据打包成CAN帧,也帮你把收到的帧解析成数据。你只需要读写它的寄存器就行,不用自己拼比特流。

3.1.1 独立控制器:SJA1000

SJA1000是NXP(原Philips)的经典芯片。我入行那会儿,很多项目还在用它的前身——82C200。SJA1000算是升级版,支持CAN 2.0B,也就是能处理29位扩展帧。

核心特点:

  • 两种模式:BasicCAN模式(兼容老芯片)和PeliCAN模式(新功能全开)。我个人习惯直接用PeliCAN,功能完整。
  • 验收滤波器:可以设置4个验收码和4个屏蔽码。这玩意儿很实用,能过滤掉你不关心的报文,减轻MCU负担。
  • 接口:并行接口,直接挂在MCU的地址/数据总线上。
我的经验: SJA1000的并行接口虽然快,但占用IO多。如果你MCU引脚紧张,可以考虑SPI接口的控制器,比如MCP2515。

3.1.2 SPI接口控制器:MCP2515

MCP2515是Microchip的产品。它通过SPI和MCU通信,只需要4根线(SCK、MOSI、MISO、CS)。对于引脚少的MCU,简直是救星。

核心特点:

  • SPI速率:最高10MHz。实际项目中我一般跑5MHz,稳定第一。
  • 缓冲区:内置2个接收缓冲器、3个发送缓冲器。够用,但别指望它像高端芯片那样有FIFO。
  • 中断:支持多种中断源,比如接收中断、发送完成中断、错误中断。

MCP2515初始化代码片段(伪代码):

// 1. 复位
SPI_Write(0xC0); // 复位指令

// 2. 配置CAN波特率(假设500kbps,晶振16MHz)
// 配置CNF1、CNF2、CNF3寄存器
SPI_Write_Register(0x2A, 0x00); // CNF1: SJW=1, BRP=0
SPI_Write_Register(0x2B, 0x90); // CNF2: PHSEG1=3, PRSEG=1, SAM=1
SPI_Write_Register(0x2C, 0x02); // CNF3: PHSEG2=2

// 3. 设置验收滤波器
SPI_Write_Register(0x00, 0x00); // RXF0SIDH
SPI_Write_Register(0x01, 0x00); // RXF0SIDL

// 4. 进入正常模式
SPI_Write_Register(0x0F, 0x00); // CANCTRL: 请求正常模式
注意: MCP2515的SPI操作有严格的时序要求。我曾经遇到过因为SPI时钟极性配置反了,导致读写寄存器全乱套的情况。调试了整整一天才发现是CPOL/CPHA没设对。

3.2 CAN收发器:信号转换的“桥梁”

控制器输出的是逻辑电平(通常是3.3V或5V),但CAN总线需要的是差分信号。收发器就是干这个活的——把逻辑电平转成CAN_H和CAN_L的差分电压。

3.2.1 TJA1050收发器

TJA1050是NXP的经典收发器,也是我项目里用得最多的。它替代了老旧的PCA82C250,性能更好。

关键参数:

参数 说明
工作电压 4.75V ~ 5.25V 标准5V供电
速率 最高1Mbps BMS常用250k或500k
待机模式 支持 通过STB引脚控制
显性/隐性电平 显性:CAN_H≈3.5V,CAN_L≈1.5V
隐性:CAN_H≈2.5V,CAN_L≈2.5V
差分信号

引脚功能:

  • TXD:发送数据输入(来自控制器)
  • RXD:接收数据输出(给控制器)
  • CANH / CANL:总线差分信号
  • STB:待机模式控制(低电平有效)
  • VREF:参考电压输出(通常不用,悬空即可)
为什么选TJA1050? 它的电磁辐射低,而且对总线故障有很好的保护。我在BMS项目里用过,即使CAN_H和电源短路,芯片也不会烧。这一点很重要,因为BMS工作环境复杂,线束容易出问题。

3.3 硬件电路设计要点

电路设计是门手艺活。同样的芯片,不同人画出来的板子,通信稳定性可能天差地别。下面是我总结的几个关键点。

3.3.1 终端电阻

CAN总线两端必须各接一个120Ω电阻。为什么?为了匹配总线阻抗,防止信号反射。

设计建议:

  • 电阻放在总线的最远端节点上。
  • 如果节点数量少,可以直接在PCB上焊死。
  • 如果节点多,建议用可插拔的终端电阻模块,方便调试。
避坑指南: 我曾经在一个项目里,因为终端电阻焊错了位置(放在了中间节点),导致总线信号过冲严重,通信时好时坏。查了两天才发现是电阻位置不对。

3.3.2 电源与去耦

收发器对电源噪声很敏感。尤其是TJA1050,它的TXD和RXD引脚直接和控制器相连,电源纹波大会导致误码。

我的做法:

  • 在收发器的VCC引脚旁边放一个100nF的陶瓷电容,尽量靠近引脚。
  • 如果空间允许,再加一个10μF的电解电容。
  • 控制器的电源和收发器的电源最好分开走线,避免数字噪声串扰。

3.3.3 共模扼流圈

在CANH和CANL线上串一个共模扼流圈(Common Mode Choke),可以有效抑制共模干扰。BMS里电机驱动、DC-DC变换器都是强干扰源,不加这个,通信很容易丢包。

选型建议:

  • 电感值:100μH ~ 1mH
  • 额定电流:大于总线最大电流(通常100mA足够)
  • 封装:越小越好,但别为了省空间选太小的,否则饱和电流不够。

3.3.4 ESD保护

CAN总线是暴露在外的,插拔连接器时很容易产生静电放电。不加保护,收发器可能一次就报废。

推荐方案:

  • 在CANH和CANL对地各加一个TVS管(比如PESD1CAN)。
  • TVS管的结电容要小(<5pF),否则会影响信号质量。
  • 如果成本敏感,可以用齐纳二极管代替,但效果差一些。
重要提醒: ESD保护器件要尽量靠近连接器放置。我见过有人把TVS管放在收发器旁边,结果静电还是从连接器一路打到了收发器。保护路径越长,效果越差。

3.3.5 典型电路参考

下面是一个典型的CAN节点电路(以MCP2515 + TJA1050为例):

MCU ----SPI----> MCP2515 ----TXD/RXD----> TJA1050 ----CANH/CANL----> 总线
                    |                    |                    |
                  3.3V                  5V                  120Ω + TVS

关键连接点:

  • MCP2515的TXD接TJA1050的TXD
  • MCP2515的RXD接TJA1050的RXD
  • TJA1050的STB引脚通过10kΩ电阻上拉到5V(正常模式)
  • CANH和CANL之间跨接120Ω终端电阻
  • CANH和CANL对地各接一个TVS管

嗯,硬件设计这块,说白了就是细节决定成败。你照着数据手册画,大概率能工作,但要想稳定可靠,就得把上面这些点都考虑到。我在BMS项目里吃过不少亏,后来总结出这套设计规范,基本没再出过通信硬件问题。

下一章,咱们聊聊CAN报文的结构和解析。那才是真正和协议打交道的地方。