📄 protocolvw.c
字号:
/******************************************************************************************
* 目的:KWP1281 协议库函数
* 功能:提供基本 KWP1281 协议操作接口
* 模块依赖:SCI.h Timer.h
******************************************************************************************/
#include <stdio.h>
#include "compiler.h"
#include "SCI.h"
#include "Timer.h"
#include "SysTool.h"
#include "Cable.h"
#include "ProtocolVW.h"
#define T0TIME 10 //定时器初始化时间 10ms
#define RECE_STATE 0 //接收状态
#define SEND_STATE 1 //发送状态
static struct KW1282 //模块数据结构
{
volatile unsigned char ComState; //通讯状态
unsigned char hold[20]; //存放保持链路发送数据
unsigned char *Waitsend; //待发送数据
unsigned char *Waitread; //待接收数据
volatile unsigned char Flashset; //发送数据就位标志
volatile unsigned char Readset; //接收数据就位标志
volatile unsigned char Ver_Flag; //取反校验标志 1是接收校验,2是发送校验
volatile unsigned char LinkFlag; //通讯成功标志 1是成功
volatile unsigned char Count; //发送计数器
volatile unsigned char ComCount; //命令计数器
unsigned char Lenth; //数据包长度
volatile int MScount; //MS记数
int Btyetime; //字节间距
int HoldT; //链路保持间距
} Tagkw;
/*
**-----------------------------------------------------------------------------------------
** 初始化 KWP1281 协议通讯模块
**-----------------------------------------------------------------------------------------
*/
void VW_Init( )
{
#ifdef DEBUGMODE
DebugString( "VW_Init()" );
#endif
Tagkw.Waitsend = NULL;
Tagkw.Waitread = NULL;
Tagkw.Flashset = 0;
Tagkw.Readset = 1;
Tagkw.Count = 0;
Tagkw.Lenth = 0;
Tagkw.MScount = 0;
Tagkw.Btyetime = 0;
Tagkw.HoldT = 1000;
Tagkw.hold[0] = 0;
Tagkw.ComCount = 0;
Tagkw.Ver_Flag = 0;
Tagkw.LinkFlag = 0;
Tagkw.ComState = 0xff;
}
/*
**-----------------------------------------------------------------------------------------
** 插入 KWP1281 通讯链路
** KeepDig:协议请求方保持链路样本
** HoldTime: 通讯链路保持时间
** 返回: 1
**-----------------------------------------------------------------------------------------
*/
char VW_Maintain( unsigned char *KeepDig, int HoldTime )
{
#ifdef DEBUGMODE
DebugString( "VW_Maintain()" );
#endif
unsigned char Len;
unsigned char i;
Tagkw.HoldT = HoldTime;
Len = VW_Getlen( KeepDig );
if( Len >= 20 )
{
return FAIL;
}
else
{
//NULL
}
for( i=0; i<Len; i++ )
{
Tagkw.hold[i] = KeepDig[i];
}
return SUCCESS;
}
/*
**-----------------------------------------------------------------------------------------
** 0x55波特触发函数,addr1决定触发ID,PORT为选脚,有成功判定
** 失败返回0;成功返回1
**-----------------------------------------------------------------------------------------
*/
unsigned char VWlink(unsigned char addr1,unsigned char portK,unsigned char portL)
{
#ifdef DEBUGMODE
DebugString( "iso_link()" );
#endif
unsigned char kb2;
unsigned char i=0;
//初始化所需的硬件环境
TimeDestroy( TIMER0 );
TimeStop( TIMER0 );
SCIdestroy();
//选通 L 线
ChanSet( portK,portL );
SCITXD( THIGH ); delay(500); //一段时间的高电平清总线
//发送请求的系统ID号
SCITXD( TLOW ); delay(200); //5波特起始位 //20ms
//发送请求的系统ID号
if( ( addr1&0x01 ) != 0 ) SCITXD( THIGH );
else SCITXD( TLOW );
delay( 200 );//20ms
if( ( addr1&0x02 ) != 0 ) SCITXD( THIGH );
else SCITXD( TLOW );
delay( 200 );
if( ( addr1&0x04 ) != 0 ) SCITXD( THIGH );
else SCITXD( TLOW );
delay( 200 );
if( ( addr1&0x08 ) != 0 ) SCITXD( THIGH );
else SCITXD( TLOW );
delay( 200 );
if( ( addr1&0x10 ) != 0 ) SCITXD( THIGH );
else SCITXD( TLOW );
delay( 200 );
if( ( addr1&0x20 ) != 0 ) SCITXD( THIGH );
else SCITXD( TLOW );
delay( 200 );
if( ( addr1&0x40 ) != 0 ) SCITXD( THIGH );
else SCITXD( TLOW );
delay( 200 );
if( ( addr1&0x80 ) != 0 ) SCITXD( THIGH );
else SCITXD( TLOW );
delay( 200 );
SCITXD( THIGH );
delay( 200 ); //结束位 200ms
ChanSet( portK,0 );
//等待0X55回送 记算动态波特率
if( !SCIDynamicBuad() )
{
return FAIL;
}
//接收ECU回应校验拨特率
TimeInit( TIMER0,10 ); //初始化T0 1ms
TimeStart( TIMER0 );
SCIENcontrol( 1 ); //允许读
for( i=0; i<2; i++ ) //等待汽车反还2个K(k1,k2)
{
TimeSet( TIMER0, 0 );
while( !SCIRE() && !TimeBreak( TIMER0,100 ) )
{
//NULL
}
if( TimeBreak( TIMER0,100 ) )
{
return FAIL;
}
kb2 = SCIreadin();
}
#ifdef DEBUG686A
unsigned char TempBuf[20];
sprintf( TempBuf, " %2x " , kb2 );
LcdStr86( 1, 1, TempBuf, BLACK );
while( 1 );
#endif
//触发完后关闭选择L线
//关闭L线
delay( 30 ); //等待30毫秒
kb2 = ~kb2;
SCIsend( kb2 ); //将后一个K取反回送给汽车校验当前设定拨特率是否正确
SCIload( Kw1281Scon ); //装载串口中断函数
TimeLoad( TIMER0, Kw1281Time );//装载定时器中断函数
TimeStart( TIMER0 );
Tagkw.LinkFlag = 1;
return SUCCESS;
}
/*
**-----------------------------------------------------------------------------------------
** KWP1281 发送协议包刷新函数
** Dig:待发送数据包
** BtyeDst:发送字节间隔( MS )
**-----------------------------------------------------------------------------------------
*/
char VW_Send( unsigned char *Dig, int BtyeDst )
{
Tagkw.MScount = 0;
while( (Tagkw.ComState != 0xff) && ( Tagkw.MScount < ( Tagkw.HoldT/T0TIME-1 ) ) )
{
//NULL
}
SCIENcontrol( 0 );//允许发送,禁止接收
Tagkw.Waitsend = Dig;
Tagkw.Waitsend[1] = Tagkw.ComCount; //命令计数器
Tagkw.Btyetime = BtyeDst;
Tagkw.Lenth = VW_Getlen( Dig );
Tagkw.Ver_Flag=2;
Tagkw.Count = 0;
Tagkw.MScount = 0;
Tagkw.LinkFlag = 0;
Tagkw.ComState = SEND_STATE; //发送状态
Tagkw.Flashset = 1; //发送数据更新就绪
while( Tagkw.Flashset && ( Tagkw.MScount < ( Tagkw.HoldT/T0TIME-1 ) ) ) //正在发送,等待1个链路保持时间时间单位
{
//NULL
}
if( !Tagkw.Flashset )
{
Tagkw.LinkFlag = 1;
return SUCCESS;
}
else return FAIL;
}
/*
**-----------------------------------------------------------------------------------------
** KWP1281 回送协议包接收函数
** Dig:数据包接收位置
** Wtime:接收等待最大时间(MS)
** MaxLen:最大接收长度
**-----------------------------------------------------------------------------------------
*/
char VW_Read( unsigned char *Dig, int Wtime, unsigned char MaxLen )
{
unsigned int WaitTime;
if( Wtime >= Tagkw.HoldT ) Wtime = Tagkw.HoldT;
WaitTime = Wtime/T0TIME;
Tagkw.Waitread = Dig;
Tagkw.Readset = 0;
Tagkw.ComState = RECE_STATE; //接收状态
Tagkw.MScount = 0;
SCIENcontrol( 1 );//允许接收,禁止发送
while( (Tagkw.MScount < WaitTime) && !Tagkw.Readset ) //指定时间等待接收完毕
{
if( Tagkw.Count >= MaxLen ) //NULL
{
Tagkw.Count = 0;
SCIENcontrol( 0 );
return FAIL;
}
}
if( Tagkw.Readset ) return SUCCESS;
else
{
Tagkw.ComState = 0xff;
return FAIL;
}
}
/*
**-----------------------------------------------------------------------------------------
** KWP1281 发送指定协议包接收函数
** SendDig:待发送数据包
** ReceDig:接收数据包
**-----------------------------------------------------------------------------------------
*/
char VW_FunRead( unsigned char *SendDig, unsigned char ReceDig[10][16] )
{
unsigned char tmpdata[5]={0x03, 0x00, 0x09, 0x03};
unsigned char i=0;
if( VW_Send( SendDig, 10 ) == 0 )
{
return FAIL;
}
if( VW_Read( ReceDig[i], 2000, 16 ) == 0 )
{
return FAIL;
}
i++;
if( (ReceDig[i-1][0] == 0x03) && (ReceDig[i-1][2] == 0x09) )
{
return i;
}
while(i<10)
{
if( VW_Send( tmpdata, 10 ) == 0 )
{
return FAIL;
}
if( VW_Read( ReceDig[i], 2000, 16 ) == 0 )
{
return FAIL;
}
i++;
if( (ReceDig[i-1][0] == 0x03) && (ReceDig[i-1][2] == 0x09) )
{
return i;
}
}
return FAIL;
}
/*
**-----------------------------------------------------------------------------------------
** KWP1281 接收函数
** ReceDig:接收数据包
**-----------------------------------------------------------------------------------------
*/
char VW_DataRead( unsigned char ReceDig[10][16] )
{
unsigned char tmpdata[5]={0x03, 0x00, 0x09, 0x03};
unsigned char i=0;
while(i<10)
{
if( VW_Read( ReceDig[i], 2000, 16 ) == 0 )
{
return FAIL;
}
i++;
if( (ReceDig[i-1][0] == 0x03) && (ReceDig[i-1][2] == 0x09) )
{
return i;
}
if( VW_Send( tmpdata, 10 ) == 0 )
{
return FAIL;
}
}
return FAIL;
}
/*
**-----------------------------------------------------------------------------------------
** 提取 KWP1281 回送协议包长度信息(KWP1281专有函数)
** Dig:数据包
**-----------------------------------------------------------------------------------------
*/
unsigned char VW_Getlen( unsigned char *Dig )
{
unsigned char length;
length = Dig[0]+1;
return( length );
}
/*
**-----------------------------------------------------------------------------------------
** 协议定时器中断函数
**-----------------------------------------------------------------------------------------
*/
void Kw1281Time()
{
Tagkw.MScount++;
//处于接收状态,收到的数据将在定时器中断取反发送
if( Tagkw.ComState == RECE_STATE )
{
if( (Tagkw.Ver_Flag==1) && ( Tagkw.MScount >= ( Tagkw.Btyetime/T0TIME ) ) )
{
SCIsendin( ~Tagkw.Waitread[Tagkw.Count-1] );
}
}
//处于发送状态,当ECU将数据取反回发并发送字节间距满时发送下一字节
else if( Tagkw.ComState == SEND_STATE )
{
if( (Tagkw.Ver_Flag==2 ) && ( Tagkw.MScount >= ( Tagkw.Btyetime/T0TIME ) ) )
{
if( !Tagkw.Waitsend )
{
return;
}
SCIsendin( Tagkw.Waitsend[Tagkw.Count] );
}
}
//请求链路时间满发送保持链路
else if( !Tagkw.Ver_Flag && (Tagkw.MScount > ( Tagkw.HoldT/T0TIME )) && Tagkw.hold[0] && Tagkw.LinkFlag )
{
Tagkw.Flashset = 1;
Tagkw.Readset = 0;
Tagkw.MScount = 0;
Tagkw.Count = 0;
Tagkw.Lenth = VW_Getlen( Tagkw.hold );
Tagkw.Waitread = NULL;
Tagkw.Waitsend = Tagkw.hold;
Tagkw.Ver_Flag=3;
Tagkw.ComState=SEND_STATE;
Tagkw.Waitsend[1] = Tagkw.ComCount; //命令计数器的数值累加
SCIsendin( Tagkw.Waitsend[Tagkw.Count] ); //发送第一字节
}
else
{
//NULL
}
}
/*
**-----------------------------------------------------------------------------------------
** 协议串口中断函数
**-----------------------------------------------------------------------------------------
*/
void Kw1281Scon()
{
unsigned char sbufdata;
Tagkw.MScount = 0;
//串口接收中断
if( SCIRE() )
{
SCIENcontrol( 0 );//允许发送,禁止接收
if( Tagkw.ComState == RECE_STATE )
{//处于接收状态,收到的数据将在定时器中断取反发送
sbufdata = SCIreadin();
Tagkw.Waitread[Tagkw.Count] = sbufdata;
Tagkw.Count++;
if( Tagkw.Count == 1 ) Tagkw.Lenth = VW_Getlen( Tagkw.Waitread );
else if( Tagkw.Count == 2 ) Tagkw.ComCount = Tagkw.Waitread[1]+1; //保存命令计数器的数值
Tagkw.Ver_Flag = 1; //接收校验
if( Tagkw.Count >= Tagkw.Lenth ) //接收完毕
{
Tagkw.Ver_Flag = 0;
Tagkw.ComState=0xff;
Tagkw.Count = 0;
Tagkw.Lenth = 0;
Tagkw.Readset = 1;//处于发送状态
Tagkw.Waitread = NULL;
Tagkw.Waitsend = NULL;
}
}
else if( Tagkw.ComState == SEND_STATE )
{//处于发送状态
sbufdata=SCIreadin();
Tagkw.Ver_Flag = 2; //发送校验
}
}
//串口发送
else if( SCISE() )
{
if( Tagkw.Ver_Flag ==1 )//接收状态
{
}
else if( Tagkw.Ver_Flag ==2 )//发送状态
{
Tagkw.Count++;
if( Tagkw.Count >= Tagkw.Lenth ) //发送完毕
{
Tagkw.Flashset = 0;
Tagkw.Count = 0;
Tagkw.Lenth = 0;
Tagkw.Waitsend = NULL;
Tagkw.ComState = RECE_STATE; //接收状态
}
}
else if( Tagkw.Ver_Flag ==3 )//通讯维持
{
Tagkw.Count++;
Tagkw.ComState=SEND_STATE; //处于发送状态
Tagkw.Flashset = 1; //发送数据更新就绪
}
Tagkw.Ver_Flag=0;
SCIENcontrol( 1 );//允许接收,禁止发送
}
}
//----------------------------------------------------------------- End Of File -----------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -