Kwp2000协议的应用(程序后续篇)

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: Kwp2000协议的应用(程序后续篇)

作者:良知犹存

转载授权以及围观:欢迎添加微信:becom_me

总述

   接上上篇文章Kwp2000协议的应用(硬件原理使用篇),本篇继续对基于PID解析数据,如何依据J1979的标准进行解析数据

   先给昨天的文章补上一张故障码对照表,昨天分析了如何读取故障码,但是如何把16bit的hex数据转为我们可以解释的故障码,一般各大厂家的维修手册会有显示,第二就是ECU的协议手册里面会进行描述故障码对应的hex数据。

下面就是部分故障码展示:

4edc953e2c684bbe819ffa954c899c08.png


四、继续读取ECU常用数据

通过服务ID:0x01 读取整车状态数据:

从上面可以看到支持的整车的数据的ID 有0x20 0x40 0xC0打头的整段ID

或者我们也可以通过向ECU发送相应格式的数据,用来解析能够支持的PID有哪些。

4edc953e2c684bbe819ffa954c899c08.png4edc953e2c684bbe819ffa954c899c08.png

TEST->ECU  (设备端发往ECU请求读取转速的数据)hex:C2 33 F1 01 0C F3

读取代码如下:仅供参考

__packed typedef struct{
  u8 fmt;                 
  u8 tgt;                 
  u8 src;               
  u8 sid;               
}KlineSend;
u8 KLineReadrpm(void)/*读发动机转速*/
{
  KLIN_RecOK = 0;
  u8* p1;
  KlineSend *p = (KlineSend*)malloc(20);
  p->fmt = 0xC2;
  p->tgt = 0x33;
  p->src = 0xF1;
  p->sid = 0x01;
  p1=(u8*)&(p->sid);
  *++p1= 0x0C;
  *++p1=CheckSum((u8*)p, sizeof(KlineSend)+1);
  SendBuf_KLin((u8*)p, sizeof(KlineSend)+2);
  free(p);
  return 0;
}

4edc953e2c684bbe819ffa954c899c08.png

ECU ->TEST (ECU 应答设备转速的回复)德尔福hex ::C4 F1 11 41 0C 0000 13

BOSH ECU回应数据格式  hex:C4 F1 11 41 0C 0000 13

虽然数据内容有些不同,但是都是符合kwp2000的数据格式,这样对我们来说我们只需要把握数据整体是否能用,再解析关键字即可,不需要一种ECU写一套代码。

4edc953e2c684bbe819ffa954c899c08.png

其中解析方式可以参照当前协议中ID支持的标准解析方式,我开发的PID都符合J1979的解析方式,所以我就按照如下表进行解析数据。4edc953e2c684bbe819ffa954c899c08.png

汽车现在有新的解析标准,大家可以自行查找,这里给大家描述的是一种方法,至于最终开发的产品,请严格按ECU所符合的标准来操作。

同理:车速的读取信息

tester ->德尔福ECU  hex:C2 33 F1 01 0D F4

德尔福ECU-> tester  hex:83  F1 10 41 0D 23 F5

读取关键词车速为 0x23

BOSH ECU回应格式为 hex:C3 F1 11 41 0D 00 13

读取关键词车速为 0x00

解析判断代码如下:

u8 ReceiveReadCommData(u8 *p,u8 len)
{
  u16 EngRpm,carSpeed;
  switch(*++p)//关键字判断
  {
    case 0x0C:
    {
      EngRpm=((*(((u8*)p)+1))*256+(*(((u8*)p)+2)))/4;
      break;
    }  
    case 0x0D:
    {
      carSpeed=*(((u8*)p)+1);
      break;
    }
    default:
      break;
  }
  return 0;
}

但是有些时间我们会遇到读取过来的数据无法使用,那么我们第一要判断的就是否是服务ID不支持,虽然上面可以看到很多ID的解析方式,甚至ECU都会回应你正确的格式,但是有些时候外部接线以及其他原因,我们获得的数据是无法使用的。

比如车速,如果ECU没有此项功能,ECU则会回复0x12否定代码,示例如下:

tester->:C233F1010DF4

ECU  ->: 83F1117F011217

但是有些时候,因为一些原因该功能ECU支持信息回复,但是实际上ECU上硬线并没有连接,所以需要我们及时分辨:

4edc953e2c684bbe819ffa954c899c08.png


五、读取一体的函数结构

加上昨天现在有几个ID的读取了,昨天没有分享读取的总函数,现在展示一下读取执行的总函数:仅供参考

KlinSendTimTypeDefTab KlineSendTimTab[KlineTask] =
{
  { 0, 0, 3   ,  *Tester        },            //用来与ECU保持长连接
  { 0, 0, 1   ,  *KLineReadrpm  },
  { 0, 0, 1   ,  *KLineReadSpeed},
  { 0, 0, 15  ,  *ReadDTC       },
  { 1, 0, 20  ,  *KLineDtcClear },            
};
u8 KlineScan(void)
{
    if(KlinRcvLen()>3)
    {
       KlineAnalyz(KlinRcvBuff(), KlinRcvLen());//调用串口接收函数
       memset((u8*)KlinRcvBuff(),0x00, 0xff);
    }
    KLIN_RecOK = 0;
    KlinClsRecvd();
  }
  if (KlineSendIndFlag.flag == 0)
  {
    if (KlineSendIndFlag.init == 1)
    {      
      printf("Klin_init\r\n");
      KlineFastInit();
      KlineSendIndFlag.count = 0;
      KlineSendIndFlag.src = 600;
      KlineSendIndFlag.flag = 1;
      (KlineSendIndFlag.cnt > 8)? (KlineSendIndFlag.cnt =0):(KlineSendIndFlag.cnt++);
      if(KlineSendIndFlag.cnt>3&&KlineSendIndFlag.cnt<6)
      {
          KlineSendIndFlag.init =1;
          KlineSendIndFlag.count = 0;
          KlineSendIndFlag.flag =0;
          KlineSendIndFlag.sta=0;/*判断为0*/
      }
      else{
          KlinComInit();  
      }            
    }
    else
    {
      for (char i = 0; i < sizeof(KlineSendTimTab)/sizeof(KlinSendTimTypeDefTab); i++)
      {
        if (KlineSendTimTab[i].flag == 0)
        {
          KlineSendTimTab[i].flag = 1;
          KlineSendTimTab[i].count = 0;//计算接收时间长度
          KlineSendTimTab[i].p() ;
          KlineSendIndFlag.flag  = 1;    
          KlineSendIndFlag.count = 0;    
          if(KlineSendIndFlag.cnt)KlineSendIndFlag.cnt =0;  /*转为0*/            
          break;
        }
      }
    }
  }
  return 0;
}

这就是我分享的kwp2000解析,还有很多细节操作,实际开发和文字描述上还是差距很多,如有需要欢迎大家联系我与我交流,添加我的微信:become_me。

目录
相关文章
|
5月前
|
API Windows
揭秘网络通信的魔法:Win32多线程技术如何让服务器化身超级英雄,同时与成千上万客户端对话!
【8月更文挑战第16天】在网络编程中,客户/服务器模型让客户端向服务器发送请求并接收响应。Win32 API支持在Windows上构建此类应用。首先要初始化网络环境并通过`socket`函数创建套接字。服务器需绑定地址和端口,使用`bind`和`listen`函数准备接收连接。对每个客户端调用`accept`函数并在新线程中处理。客户端则通过`connect`建立连接,双方可通过`send`和`recv`交换数据。多线程提升服务器处理能力,确保高效响应。
60 6
|
5月前
|
网络协议 网络架构
动图 | 6张图让你秒懂“ARP中间人攻击”原理,堪称史诗级解释!
动图 | 6张图让你秒懂“ARP中间人攻击”原理,堪称史诗级解释!
237 0
|
8月前
|
消息中间件 小程序 网络性能优化
蓝易云 - 直播小程序源码有用的协议知识:MQTT协
在直播小程序源码中,MQTT协议可以用于实现实时消息推送,如弹幕、聊天消息、礼物信息等。通过使用MQTT协议,可以确保消息的实时性和可靠性,从而提高用户体验。
198 0
|
网络协议 网络安全 C++
【网络篇】第十六篇——再谈端口号
【网络篇】第十六篇——再谈端口号
【网络篇】第十六篇——再谈端口号
|
传感器
Kwp2000协议的应用(程序原理篇)
Kwp2000协议的应用(程序原理篇)
345 0
Kwp2000协议的应用(程序原理篇)
|
安全 算法 Linux
Linux网络原理及编程(3)——第十三节 HTTPS
大家应该都知道http和https的区别,区别很简单,主要就是在https是采用了加密协议的,而http完全是在网络上裸奔的。而我们现在几乎所有的连接都用的是https
148 0
Linux网络原理及编程(3)——第十三节 HTTPS
|
设计模式 监控 网络协议
Linux网络原理与编程——第十一节 网络基础及套接字
从system call(系统调用结构)开始往下,都是属于OS和硬件的范畴,我们一般的程序员所进行的开发,通常都是在用户层。(这个我们后面还会具体说到)。
221 0
Linux网络原理与编程——第十一节 网络基础及套接字
|
域名解析 网络协议 算法
Linux网络原理与编程(4)——第十四节 传输层协议
客户端认为连接已经建立成功了,所以就正常发数据。但是这个时候服务器并未建立连接,在收到数据之后,会向客户端发送一个含有RST的报文(reset),即希望客户端重新建立连接。
265 0
Linux网络原理与编程(4)——第十四节 传输层协议
|
监控 网络协议 NoSQL
不为人知的网络编程(十一):从底层入手,深度分析TCP连接耗时的秘密
TCP的开销到底有多大,能否进行量化。一条TCP连接的建立需要耗时延迟多少,是多少毫秒,还是多少微秒?能不能有一个哪怕是粗略的量化估计?
652 0
不为人知的网络编程(十一):从底层入手,深度分析TCP连接耗时的秘密
|
编解码 算法 安全
细说网络电话的原理
VoIP 电话/VoIP 网络电话系统把普通电话的模拟信号转换成计算机可联入因特网传送的IP 数据包,同时也将收到的IP数据包转换成声音的模拟电信号。经过VoIP 电话/VoIP 网络电话系统的转换及压缩处理,每个普通电话传输速率约占用8~11kbit/s 带宽,因此在与普通电信网同样使用传输速率为64kbit/s 的带宽时,VoIP 电话/VoIP 网络电话数是原来的5~8 倍。VoIP 电话/VoIP 网络电话的核心与关键设备是VoIP 电话/VoIP 网络电话网关。