⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 protocolvw.c

📁 汽车电子解码器电缆测试。可以判断汽车故障在哪里
💻 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 + -