Wednesday, 09 December 2020 10:10

ISO15765-4协议-初始化和读车架号的代码实现(源自C300开发板教程) Featured

在NL_OBD_SendCANFrame函数的支持下,OBD诊断程序的开发就会变得简单,我们只需关注ISO15031-5协议的功能实现即可,网络层,数据链路层等底层处理由NL_OBD_SendCANFrame函数完成。

下面是C300车联网开发板第一版软件关于OBD诊断程序代码截图。

图片

图中我们看到第一版本软件主要实现读车架号,读故障码,读数据流三大基本OBD诊断信息,同时还有一个协议初始化函数。下面我们就围绕这四方面应用程序代码进行具体分析讲解。

ISO15765-4初始化

图中代码片段82行通过调用ISO15765_4_WakeUp函数,如果它的返回值是NL_OK表示初始化成功。下面截图分析ISO15765_4_WakeUp函数源码,了解初始化的过程。

 

图片

ISO15765_4_WakeUp函数有两个参数,参数1是CAN通信速率,其值我已经用宏定义进行了定义分别是CAN_500K,CAN_250K,CAN_125K,这三个速率已经涵盖了法规诊断协议和增强型诊断协议也就是专车私有协议的速率。更多速率可以通过计算分频值获得,这部分内容在第6章的6.1.2小节 CAN配置中学习。参数2是诊断协议类型,只能填ISO15765_4STD_500K和ISO15765_4EXT_500K这两个协议。

31行对协议类型进行判断,如果是ISO15765_4STD_500K标准CAN协议执行33行到35行。如果是ISO15765_4EXT_500K扩展CAN协议执行39行到41行。首先看标准CAN协议33行NL_OBD_SelectCAN函数,这个函数是用来选择OBD 接口CAN通信引脚的,参数分别是有CAN_6_14和CAN_3_11。CAN_6_14选择OBD接口的6和14引脚作为CAN通信,6是CANH,14是CANL。CAN_3_11选择OBD接口的3和11引脚作为CAN通信,3是CANH,11是CANL。对于法规协议ISO15765-4协议,CAN通信引脚被固定定义为OBD接口的6和14引脚,所以此处函数NL_OBD_SelectCAN(CAN_6_14)。34行NL_OBD_CANConfig函数主要用于设置CAN通信的速率,CAN的IDE类型和滤波器,第1个参数用于设置CAN速率,第2参数用于设置CAN的IDE类型,也就是标准CAN通信还是扩展CAN通信,第3个参数用于设置滤波器,当前滤波器设置值为0x7e0,0x7e0,0x7f0,0x7f0,这个值的设置和我们的OBD分析仪上位机滤波器设置是一摸一样的,由两组滤波器组成,四个值分别代表 滤波器1屏蔽码,滤波器2屏蔽码,滤波器1校验码,滤波器2校验码,因为在ISO15765-4协议关于标识符定义我们知道,标准CAN效应数据的高7位值都固定是0x7e,所以过滤器屏蔽码0x7e0,而效验码0x7f0,只比较高7位是否是0x7e,低4位忽略即可。35行通过NL_OBD_SendCANFrame函数发送EntCmd15765请求数据,注意这个请求数据的SID=0x01,PID=0x00,这是ISO15765-4协议推荐我们使用的初始化请求数据,也是ISO15031-5协议定义的Supported PID请求数据,而当前版本软件我们并没有做Supported PID列表,这将在第二版软件根据实际需求添加上该部分代码。如果NL_OBD_SendCANFrame函数第3个参数值err=NL_OK,说明接收到了针对SID=0x01,PID=0x00的响应数据,证明当前汽车支持ISO15765_4STD_500K协议。接下来的ISO15765_4EXT_500K扩展CAN协议基本类似,39行和41行函数和标准CAN类似。这里主要讲解下40行的扩展CAN滤波器设置,根据ISO15765-4关于扩展CAN请求和响应标识符的定义,响应数据的标识符高13位是不变的,低16位是两个字节,分别表示目标地址和源地址,传输方向的不同,且物理硬件的不同,值都会发生变化。所以只有高13位0x18DA是固定的。针对这个情况滤波器设置值为0x18DA0000,0x18DA0000,0x1FFF0000,0x1FFF0000,两组滤波器过滤判断一样,比较高13位的值必须是0x18DA,低16位忽略比较。

读车架号

下面截图是读车架号的代码片段。

图片

87行判断OBDStruct.VINStruct.VIN是否存储了读到的车架号,如果OBDStruct.VINStruct.flag的值是RESET表示OBDStruct.VINStruct.VIN值是空的或者没有更新的;OBDStruct.VINStruct.flag的值是SET表示读到了车架号并存储在OBDStruct.VINStruct.VIN中。同时OBDStruct.VINStruct.flag也是同步TaskTCP的变量,OBDStruct.VINStruct.flag值是SET时,TaskTCP才会上传车架号到服务器。89行清空OBDStruct.VINStruct.VIN变量。90行读取车架号,并返回存储车架号地址到ram指针。91行到94行车架号读取成功把ram指向的存储单元存储的车架号复制到OBDStruct.VINStruct.VIN中,并设置OBDStruct.VINStruct.flag = SET告知TaskTCP可以上传车架号信息到服务器。

如何请求和响应车架号,我们要看ISO15765_4_GetVIN函数。

图片

函数有两个参数,参数1表示协议类型,参数2 *err=NL_OK表示函数读取车架号成功,*err=NL_NOK表示读取车架号失败。55行利用NL_OBD_SendCANFrame函数发送车架号请求,并获得汽车或者模拟器的响应数据。下面进行模拟并在线仿真帮助理解。

1. 设置模拟器模拟车架号1G1JC5444R7252367

图片

 

2. C300车联网开发板对应的服务器网站显示读到的正确车架号。

图片

 

3. OBD分析仪采集到的读车架号原始数据。

图片

 

4.打断点,查看ram指针对应存储单元存储的响应数据。应用层原始数据从第5字节开始表示车架号。

图片

5. 下图把Memory区转换成ASCII编码,可以清晰查看到车架号。

图片

所以57行到63行代码就是把ram指向的存储单元第5个字节开始17个字节表示车架号复制到VINRAM数组中。64行代码是在VINRAM数组车架号后加入0这个结束字符。65行代码返回VINRAM数组地址。这就是ISO15765-4协议车架号读取过程。

Read 12567 times Last modified on Wednesday, 09 December 2020 10:37