3、CAN控制器与收发器:SJA1000、MCP2515、TJA1050选型与电路设计

做CAN总线开发,绕不开三个核心芯片:控制器和收发器。说白了,控制器负责协议处理,收发器负责电平转换。我这些年经手过不少项目,从工业设备到汽车电子,选型上踩过坑也填过坑。今天就把SJA1000、MCP2515、TJA1050这三颗经典芯片的选型要点和电路设计经验,一次性讲清楚。

3.1 控制器选型:SJA1000 vs MCP2515

先问个问题:你的主控芯片有没有内置CAN控制器?如果有,直接用。如果没有,就得外挂一颗独立的CAN控制器芯片。市面上最常见的就是NXP的SJA1000和Microchip的MCP2515。

对比项 SJA1000 MCP2515
接口类型 并行(8位数据/地址复用) SPI(最高10 MHz)
封装 DIP28 / SO28 SOIC-18 / PDIP-18
工作模式 BasicCAN / PeliCAN 标准帧 / 扩展帧
接收缓冲 64字节FIFO 2个接收缓冲 + 3个发送缓冲
滤波能力 单滤波 / 双滤波(PeliCAN) 2个验收滤波寄存器
典型主控 51单片机、ARM7 STM32、Arduino、树莓派
价格参考 ¥8-15 ¥5-10

我的选型建议:

  • 如果你用51单片机或FPGA,主控IO资源丰富,选SJA1000。并行接口速度快,实时性好。
  • 如果你用STM32、Arduino这类SPI接口丰富的主控,选MCP2515。连线少,PCB布局轻松。
  • 我个人习惯:工业控制场景优先MCP2515,因为SPI隔离容易做;汽车电子场景优先SJA1000,因为PeliCAN模式滤波更灵活。

3.2 SJA1000电路设计要点

SJA1000是经典中的经典。我最早接触CAN就是用它搭的节点。它的并行接口看起来复杂,其实只要掌握几个关键点,设计起来并不难。

3.2.1 引脚功能与连接

SJA1000的引脚分为三组:

  • 数据/地址总线:AD0-AD7,复用模式,需要配合ALE锁存地址。
  • 控制信号:CS(片选)、RD(读)、WR(写)、ALE(地址锁存使能)。
  • 时钟与复位:XTAL1/XTAL2(外接16MHz晶振)、RST(低电平复位)。

经验之谈:我曾经在一个项目中,SJA1000死活不工作,查了半天发现是ALE信号时序不对。SJA1000对ALE的脉宽有要求,至少需要23ns。如果你的主控速度太快,记得在ALE线上加一个RC延时,或者用IO口模拟ALE时序。

3.2.2 典型电路原理图

// SJA1000与51单片机连接示意
// 主控:AT89C52
// 晶振:16MHz(SJA1000侧独立晶振)

// 地址/数据总线
P0.0-P0.7 → AD0-AD7
// 控制信号
P2.0 → CS(片选,低有效)
P2.1 → ALE(地址锁存)
P2.2 → RD(读)
P2.3 → WR(写)
// 中断
P3.2 → INT(中断输出,低有效)
// 复位
P2.4 → RST(复位,低有效,需外接上拉)

注意:SJA1000的复位引脚是低电平有效,且内部没有上拉。必须在RST引脚外接10kΩ上拉电阻到VCC,否则芯片无法正常启动。我见过有人忘记加上拉,结果芯片一直处于复位状态,CAN总线毫无反应。

3.3 MCP2515电路设计要点

MCP2515是后来者,但凭借SPI接口的简洁性,迅速占领了市场。它的设计比SJA1000简单得多,但也有一些容易忽略的细节。

3.3.1 SPI通信配置

MCP2515的SPI通信模式固定为模式0(CPOL=0, CPHA=0)。时钟频率最高10 MHz。我建议实际使用时控制在5 MHz以下,尤其是长线传输时,频率高了容易丢数据。

// MCP2515 SPI初始化配置(以STM32 HAL库为例)
SPI_HandleTypeDef hspi1;

void MX_SPI1_Init(void)
{
    hspi1.Instance = SPI1;
    hspi1.Init.Mode = SPI_MODE_MASTER;
    hspi1.Init.Direction = SPI_DIRECTION_2LINES;
    hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
    hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;   // CPOL=0
    hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;       // CPHA=0
    hspi1.Init.NSS = SPI_NSS_SOFT;
    hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; // 9 MHz / 8 = 1.125 MHz
    hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
    hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
    hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
    hspi1.Init.CRCPolynomial = 10;
    HAL_SPI_Init(&hspi1);
}

3.3.2 中断与片选处理

MCP2515的INT引脚是开漏输出,需要外接上拉电阻。片选CS在每次SPI传输前拉低,传输完成后拉高。这里有个坑:MCP2515的片选不能一直拉低,否则它会认为SPI总线一直被占用,无法处理内部状态机。

避坑指南:我曾经在调试MCP2515时,发现发送数据后收不到ACK。折腾了两天,最后用示波器一看,CS信号在SPI传输结束后没有及时拉高。MCP2515的CS高电平时间至少需要1个SPI时钟周期,否则芯片会进入未知状态。解决办法:在每次SPI传输后,加一个1μs的延时再拉高CS。

