Ixxat CAN 接口状态

CAN 接口状态的获取

canControlGetStatus

周期性调用canControlGetStatus API

HRESULT EXTERN_C canControlGetStatus (
HANDLE hCanCtl,
PCANLINESTATUS pStatus
);

pStatus 指针指向一个CANLINESTATUS 结构体

typedef struct _CANLINESTATUS
{
UINT8 bOpMode;
UINT8 bBtReg0;
UINT8 bBtReg1;
UINT8 bBusLoad;
UINT8 dwStatus;
} CANLINESTATUS, *PCANLINESTATUS;

应用程序可根据返回的指针指向一个CANLINESTATUS 中的各属性进行CAN接口状态的判断

  1. bOpMode 当前CAN控制器的模式

    • CAN_OPMODE_STANDARD: 接收11位标识符
    • CAN_OPMODE_EXTENDED: 接收29位标识符
    • CAN_OPMODE_ERRFRAME: 错误消息通过特殊的CAN消息传递给应用程序
    • CAN_OPMODE_LISTONLY: 只听模式
    • CAN_OPMODE_LOWSPEED: 使用低速CAN模式
    • CAN_OPMODE_AUTOBAUD: 自动检测波特率
  2. bBtReg0 和 bBtReg1 分别对应Philips SJA 1000 CAN控制器的BTR0和BTR1 寄存器(16MHz 时钟频率),可换算为CAN总线的波特率

  3. bBusLoad 表示当前CAN总线的负载率的百分比(需要使用的CAN 接口型号支持该功能,可通过canControlGetCaps 获取控制器支持的功能特性CANCAPABILITIES中的dwFeatures)

    typedef struct _CANCAPABILITIES
    {
    UINT16 wCtrlType;
    UINT16 wBusCoupling;
    UINT32 dwFeatures;
    UINT32 dwClockFreq;
    UINT32 dwTscDivisor;
    UINT32 dwCmsDivisor;
    UINT32 dwCmsMaxTicks;
    UINT32 dwDtxDivisor;
    UINT32 dwDtxMaxTicks;
    } CANCAPABILITIES, *PCANCAPABILITIES;
    
  4. dwStatus 当前CAN 控制器的状态

    • CAN_STATUS_TXPEND: 正在传输一条CAN报文
    • CAN_STATUS_OVRRUN: 接收缓存器过载,需要Reset CAN控制器
    • CAN_STATUS_ERRLIM: CAN 错误计数器溢出
    • CAN_STATUS_BUSOFF: CAN 控制器 bus-off
    • CAN_STATUS_ININIT: CAN 控制器处于stopped状态
    • CAN_STATUS_BUSCERR: CAN 总线耦合错误

CAN 消息中的CANMSGINFO

在使用canChannelPeekMessage,canChannelPeekMsgMult,canChannelReadMessage,canChannelReadMsgMult 等API 读取CAN总线上接收到的消息时,可首先判断PCANMSG 中的uMsgInfo bType 属性,用于判断接收到的CAN消息是数据报文还是状态或错误报文

typedef struct _CANMSG
{
UINT32 dwTime;
UINT32 dwMsgId;
CANMSGINFO uMsgInfo;
UINT8 abData[8];
} CANMSG, *PCANMSG;
typedef struct _CANMSGINFO
{
UINT8 bType;
UINT8 bFlags2;
UINT8 bFlags;
UINT8 bAccept;
} CANMSGINFO, *PCANMSGINFO;
  • bType
    • CAN_MSGTYPE_DATA: 正常数据帧
      
    • CAN_MSGTYPE_INFO: 信息帧,如控制器状态变化等
      
    • CAN_MSGTYPE_ERROR: 控制器检测到的错误帧
      
    • CAN_MSGTYPE_STATUS: 状态帧,当前CAN 控制器的状态,参见上文dwStatus
      
    • CAN_MSGTYPE_WAKEUP: 唤醒帧
      
    • CAN_MSGTYPE_TIMEOVR: 超时帧
      
    • CAN_MSGTYPE_TIMERST: 时间复位帧
      

示例代码


    hResult = canChannelReadMessage(hCanChn, 100, &sCanMsg);

    if (hResult == VCI_OK)
    {
      if (sCanMsg.uMsgInfo.Bytes.bType == CAN_MSGTYPE_DATA)
      {
        // show data frames 
        if (sCanMsg.uMsgInfo.Bits.rtr == 0)
        {
          UINT8 j;

          _tprintf(TEXT("\nTime: %10u  ID: %3X  DLC: %1u  Data:"),
            sCanMsg.dwTime, sCanMsg.dwMsgId, sCanMsg.uMsgInfo.Bits.dlc);

          for (j = 0; j < sCanMsg.uMsgInfo.Bits.dlc; j++)
          {
            _tprintf(TEXT(" %.2X"), sCanMsg.abData[j]);
          }
        }
        else
        {
          _tprintf(TEXT("\nTime: %10u ID: %3X  DLC: %1u  Remote Frame"),
            sCanMsg.dwTime, sCanMsg.dwMsgId, sCanMsg.uMsgInfo.Bits.dlc);
        }
      }
      else if (sCanMsg.uMsgInfo.Bytes.bType == CAN_MSGTYPE_INFO)
      {
        // show informational frames
        switch (sCanMsg.abData[0])
        {
          case CAN_INFO_START:
            _tprintf(TEXT("\nCAN started..."));
            break;

          case CAN_INFO_STOP:
            _tprintf(TEXT("\nCAN stoped..."));
            break;

          case CAN_INFO_RESET:
            _tprintf(TEXT("\nCAN reseted..."));
            break;
        }
      }
      else if (sCanMsg.uMsgInfo.Bytes.bType == CAN_MSGTYPE_ERROR)
      {
        // show error frames
        switch (sCanMsg.abData[0])
        {
          case CAN_ERROR_STUFF:
            _tprintf(TEXT("\nstuff error..."));
            break;

          case CAN_ERROR_FORM:
            _tprintf(TEXT("\nform error..."));
            break;

          case CAN_ERROR_ACK:
            _tprintf(TEXT("\nacknowledgment error..."));
            break;

          case CAN_ERROR_BIT:
            _tprintf(TEXT("\nbit error..."));
            break;

          case CAN_ERROR_CRC:
            _tprintf(TEXT("\nCRC error..."));
            break;

          case CAN_ERROR_OTHER:
          default:
            _tprintf(TEXT("\nother error..."));
            break;
        }
      }
      else if (sCanMsg.uMsgInfo.Bytes.bType == CAN_MSGTYPE_STATUS)
      {
         // show status frames
        switch (sCanMsg.abData[0])
        {
          case CAN_STATUS_TXPEND:
            _tprintf(TEXT("\n transmission pending..."));
            break;

          case CAN_STATUS_OVRRUN:
            _tprintf(TEXT("\n data overrun occurred..."));
            break;

          case CAN_STATUS_ERRLIM:
            _tprintf(TEXT("\n error warning limit exceeded..."));
            break;

          case CAN_STATUS_BUSOFF:
            _tprintf(TEXT("\n bus off status..."));
            break;

          case CAN_STATUS_ININIT:
            _tprintf(TEXT("\n init mode active..."));
            break;

          case CAN_STATUS_BUSCERR:
            _tprintf(TEXT("\n bus coupling error..."));
            break;
          default:
            _tprintf(TEXT("\nother error..."));
            break;
        }
    }
  }
 

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。