Kwp2000协议的应用(程序原理篇)
作者:良知犹存
转载授权以及围观:欢迎添加微信: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解析,里面代码是实践过的,还有很多细节因为篇幅与时间的原因就不多写了,如果大家有什么更好的思路,欢迎分享交流哈。
更多分享,扫码关注我
Kwp2000协议的应用(程序原理篇)的更多相关文章
- Kwp2000协议的应用(硬件原理使用篇)
作者:良知犹存 转载授权以及围观:欢迎添加微信:becom_me 发现K线没有过多的文章描述,作为一个开发过K线的人,不写些文章帮助后来的人岂不是太浪费开发经验了呢. 总述 KWP2000是一 ...
- 【如何快速的开发一个完整的iOS直播app】(原理篇)
原文转自:袁峥Seemygo 感谢分享.自我学习 目录 [如何快速的开发一个完整的iOS直播app](原理篇) [如何快速的开发一个完整的iOS直播app](播放篇) [如何快速的开发一个完整的 ...
- iOS:app直播---原理篇
[如何快速的开发一个完整的iOS直播app](原理篇) 转载自简书@袁峥Seemygo:http://www.jianshu.com/p/7b2f1df74420 一.个人见解(直播难与易) 直播 ...
- 如何快速的开发一个完整的iOS直播app(原理篇)
目录 [如何快速的开发一个完整的iOS直播app](原理篇) [如何快速的开发一个完整的iOS直播app](播放篇) [如何快速的开发一个完整的iOS直播app](采集篇) 前言 大半年没写博客了,但 ...
- 微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)
1.点评 对于IM系统来说,如何做到IM聊天消息离线差异拉取(差异拉取是为了节省流量).消息多端同步.消息顺序保证等,是典型的IM技术难点. 就像即时通讯网整理的以下IM开发干货系列一样: <I ...
- TCP协议、算法和原理
TCP是一个巨复杂的协议,因为他要解决很多问题,而这些问题又带出了很多子问题和阴暗面.所以学习TCP本身是个比较痛苦的过程,但对于学习的过程却能让人有很多收获. 关于TCP这个协议的细节,我还是推荐你 ...
- 推荐-zabbix原理篇
推荐-zabbix原理篇(1) 提交 我的留言 加载中 已留言 本文大纲 snmp介绍 监控流程 开源监控工具zabbix zabbix监控功能的实现 支持数据库存储类型 Zabbix架构中的组件 Z ...
- Cesium原理篇:3最长的一帧之地形(2:高度图)
这一篇,接着上一篇,内容集中在高度图方式构建地球网格的细节方面. 此时,Globe对每一个切片(GlobeSurfaceTile)创建对应的TileTerrain类,用来维 ...
- 基于GBT28181:SIP协议组件开发-----------第四篇SIP注册流程eXosip2实现(一)
原创文章,引用请保证原文完整性,尊重作者劳动,原文地址http://www.cnblogs.com/qq1269122125/p/3945294.html. 上章节讲解了利用自主开发的组件SIP组件l ...
随机推荐
- 【项目实践】SpringBoot三招组合拳,手把手教你打出优雅的后端接口
以项目驱动学习,以实践检验真知 前言 一个后端接口大致分为四个部分组成:接口地址(url).接口请求方式(get.post等).请求数据(request).响应数据(response).如何构建这几个 ...
- 对于k8s微服务的性能测试监控平台搭建
之前有写过对于传统项目的性能测试监控,但是对于目前市场占比已经很低,大部分项目使用k8s,今天讲一下对于k8s如何去监控. 对于k8s的监控我们所有的操作都要在master下进行. 一.部署grafa ...
- 利用GPU实现大规模动画角色的渲染(转)
原文: https://www.cnblogs.com/murongxiaopifu/p/7250772.html 利用GPU实现大规模动画角色的渲染 0x00 前言 我想很多开发游戏的小伙伴都希望自 ...
- 深入理解MySQL索引(上)
简单来说,索引的出现就是为了提高数据查询的效率,就像字典的目录一样.如果你想快速找一个不认识的字,在不借助目录的情况下,那我估计你的找好长时间.索引其实就相当于目录. 几种常见的索引模型 索引的出现是 ...
- vim 手动添加脚本头部信息
vim /root/.vimrc 8,1 全部 set autoindent set tabstop=5 set shiftwidth=4 function AddTitle() call setli ...
- Linux性能相关命令
Linux性能相关命令 目录 Linux性能相关命令 1. 查看硬盘相关信息 2. 查看CPU相关信息 3. 查看内存相关信息 4. 查看进程运行的信息 1. 查看硬盘相关信息 cat /proc/s ...
- 四:WEB源码扩展
前言:WEB源码在安全测试中是非常重要的信息来源,可以用来进行代码审计漏洞也可以用来做信息突破口,其中WEB源码有很多技术需要简明分析,获取某ASP源码后就可以采用默认数据库下载为突破,获取某其他脚本 ...
- Python编程小技巧(一)
在使用Tkinter编写代码的时候,有时候会忘记某个组件的参数是什么或者忘记某个参数怎么拼写的,此时可以通过如下方式查询组件的参数列表,以按钮组件为例: 1 # -*- coding:utf-8 -* ...
- 深入研究.NET 5的开放式遥测
OpenTelemetry 介绍 OpenTelemetry是一种开放的源代码规范,工具和SDK,用于检测,生成,收集和导出遥测数据(指标,日志和跟踪),开放遥测技术得到了Cloud Native C ...
- 深度学习DeepLearning技术实战(12月18日---21日)
12月线上课程报名中 深度学习DeepLearning(Python)实战培训班 时间地点: 2020 年 12 月 18 日-2020 年 12 月 21日 (第一天报到 授课三天:提前环境部署 电 ...