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

📄 protocolkw2000.c

📁 汽车电子解码器电缆测试。可以判断汽车故障在哪里
💻 C
📖 第 1 页 / 共 2 页
字号:
     // 5波特触发
     if( !KWIso_link( SysId, portK, portL ) )
     {
          TimeRelease();
          SCIRelease();
          return FAIL;
     }
     TimeInit( TIMER0,5 );   //初始化T0 10ms
     SCIload( Kw2000Scon );
     TimeLoad( TIMER0, Kw2000Time );
     //发送触发数据
     Tagkw.MScount = 0;
     Tagkw.Waitsend = LinkDig;
     Tagkw.Btyetime = 10;
     Tagkw.Lenth = KW_Getlen( LinkDig );
     Tagkw.Chksum = 0;
     for( i=0; i<Tagkw.Lenth-1; i++ )
     {
          Tagkw.Chksum += Tagkw.Waitsend[i];
     }
     Tagkw.Waitsend[i] = Tagkw.Chksum;
     Tagkw.Count = 0;
     SCIsendin( Tagkw.Waitsend[Tagkw.Count++] );    //发送第一字节
     Tagkw.Flashset = 1; //发送数据更新就绪
     Tagkw.Readset = 0;
     if( KW_Read( Temp, 800, 20 ) )
     {
          return SUCCESS;
     }
     else
     {
          //NULL
     }
     TimeRelease();
     SCIRelease();
     return FAIL;
}
/*
**-----------------------------------------------------------------------------------------
** KWP2000 发送协议包刷新函数
** Dig:待发送数据包
** BtyeDst:发送字节间隔( MS )
**-----------------------------------------------------------------------------------------
*/
char KW_Send( unsigned char *Dig, int BtyeDst )
{
     int i;
     while( Tagkw.MScount < ( 20/T0TIME ) ); //桢间距 20MS
     Tagkw.MScount = 0;
     while( Tagkw.Flashset && ( Tagkw.MScount < ( Tagkw.HoldT/T0TIME-1 ) ) )  //正在发送,等待一个链路时间单位
     {
          //NULL
     }
     Tagkw.MScount = 0;
     while( !Tagkw.Readset && ( Tagkw.MScount < ( Tagkw.HoldT/T0TIME-1 ) ) )   //正在接收,等待一个链路时间单位
     {
          //NULL
     }
     if( !Tagkw.Readset )
     {
          return 0; //上一次收发接收失败
     }
     else
     {
          //NULL
     }
     // 装载发送数据 初始化发送状态
     Tagkw.MScount = 0;
     Tagkw.Waitsend = Dig;
     Tagkw.Btyetime = BtyeDst;
     Tagkw.Lenth = KW_Getlen( Dig );
     Tagkw.Chksum = 0;
     for( i=0; i<Tagkw.Lenth-1; i++ )
     {
          Tagkw.Chksum += Tagkw.Waitsend[i];
     }
     Tagkw.Waitsend[i] = Tagkw.Chksum;
     Tagkw.Count = 0;
     Tagkw.Flashset = 1; //发送数据更新就绪
     while( Tagkw.Flashset && ( Tagkw.MScount < ( Tagkw.HoldT/T0TIME-1 ) ) )    //正在发送,等待1个链路保持时间时间单位
     {
          //NULL
     }
     return SUCCESS;
}
/*
**-----------------------------------------------------------------------------------------
** KWP2000 回送协议包接收函数
** Dig:数据包接收位置
** Wtime:接收等待最大时间(MS)
** MaxLen:最大接收长度
**-----------------------------------------------------------------------------------------
*/
char KW_Read( unsigned char *Dig, int Wtime, unsigned char MaxLen )
{
     unsigned int WaitTime;
     if( Wtime >= Tagkw.HoldT )    Wtime = Tagkw.HoldT;
     Tagkw.MScount = 0;
     while( !Tagkw.Readset && ( Tagkw.MScount < ( Tagkw.HoldT/T0TIME-1 ) ) )    //正在接收,等待一个链路时间单位
     {
          //NULL
     }
     Tagkw.MScount = 0;
     while( Tagkw.Flashset && ( Tagkw.MScount < ( Tagkw.HoldT/T0TIME-1 ) ) )    //正在发送,等待一个链路时间单位
     {
          //NULL
     }
     WaitTime = Wtime/T0TIME;
     Tagkw.MScount = 0;
     Tagkw.Waitread = Dig;
     Tagkw.Lenth = 4;
     Tagkw.Readset = 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;
     return FAIL;
}
/*
**-----------------------------------------------------------------------------------------
** 提取 KWP2000 回送协议包长度信息(KW2000专有函数)
** Dig:数据包
**-----------------------------------------------------------------------------------------
*/
unsigned char  KW_Getlen( unsigned char *Dig )
{
     if( Dig[0]>0x80 )
     {
          return( ( Dig[0]&0x3f )+4 );
     }
     else  if( Dig[0]==0x80 )
     {
          return( Dig[3]+5 );
     }
     else
     {
          return( Dig[0]+1 );
     }
}
/*
**-----------------------------------------------------------------------------------------
** 协议定时器中断函数
**-----------------------------------------------------------------------------------------
*/
void  Kw2000Time()
{
     static char i;
     Tagkw.MScount++;
     //字节间距满发送下一字节
     if( Tagkw.Flashset && ( Tagkw.MScount >= (int)( Tagkw.Btyetime/T0TIME )) )
     {
          if( !Tagkw.Waitsend )
          {
               return;
          }
          SCIsendin( Tagkw.Waitsend[Tagkw.Count] );
          Tagkw.Count++;
          if( Tagkw.Count >= Tagkw.Lenth ) //发送完毕
          {
               Tagkw.Count = 0;
               Tagkw.Lenth = 0;
               Tagkw.Waitsend = NULL;
          }
          else
          {
               //NULL
          }
     }
     //请求链路时间满发送保持链路
     else  if( Tagkw.MScount > (int)( Tagkw.HoldT/T0TIME ) && Tagkw.hold[0] )
     {
          Tagkw.MScount = 0;
          Tagkw.Count = 0;
          Tagkw.Lenth = KW_Getlen( Tagkw.hold );
          Tagkw.Waitread = NULL;
          Tagkw.Waitsend = Tagkw.hold;
          Tagkw.Chksum = 0;
          for( i=0; i<Tagkw.Lenth-1; i++ )
          {
               Tagkw.Chksum += Tagkw.Waitsend[i];
          }
          Tagkw.Waitsend[i] = Tagkw.Chksum;
          Tagkw.Count = 0;
          SCIsendin( Tagkw.Waitsend[Tagkw.Count++] ); //发送第一字节
          Tagkw.Flashset = 1; //发送数据更新就绪
     }
     else
     {
          //NULL
     }
}
/*
**-----------------------------------------------------------------------------------------
** 协议串口中断函数
**-----------------------------------------------------------------------------------------
*/
void  Kw2000Scon()
{
     Tagkw.MScount = 0;
     //串口接收中断
     if( SCIRE() )
     {
          if( !Tagkw.Waitread )    return;
          Tagkw.Waitread[Tagkw.Count] = SCIreadin();
          if( Tagkw.Waitread[0] ==0x80 )
          {
               if( Tagkw.Count == 3  ) Tagkw.Lenth = KW_Getlen( Tagkw.Waitread );
          }
          else if( Tagkw.Count == 0 )
          {
               Tagkw.Lenth = KW_Getlen( Tagkw.Waitread );
          }
          Tagkw.Count++;
          if( Tagkw.Count >= Tagkw.Lenth )   //接收完毕
          {
               Tagkw.Count = 0;
               // Kw2000 协议 ECU 忙标志
               if( Tagkw.Waitread[0] >0x80 && Tagkw.Waitread[3] == 0x7f )  return;
               if( Tagkw.Waitread[0] ==0x80 && Tagkw.Waitread[4] == 0x7f ) return;
               // Kw2000 协议 ECU 忙标志
               Tagkw.Lenth = 0;
               Tagkw.Readset = 1;
               Tagkw.Waitread = NULL;
          }
     }
     //串口发送
     else if( SCISE() )
     {
          if( !Tagkw.Waitsend ) //发送完毕
          {    //注意: 程序经典错误 <时间性的控制错误> 逻辑上没有问题的中断代码在模拟运行时
               //必须考虑中断响应存在响应时间,以下发送流程解晰
               //向串口发送数据由定时器引发
               //定时器发送数据0 | 中断响应时间 |     定时器发送数据1 | 中断响应时间 |
               //                                -串口中断0                           -串口中断1
               //可以看到实际的发送 2 个字节数据 完毕是在 串口中断1 而并不是在 定时器发送数据1 的定时中断内
               //所以若以定时中断为基准判断收发标记
               //理论上已经下达 了 2次发送请求,但实际在串口中断1响应前只完成发送一次数据
               //这时误以为已经发送完毕而打开接收的话,如果程序执行时间 小于 中断响应时间 就会
               //在 串口中断1 产生之前允许接收,在单工总线情况下就会误收到乱数
               Tagkw.Flashset = 0;
          }
     }
}

//----------------------------------------------------------------- End Of File -----------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -