CAN/杂谈/Scope

CAN驱动总线(高速),500Kbit/s,可基本满足实时要求。

CAN舒适总线(低速),100 Kbit/s,用于对时间要求不高的情况。 

数据传输终端:是一个电阻,防止数据在线端被反射,以回声的形式返回,影响数据的传输。

数据传输线:双向数据线,由高低双绞线组成。

当车辆使用诊断CANBUS总线结构后,VAS5051等诊断仪器必须使用相对应的新型诊断线(VAS5051/5A或VAS5051/6A), 否则无法读出相应的诊断信息。另外,车上的诊断接口也作出了相应的改动,具体信息看如下图表: 注:5051仪器的版本号必须大于3.0以上     才能使用诊断CANBUS总线。 新型诊断线能够适用于旧型诊断接口。

   CAN具有以下的属性:      

• 报文的优先权      

• 保证延迟时间    

 • 设置灵活    

• 时间同步的多点接收  

• 系统内数据的连贯性

 • 多主机

• 错误检测和错误标定  

• 只要总线一处于空闲,就自动将破坏的报文重新传输

 • 将节点的暂时性错误和永久性错误区分开来,并且可以自动关闭由OSI参考模型分层CAN结构的错误的节点。 

7 个不同的场组成。数据场长度可为 0
CAN2.0B 存在标准和扩展两种帧格式
为了设计简单�可以对标准格式执行部分扩展,不一定要完全扩展
可以用整个标识符进行报文滤波�也可以把标识符屏蔽一部分进行报文滤波
帧起始� SOF 仅由一显位构成。所有站都必须同步于首先发送的那个帧起始前沿
仲裁场�标准格式� 11 位标识符 ID28~ ID18, 远程发送请求位RTR 组成�其中 ID 高七位不可全为1 �隐性�。
仲裁场�扩展格式� 29 位标识符 ID28~ ID0 、 SRR位、 IDE 位、 RTR 位组成
SRR 是隐性位�它用于替代标准格式的 RTR 位。
IDE=1 �隐性�代表扩展格式。 IDE 位在扩展格式 中位于仲裁场而在标准格式中位于控制场。
控制场 6 个位组成
数据长度码 DLC3~DLC0 指示数据场的字节数� 0~8�其他数值不允许使用。
保留位 r1 r0 必须为 0 IDE( 标准格式 )=0
数据场� 0~8 个字节� 8 / 字节� MSB 先发
CRC 15 CRC 序列和 1 CRC 界定符组成。 CRC界定符为一隐性位。
应答场 2 位�包括应答间隙和应答界定符�不进行位填充。
在应答间隙时间�发送器发隐位�所有正确接收到有效报文的接收器发一个显位。
应答界定符为隐位 (1)
帧结束� 7 个隐位组成�不进行位填充

错误帧

错误帧由两个不同的场组成�第一个场是不同站 提供的错误标志的叠加�第二个场是错误界定符。
错误标志 分两种�主动错误标志� 6 个显性位�和 被动错误标志�6 个隐性位�
检测到错误条件的“错误主动”站发送主动错误 标志�这样一来所有其他站都会检测到错误条件
并开始发送错误标志。叠加在一起最多 12 个显性位
检测到错误条件的“错误被动”站发送被动错误 标志。从那时开始�等待6 个相同极性的位� 一旦 等到�被动错误标志就算完成
错误界定符 包括 8 个隐性位。一个站发送错误标志 以后�就发送一个隐性位�并一直监视总线�直到发现一个隐性位�就发送其余7 个隐性位。

过载帧

过载帧包括两个场�过载标志� 6 个显位及其叠加�和过 载界定符�8 个隐位�
导致发送过载标志的条件� ①接收器内部要求延迟下一个 数据帧或远程帧�②在间歇场第一或第二位检测到一个显 性位
过载标志 的形式与主动错误标志一样
一个站发出过载标志�其他站都将检测到过载条件并发出 过载标志。
过载界定符 的形式与错误界定符一样。过载标志发送后� 站就监视总线直到发现从显位到隐位的跳变�然后发送其 余7 个隐性位。

错误类型和界定

5种错误类型�

(1)
位错误�发送器监视到总线位数值与发出的位数值不同。仲裁场填充位和应答间隙发出隐位而检测到显位则例外
(2)
填充错误�应该使用位填充的地方出现第 6 个相同位。
(3)
CRC 错误�计算结果与收到的 CRC 不同
(4)
形式错误�固定形式的位场中出现非法位
(5)
应答错误�在应答间隙�发送器未检测到显位
检测到 CRC 错误�应在应答界定符后发送错误标志�检测到其他错误应在下一位发送错误标志。
节点的 3 种故障状态�①错误主动�②错误被动� ③总线关闭
正常情况下节点是“错误主动”站�此类站检测到错误时发送主动错误标志
出现错误较多的节点转为“错误被动”站�此类 站检测到错误时只能发被动错误标志
出现太多错误时节点转为“总线关闭”状态�此时节点不可对总线有任何影响�例如关闭输出驱动器�

应用


on sysvar_change (sysvar::TransitionTimeMeasurement::SignalUsedForMeasurement | sysvar::TransitionTimeMeasurement::ThresholdInPercent)
{
  switch(@sysvar::TransitionTimeMeasurement::SignalUsedForMeasurement)
  {
    case 0: 
        if(@sysvar::TransitionTimeMeasurement::ThresholdInPercent == 0)

        {
          @sysvar::TransitionTimeMeasurement::ThresholdStart = 2630;
          @sysvar::TransitionTimeMeasurement::ThresholdEnd   = 3590;
        }
        else
        {
          @sysvar::TransitionTimeMeasurement::ThresholdStart = 10;
          @sysvar::TransitionTimeMeasurement::ThresholdEnd = 90;
        }
        break;
    case 1: 
        if(@sysvar::TransitionTimeMeasurement::ThresholdInPercent == 0)
        {
         @sysvar::TransitionTimeMeasurement::ThresholdStart = 1565;
         @sysvar::TransitionTimeMeasurement::ThresholdEnd   = 2485;
        }
        else
        {
          @sysvar::TransitionTimeMeasurement::ThresholdStart = 10;
          @sysvar::TransitionTimeMeasurement::ThresholdEnd   = 90;
        }
        break;
    case 2: 
        if(@sysvar::TransitionTimeMeasurement::ThresholdInPercent == 0)
        {
         @sysvar::TransitionTimeMeasurement::ThresholdStart = 186;
         @sysvar::TransitionTimeMeasurement::ThresholdEnd   = 2073;
        }
        else
        {
          @sysvar::TransitionTimeMeasurement::ThresholdStart = 10;
          @sysvar::TransitionTimeMeasurement::ThresholdEnd   = 90;
        }
        break;
        
  }
}

test如何立即执行

测量开始的默认窗口

节点的属性宏-可调用

  • %NODE_NAME%
    Node name//只能用在节点中,不能用在test
  • %CHANNEL%
    Number of the channel to which the node is assigned.
  • %NETWORK_NAME%
    Number of the network to which the node is assigned.
  • %FILE_NAME%//XX.can
    Name of the file that contains the source code (e.g. SomeIncludeFile.cin).
  • %FILE_NAME_NO_EXT%//XX
    Name of the file that contains the source code but without file extension (e.g. SomeIncludeFile).
  • %BASE_FILE_NAME%//
    Name of the .can file that is just compiled (e.g. SomeFile.can); especially useful in include files.
  • %BASE_FILE_NAME_NO_EXT%
    Name of the .can file that is just compiled but without file extension (e.g. SomeFile); especially useful in include files.
  • %BUS_TYPE%//CAN/LIN
    Bus type of the channel to which the node is assigned.

write("The node name is %NODE_NAME%");
write("Activated functionality in network %NETWORK_NAME% (Channel %BUS_TYPE%%CHANNEL%)");

message * canTestMessage;//要测量的message

 message EngineData msg1;

  //enable ACK
  canSetChannelOutput(%CHANNEL%, 1);//默认是1 可写可不写,停发的时候可以写0
  canTestMessage = msg1;//可重复赋值
  canTestMessage.can = %CHANNEL%;

variables
{
  char scopeTestStepName[256];

  const long domVoltageThreshold = 900; //mV
  const long recVoltageThreshold = 500; // mV

  //bit masks used for analysis
  ScopeBitMaskPolygon bitMaskArb;
  ScopeBitMaskPolygon bitMaskBRS;
  ScopeBitMaskPolygon bitMaskData;
  ScopeBitMaskPolygon bitMaskCRCdel;
  
  //bit lengths in ns
  double bitLengthArb, bitLengthBRS, bitLengthData, bitLengthCRCdel;

  //the one and only analysis handle used for all analysis functions
  ScopeAnalyseHandle scopeAnlyzHandle = {Handle = 999};
  
  long maxNumOfErrorsToShow = 10; //max. number of errors added in test report
  
  CANSettings arbPhaseSettings;
  CANSettings dataPhaseSettings;
  
}

nt WaitForAnyCANMessage()
{
  long res;
  res = TestWaitForMessage(1000);

  if(res < 0){
    testStepFail(testStepName, "No message received", "");
    return 0;
  }
  
  res = TestGetWaitEventMsgData(canTestMessage);//获取数据到cantestmessage
  if(res != 0){

    testStepFail(testStepName, "No message received", "");
    return 0;
  }
  return 1;
}

