作者:良知犹存

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

总述

    接上篇文章Kwp2000协议的应用(硬件原理使用篇),本篇针对kwp2000协议标准的服务ID详细介绍,以及针对程序实现应答机制,进行介绍。

三、通讯实现过程详解

KWP2000有两种启动方式,5波特率启动和高速启动方式,5波特率基本不使用了,并且我使用过程中是高速初始化的方式,所以下面就按照高速初始化的方式介绍:

在向ECU发送C1 33 F1 81 66 的启动数据之前,还需要进行KWP通信的握手,这时候就需要用到快速初始化,用来告诉ECU有设备准备接入。

Tidle 我在程序实现设置为400ms,>= 300ms

TiniL 我在程序实现设置为25ms, 24~26ms范围内

Twup 我在程序实现设置为50ms,49ms~51ms

 

注意:由于高速初始化需要对TX引脚进行置高置低,所以IO配置成推挽输出比较好,所以发送数据的时候使用模拟串口配置TX引脚进行数据的发送。

 

下面代码展示是堵塞执行,其实已经用状态机实现了,类似的延时状态机之前文章已经描述过,因为篇幅的原因,此处就不多做赘述,需要的人可以看我之前的文章。程序堵塞的优化方法(一)解决程序堵塞的优化方法(二)

u8 KlineFastInit(void){  KLin_RX_CLOSE();/*关闭接收引脚*/  K_OUT_HIGH;       /*TX引脚输出置高*/  Delay_ms(400);  /*保持拉高400ms*/      K_OUT_LOW;    /*TX引脚输出拉低*/  Delay_ms(25);/*保持拉低25ms*/  K_OUT_HIGH; /*TX引脚输出置高*/  Delay_ms(25);/*保持拉高25ms*/   KLin_RX_OPEN();/*打开接收引脚*/  Start_CommunicationKLin();/*向K-line发送 C1 33 F1 81 66 进行启动 */  }

Tres 进行发送与接收之间的判断,通过这个时间可以判断ECU的回应情况,而不至于MCU出现长等待情况,如果出现该时间内数据没有回应,MCU端可以进行ECU重新建立通信的初始化过程。

 

正常情况下一些ECU回复信息 hex:83 F1 11 C1 E9 8F BE

注意了:KB1 KB2 就是我们需要提取的关键词,用来判断ECU是否回复积极响应,不过日本产的三国ECU的关键词是0xE98F,而德尔福和博世ECU的回复关键词是0xEF8F。

BOSH的回复信息 hex:C3 F1 11 C1 EF 8F 04

不过都一样,整条信息最后一位符合累加校验,我们把数据确认是可以用的之后,直接进行关键词判断,对于德尔福、BOSH的接收的信息的不一致,就可以在软件层面忽略,解析判断代码如下:

 

u8 ReceiveECUStartCommunication(u8 *p, u8 len){  p++;//移动八位  显示第二位数据的地址  if ((BigtoLittle16(*(u16*)(p)) == 0xEF8F)||  (BigtoLittle16(*(u16*)(p)) == 0xE98F))//关键字判断 通过大小端转化函数  {      printf("Kline-StartCommunication!\r\n");  }  return 0;}


通讯一旦建立之后我们就可以进行对ECU读取想要的数据。比如读或者删除整车故障码,车辆编号,水温,车速,转速,油压等各种车身上提供的传感器数据。

 

这是对应的服务ID,通过ID这个关键词我们可以进行读取所需的不同种类的车身信息

 

例如我要读取车身的故障码,由上图可知故障码属于ID:0x03的服务ID类中

这时候我就向ECU发送数据 hex:C1 33 F1 03 E8

__packed typedef struct{  u8 fmt;                   u8 tgt;                   u8 src;                 u8 sid;               }KlineSend;u8 ReadDTC(void)  KlineSend *p = (KlineSend*)malloc(20);  p->fmt = 0xC1;  p->tgt = 0x33;  p->src = 0xF1;  p->sid = 0x03;  //cheksum = 0xE8  ((u8*)p)[sizeof(KlineSend)] = CheckSum((u8*)p, sizeof(KlineSend));  SendBuf_KLin((u8*)p, sizeof(KlineSend)+1);  free(p);  return 0;}

 

假设回来数据为 hex:87 F1 11 43 0562 0000 0000 33

(BOSH ECU 回传数据大致为 hex>:C7 F1 11 43 0118 0107 0000 2D )故障码信息是随意写的

u8 ReceiveECUReadDTCByStatus(u8 *p, u8 len){  u8 lenth = 0;  ++p;  --len;//刚好的故障码长度  for (u8 i = 0; i<3; i++)  {    if (*(u16*)&(p[i * 2]) != 0x0000)    {      lenth += 2;//两个字节为一组    }  }  for (u8 i = 0; i<lenth / 2; i++)  {    printf(".DT_%d,0x%04X\r\n",i,BigtoLittle16(*(u16*)&((p[i * 2]))));  }  return 0;}

解析逻辑执行如下:仅供参考

__packed typedef struct{  u8 fmt;                   u8 tgt;                  u8 src;                u8 sid;                  }KlineSecondFORMAT;__packed typedef struct{  u8 sid;                  u8(*f)(u8*, u8);        }KlineAnalyzTypeDef;  uint8_t CheckSum(uint8_t* data, uint8_t len)// V{  uint8_t i;  uint8_t sum;  sum = 0;  for(i = 0; i < len; i++)  {    sum += data[i];  }  return sum;}KlineAnalyzTypeDef KlineAnalyzTab[] ={  { 0xC1, ReceiveECUStartCommunication},    //启动通讯  { 0x43, ReceiveECUReadDTCByStatus },};u8 KlineAnalyz(u8 *p,u8 lenth){  KlineSecondFORMAT*p1;  p1 = (KlineSecondFORMAT*)p;  while(lenth)  {    u8 len = p1->fmt & 0x3F;    if (len != 0)    {      if (p[len + sizeof(KlineSecondFORMAT)-1] != CheckSum(p, len + sizeof(KlineSecondFORMAT)-1))        return 1;//返回错误        for (int i = 0; i < sizeof(KlineAnalyzTab) / sizeof(KlineAnalyzTypeDef); i++)        {          if (p1->sid == KlineAnalyzTab[i].sid)          {            KlineAnalyzTab[i].f(&(p1->sid), len);            break;          }        }        lenth = lenth -(len+ sizeof(KlineSecondFORMAT));        p1=(KlineSecondFORMAT*)((u8*)p1+(len+ sizeof(KlineSecondFORMAT)));      }  return 0;  }

这就是我分享的kwp2000解析,里面代码是实践过的,还有很多细节因为篇幅与时间的原因就不多写了,如果大家有什么更好的思路,欢迎分享交流哈。

更多分享,扫码关注我

最新文章

  1. TSQL 聚合函数忽略NULL值
  2. babel6 的 export default bug
  3. Hibernate框架之get和load方法的区别
  4. AppleWatch___学习笔记(三)iPhone和Apple Watch上的数据同步
  5. JS eval() 特殊用法
  6. 关于mvc中@Html.DropDownListFor和@Html.DropDownList默认值无法选中问题简单总结
  7. 消灭Bug!18款最佳的问题跟踪管理应用程序
  8. 具有timeout 功能的函数调用
  9. java学习材料
  10. zoj3261 带权并查集
  11. Echarts事件
  12. 自定义控件和XControl控件
  13. POJ 1220 NUMBER BASE CONVERSION(较复杂的进制转换)
  14. javascript Node操作
  15. Python之软件管理
  16. MarkDown编写规范指南
  17. 暑假集训D10总结
  18. linux nvme的sendfile流程
  19. 400多个开源项目以及43个优秀的Swift开源项目-Swift编程语言资料大合集
  20. Spring Boot实战笔记(四)-- Spring常用配置(事件Application Event)

热门文章

  1. LeetCode 面试题16.18.模式匹配
  2. 阿里云centos7[linux]安装nginx
  3. 【Flutter】容器类组件之填充
  4. Docker学习笔记之创建安装了nginx服务器的镜像
  5. 温故而知新--day2
  6. MySQL的CURD 增删改查
  7. Java 安全之Weblogic 2018-2628&amp;2018-2893分析
  8. centos7.4使用filrewalld打开关闭防火墙与端口
  9. MySQL库和表的操作
  10. JavaScript中的Object类型!