2. OBD硬件接口与协议:OBD-II物理接口定义(16针脚定义),CAN总线协议详解(CAN 2.0A/B),单线CAN与双线CAN的区别
好,咱们直接进入正题。这一章聊的是OBD系统的“物理层”和“数据链路层”。说白了,就是你的诊断仪插到车上那个接口,到底是怎么定义的?里面的针脚都干嘛用的?以及车里面那些模块之间是怎么通过CAN总线“说话”的。
我个人习惯,做诊断开发,第一步一定是把硬件接口吃透。不然你软件写得再好,线接错了,或者协议选错了,全是白搭。我在项目里就见过有人把CAN_H和CAN_L接反了,结果通讯死活调不通,查了一整天。
2.1 OBD-II物理接口:16针脚定义
OBD-II接口,就是车上那个梯形的、16个针脚的插座。标准叫法是SAE J1962。你想想看,这个接口从1996年在美国强制推行,到现在快30年了,几乎所有的乘用车和轻型卡车都在用。
这16个针脚,并不是每个都有用。很多是“预留”或者“厂商自定义”的。咱们重点看那些通用的、你一定会用到的。
| 针脚号 | 信号定义 | 说明 |
|---|---|---|
| 1 | 厂商自定义 | GM常用,比如J2411单线CAN |
| 2 | J1850 Bus+ | 福特/通用老协议,现在很少见了 |
| 3 | 厂商自定义 | 福特DLC,或者其它 |
| 4 | 底盘地 (Chassis Ground) | 直接连车架,大电流回路 |
| 5 | 信号地 (Signal Ground) | 传感器和逻辑电路参考地 |
| 6 | CAN High (CAN_H) | ISO 15765-4 标准,高速CAN |
| 7 | K-Line (ISO 9141-2) | 欧系老车常用,单线通讯 |
| 8 | 厂商自定义 | 很多车用来做唤醒或其它 |
| 9 | 厂商自定义 | LIN总线或其它低速网络 |
| 10 | J1850 Bus- | 与针脚2配对使用 |
| 11 | 厂商自定义 | 福特、马自达等 |
| 12 | 厂商自定义 | 常用于气囊或其它 |
| 13 | 厂商自定义 | 常用于防盗或其它 |
| 14 | CAN Low (CAN_L) | 与针脚6配对,组成差分对 |
| 15 | L-Line (ISO 9141-2) | K-Line的辅助线,很少用 |
| 16 | 电池正极 (Battery +) | 常电,12V/24V,给诊断仪供电 |
核心要点:你只需要记住4、5、6、14、16这五个针脚。4和5是地,16是电源,6和14是CAN总线。搞定这五个,90%的现代车你都能连上。
嗯,这里要注意一点。针脚4(底盘地)和针脚5(信号地)在车内通常是连在一起的,但设计上它们是分开的。底盘地用来走大电流,比如驱动继电器;信号地是给ECU内部逻辑用的。我建议你在做诊断仪设计时,这两个地最好在PCB上单点连接,避免地环路干扰。
2.2 CAN总线协议详解:CAN 2.0A/B
CAN总线,全称是Controller Area Network。这玩意儿是德国博世公司在80年代发明的,初衷是为了减少汽车线束。你想想看,以前的车,一个传感器一根线,全车线束能绕地球一圈。CAN总线出来以后,所有ECU都挂在一对双绞线上,数据共享,清爽多了。
CAN协议有两个版本:CAN 2.0A 和 CAN 2.0B。它们的区别,说白了就是“身份证号码”的长度不一样。
- CAN 2.0A:标准帧,ID是11位。最多支持2^11 = 2048个不同的ID。
- CAN 2.0B:扩展帧,ID是29位。最多支持2^29 = 5亿多个ID。
为什么会这样?因为后来车上的ECU越来越多,11位ID不够用了。比如一个高端车型,可能有上百个ECU,每个ECU又发几十种信号,2048个ID很快就用完了。所以CAN 2.0B就出来了,把ID扩展到29位。
我个人习惯,在开发诊断工具时,默认都支持CAN 2.0B。因为现在的车,尤其是德系车,几乎全用扩展帧。你如果只支持标准帧,很多数据都收不到。
咱们来看一个CAN数据帧的结构,这是最核心的:
帧起始 (SOF) - 1位
仲裁域 (Arbitration Field) - 11位 (标准) 或 29位 (扩展)
控制域 (Control Field) - 6位
数据域 (Data Field) - 0~8字节
CRC域 (CRC Field) - 16位
应答域 (ACK Field) - 2位
帧结束 (EOF) - 7位
这里我重点说一下仲裁域。CAN总线有个很牛的特性:多主通讯。也就是说,多个ECU可以同时往总线上发数据,不会冲突。怎么做到的?靠“线与”逻辑和仲裁机制。
每个CAN帧都有一个ID,ID越小,优先级越高。如果两个ECU同时发数据,总线会逐位比较ID。谁的ID是0(显性位),谁就赢;谁的ID是1(隐性位),谁就自动退出发送,等下次再试。这个机制,保证了高优先级的数据(比如刹车信号)永远不会被低优先级的数据(比如车窗信号)阻塞。
避坑指南:我曾经在项目里遇到过一个问题:两个ECU的CAN ID设置得太接近,导致仲裁时频繁冲突,总线负载率飙升。后来我建议把关键信号的ID设得小一些,比如0x100以内,非关键信号设大一些,比如0x700以上。这样仲裁一次就搞定,效率高很多。
2.3 单线CAN与双线CAN的区别
说到单线CAN和双线CAN,很多人容易搞混。其实它们完全是两码事。
双线CAN,就是我们上面说的标准CAN总线。它用一对双绞线(CAN_H和CAN_L)传输信号,采用差分电压。CAN_H比CAN_L高2V时,表示显性位(逻辑0);两者电压相等时,表示隐性位(逻辑1)。这种差分传输抗干扰能力极强,适合高速、远距离通讯。速率最高能到1Mbps,车上常用的是250kbps或500kbps。
单线CAN,也叫GMLAN或SAE J2411。它只有一根线(SW CAN),对地传输电压。高电平表示显性,低电平表示隐性。速率很低,通常只有33.33kbps或83.33kbps。抗干扰能力差,但成本低,线束少。
它们的区别,我列个表你就清楚了:
| 特性 | 双线CAN (ISO 11898) | 单线CAN (SAE J2411) |
|---|---|---|
| 物理介质 | 双绞线 (CAN_H + CAN_L) | 单根线 (SW CAN) |
| 传输方式 | 差分电压 | 单端电压 |
| 最高速率 | 1 Mbps | 83.33 kbps |
| 抗干扰能力 | 强 | 弱 |
| 典型应用 | 动力总成、底盘、ADAS | 车身控制、门窗、座椅 |
| OBD接口针脚 | 6 (CAN_H) 和 14 (CAN_L) | 1 (GM专用) |
你想想看,为什么会有单线CAN?说白了就是为了省钱。像车窗、门锁这种低速信号,用双线CAN太浪费了。单线CAN一根线搞定,成本降低一半。但代价就是速率低、抗干扰差。所以单线CAN只用在车身舒适系统上,动力系统绝对不敢用。
警告:千万不要把单线CAN的收发器直接接到双线CAN总线上!电平不匹配,会烧芯片。我见过有人图省事,把GMLAN的模块挂到高速CAN上,结果模块的收发器直接冒烟了。一定要用对应的收发器芯片,比如TJA1050用于双线CAN,MC33897用于单线CAN。
好了,这一章的内容就这些。总结一下:OBD接口记住4、5、6、14、16;CAN协议记住2.0A和2.0B的区别;单线CAN和双线CAN记住应用场景和速率差异。下一章咱们聊诊断协议,那才是真正开始写代码的地方。