testfunction Init ()
{
  maxNumOfErrorsToShow =10;
  
  InitBitMaskArbitration();
  InitBitMaskBRS();
  InitBitMaskData();
  InitBitMaskCRCdel();

  strncpy(testStepName, "Test Prepration", testStepNameLength);
  
  testWaitForTimeout(1000); //needed for virtual scope, if test modul is started immiditly
  if(DoScopeConnect() <= 0 ) return;
  
  if(!WaitForAnyCANMessage()) 
  {
    write("Waiting for CAN message failed");
    return;
  }

  
  if(!DoScopeTrigger()) 
  {
    write("Scope trigger failed");
    return;
  }
  
  {
    long res;
    res = testWaitForScopeFitData(canTestMessage, eCAPLScopeDataField_CAN_MESSAGE, eCAPLScopeDataField_CAN_MESSAGE);//前面必须获取数据到此message,此函数有效
    if(CheckStatusInternal(res, "testWaitForScopeFitData"))//返回值正确
    {
      const long bufLength = 256;
      char buffer[bufLength];
      snprintf(buffer, bufLength, "Frame under test. ID = %d, DLC = %d, EDL = %d, BRS = %d",
        valOfId(canTestMessage.id), canTestMessage.dlc, canTestMessage.edl, canTestMessage.BRS);
      TestReportAddWindowCapture("Scope", scopeTestStepName, buffer);//截图scope
    }
  }
}

 int CheckStatusInternal(long status, char text[])
{
 if(status <= 0)
 {
   testStepFail(scopeTestStepName, " Internal error in %s, return code = %d", text, status);
   return 0;
 }
 return 1;
}


int DoBitAnlyz(ScopeBitMaskPolygon bitMask, dword startField, dword endField, char text[], double bitLength)
{
  int i;
  const int testRepetitions = 3;
  const long textLength = 256;
  char text1[textLength], bitNameStartField[textLength], bitNameEndField[textLength];
  
  long flags, numOfInValidMasks, invalidMaskNumber;
 
  GetBitFieldName(bitNameStartField, textLength, startField);
  GetBitFieldName(bitNameEndField, textLength, endField);
  if(startField != endField)

        testReportAddExtendedInfo("text", "Analysing bits from %s to %s", bitNameStartField, bitNameEndField);//添加表头
  else

         testReportAddExtendedInfo("text", "Analysing bit %s", bitNameStartField);
  
  flags = 0;

  for(i=0;;++i)
  {
    numOfInValidMasks = TestWaitScopeAnalyseSignal(canTestMessage, flags, 
    startField, endField, 
    bitMask, domVoltageThreshold, recVoltageThreshold, scopeAnlyzHandle);//900 500mv显隐性阈值
  
    if(numOfInValidMasks < 0)//如果重复测量三次-警告;第四次报错
    {
      if(i<testRepetitions)
      {
        testStepWarning(testStepName, " Internal error in %s, return code = %d", "TestWaitScopeAnalyseSignal", numOfInValidMasks);
      }
      else
      {
        testStepFail(testStepName, " Internal error in %s, return code = %d", "TestWaitScopeAnalyseSignal", numOfInValidMasks);

        return 0;
      }
    }
    else

        break;
  }
  if(numOfInValidMasks == 0)
  {
    //no mask violations found
    snprintf(text1, textLength, "First bit(s) of the analyzed cutout");
    DoShowBitMask(scopeAnlyzHandle, startField, 0, 10, text1);
  }
  else 
  {
    //there are bit mask violations
    testStepFail(scopeTestStepName, "%d bit mask violations found.", numOfInValidMasks);

    //iterate through all erroneous bits, make a screen shot, and  add a description to the test report
    for(invalidMaskNumber = 1; invalidMaskNumber <= numOfInValidMasks && invalidMaskNumber <= maxNumOfErrorsToShow; ++invalidMaskNumber)
    {
      ScopeMaskViolationData maskViolationData;
      if(DoGetCAPLViolationMask(scopeAnlyzHandle, invalidMaskNumber, maskViolationData)){
        ShowBitMask(scopeAnlyzHandle, invalidMaskNumber, maskViolationData, bitMask, bitLength);
      }
    }
  }
  
  //get average voltages//获取平均电压
  if(startField != endField)
  {
    long res;
    ScopeMaskViolationData maskViolationData;
    res =
testWaitScopeGetBitInfo(scopeAnlyzHandle, startField, 0, endField, 0, maskViolationData);
    if(!CheckStatusInternal(res, "testWaitScopeGetBitInfo")) return 0;
   
//添加到表头
    TestReportAddExtendedInfo("text", "Average voltages:\nCAN high dominant = %d mV, CAN high recessive = %d mV\nCAN low dominant = %d mV, CAN low recessive = %d mV\nCAN diff dominant = %d mV, CAN diff recessive = %d mV", 
     maskViolationData.domVoltageCANH, maskViolationData.recVoltageCANH,
     maskViolationData.domVoltageCANL, maskViolationData.recVoltageCANL,
     maskViolationData.domVoltageDiff, maskViolationData.recVoltageDiff);

  }
  return 1;
}
 

int DoShowBitMask(ScopeAnalyseHandle handle, long msgFieldStart, long bitIndex, long bitCount, char text[])
{
  long res;

  //display the cutout in the scope window
  res = TestWaitScopeShowMask(handle, msgFieldStart, bitIndex, bitCount);//仅显示差分信号
  if(res != 1) 
  {
    testStepFail(scopeTestStepName, " Internal error in TestWaitScopeShowMask, return code = %d", res);
    return 0;
  }

  //make a scrren shot and add it to the test report
  TestReportAddWindowCapture("Scope", scopeTestStepName, text);//截图
  
  return 1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yuanyikangkang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值