K线诊断协议驱动器设计
void k_ifc_rx(void)
{
k_u8 ch,SciSr1;
SciSr1=Kline_periph[SCISR1];
ch=Kline_periph[SCIDRL];
TimerStop(k_TP4);
switch(k_curmsg.state){
case k_FMT:
if(k_REP==k_drvhandle.mode){
if(ch==k_curmsg.fmt){
k_curmsg.state=k_TGTADDR;
k_SendChar(k_curmsg.tgt_addr);
}
}else{
k_curmsg.state=k_TGTADDR;
k_curmsg.fmt=ch;
}
break;
case k_TGTADDR:
...
break;
case k_SRCADDR:
...
break;
case k_DATALEN:
if(k_REP==k_drvhandle.mode){
if(ch==k_curmsg.datalen){
k_curmsg.msgdatalen=0;
k_curmsg.state=k_SID;
k_SendChar(k_curmsg.sid);
}
}else{
k_curmsg.msgdatalen=0;
k_curmsg.datalen=ch;
free(k_curmsg.data);
k_curmsg.data=malloc(k_curmsg.datalen);
k_curmsg.state=k_SID;
}
break;
case k_SID:
if(k_REP==k_drvhandle.mode){
if(ch==k_curmsg.sid){
k_curmsg.msgdatalen++;
if(k_curmsg.msgdatalen==k_curmsg.datalen){
k_curmsg.state=k_CS;
k_SendChar(k_curmsg.checksu);
}else{
k_curmsg.state=k_DATA;
k_SendChar(k_curmsg.data[0]);
}
}
}else{
k_curmsg.sid=ch;
k_curmsg.msgdatalen++;
if(k_curmsg.datalen==k_curmsg.msgdatalen){
k_curmsg.state=k_CS;
}else{
k_curmsg.state=k_DATA;
}
}
break;
case k_DATA:
...
break;
case k_CS:
k_curmsg.state=k_FMT;
if(k_REP==k_drvhandle.mode){
if(ch==k_curmsg.checksum){
k_curmsg.done=1;
}
}else{
k_curmsg.checksum=ch;
k_curmsg.done=1;
}
break;
} if((k_REQ==k_drvhandle.mode)(k_FMT!=k_curmsg.state)){
TimerStart(k_REP_P4MS,k_TP4,0,1);
}
}2.2 初始化
在开始诊断服务之前,诊断仪必须对ECU进行初始化,通过ECU的响应获取ECU支持的报文头格式和定时参数,建立诊断通讯【4】。初始化过程如图1所示,诊断仪发送一个25ms ’0’、25ms’1’的WuP(WakeUp Pattern),然后发送STC(StartCommunication) Request,ECU检测出WuP并接收到正确的STC Request后返回STC Response,该报文的Data字段为由两个字节构成的“关键字(Key Word)”,指定了ECU所支持的报文头和定时参数信息,如Key Word指定为0x8fea即表示在报文头中采用附加长度信息Len表示数据字段长度,同时采用默认的定时参数。
评论