3.4 收发器选型:TJA1050

收发器是CAN控制器的物理层接口。TJA1050是NXP的经典产品,替代了早期的TJA1040和PCA82C250。它的主要作用是把控制器的逻辑电平(3.3V或5V)转换为CAN总线的差分电平(CAN_H和CAN_L)。

参数 TJA1050 TJA1040 PCA82C250
工作电压 4.75V - 5.25V 4.75V - 5.25V 4.5V - 5.5V
待机电流 5 μA 10 μA 100 μA
最高速率 1 Mbps 1 Mbps 1 Mbps
斜率控制 无(固定斜率) 有(RS引脚) 有(RS引脚)
总线引脚保护 ±8 kV HBM ±6 kV HBM ±4 kV HBM
待机模式 有(STB引脚) 有(STB引脚) 无

为什么我推荐TJA1050?

  • 电磁辐射低:TJA1050优化了输出波形,EMI性能比82C250好很多。
  • 待机功耗低:5μA的待机电流,适合电池供电的节点。
  • 总线保护强:±8kV的ESD能力,省去了外部TVS管(但我不建议省,后面会讲)。

3.5 收发器电路设计:TJA1050实战

TJA1050的电路设计相对简单,但有几个关键点必须注意。我画过不下50块CAN板子,总结出下面这套标准电路。

3.5.1 标准应用电路

// TJA1050标准电路连接
// VCC = 5V

// 引脚连接
TJA1050:
  引脚1 (TXD) → 控制器TXD (MCU的CAN_TX)
  引脚2 (GND) → GND
  引脚3 (VCC) → 5V (需加100nF去耦电容)
  引脚4 (RXD) → 控制器RXD (MCU的CAN_RX)
  引脚5 (Vref) → 悬空 (或接100nF到GND)
  引脚6 (CANL) → CAN总线L线
  引脚7 (CANH) → CAN总线H线
  引脚8 (STB) → GND (正常模式) 或 MCU GPIO (待机控制)

// 总线终端电阻
CANH ── 120Ω ── CANL  (总线两端各一个)

重要提醒:TJA1050的TXD引脚不能一直为低电平。如果TXD持续低电平超过约1ms,TJA1050会进入总线错误状态,停止发送。我遇到过有人用GPIO直接控制TXD,结果程序跑飞了,TXD一直低,整个CAN总线都被拉死了。解决办法:在TXD和MCU之间串联一个1kΩ电阻,或者确保软件有超时保护。

3.5.2 保护电路设计

虽然TJA1050内部有ESD保护,但在工业现场,我建议还是加上外部保护电路。这是血的教训换来的经验。

  • TVS管:在CANH和CANL对地各加一个双向TVS管,选型SMAJ6.0CA或PESD1CAN。
  • 共模扼流圈:在CANH和CANL上串联一个共模扼流圈(如ACM2012-900-2P),抑制共模干扰。
  • 终端电阻:总线两端各一个120Ω电阻,不能省。如果节点数少,可以在每个节点上加一个120Ω,但总等效电阻必须接近60Ω。

我的习惯:在CANH和CANL之间并联一个10nF的电容,可以滤除高频噪声。但要注意,这个电容不能太大,否则会影响总线信号边沿,降低通信距离。10nF是我试过的最优值。

3.6 知识结构总览

下面这张图把控制器和收发器的选型与电路设计逻辑串起来了。你可以把它当作设计时的检查清单。

CAN控制器与收发器选型与电路设计知识结构 CAN控制器与收发器选型与电路设计 主控是否内置CAN控制器? 是 → 直接使用内置控制器 否 → 外挂独立控制器 外挂控制器选型 SJA1000 并行接口 | 16MHz晶振 MCP2515 SPI接口 | 5MHz时钟 收发器:TJA1050 电路要点:TVS保护 | 共模扼流圈 | 终端电阻120Ω

3.7 常见问题与避坑

最后,我把这些年遇到的典型问题列出来。你设计时对照检查,能省不少调试时间。

问题1:CAN总线无通信,示波器看CAN_H和CAN_L都是2.5V

原因:收发器没有进入正常模式。检查TJA1050的STB引脚是否接地。如果是通过GPIO控制,检查GPIO电平是否正确。

问题2:通信偶尔丢帧,错误帧增多

原因:终端电阻不匹配。用万用表测量CAN_H和CAN_L之间的电阻,正常应在60Ω左右(总线两端各120Ω并联)。如果只有一端有120Ω,电阻就是120Ω,信号反射严重。

问题3:MCP2515初始化失败,SPI读写无响应

原因:SPI模式不对。MCP2515只支持模式0(CPOL=0, CPHA=0)。我曾经用STM32的默认配置(模式3)去读,结果读回来的全是0xFF。检查你的SPI配置,确保CPOL和CPHA都正确。

嗯,以上就是CAN控制器和收发器选型与电路设计的全部核心内容。记住一句话:芯片选型看接口,电路设计看保护。把这两点抓住了,CAN节点设计就成功了一大半。