This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] LAUNCHXL-F28379D:使用 DriverLib 禁用 CAN RX 邮箱 ID 过滤

Guru**** 2524550 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/931171/launchxl-f28379d-disable-can-rx-mailbox-id-filtering-with-driverlib

器件型号:LAUNCHXL-F28379D
您好!
我正在尝试使用 DriverLib 配置 CAN 邮箱、以便通过以下方式接收所有11位消息 ID:
const uint32_t g_CAN_BASE = CANB_BASE;
const uint32_t g_CAN_Rx_obj_id = 2;
CAN_setupMessageObject()
  G_CAN_BASE、        // CAN 总线选择
  G_CAN_Rx_obj_id、     // RX 邮箱
  0、            //消息 ID (无关)-但程序按此...进行过滤
  CAN_MSG_FRAME_STD、   //不支持扩展 ID
  CAN_MSG_OBJ_TYPE_RX、  //接收
  0、            //无消息过滤
  CAN_MSG_OBJ_NO_FLAGS、  //无标志
  8);            //消息长度(无关)
稍后、我使用以下命令轮询邮箱以查找循环中的消息:
uint16_t l_msg_data[8];
if (CAN_readMessage (g_CAN_BASE、g_CAN_Rx_obj_id、l_msg_data))
  //处理消息
当我发送 ID 为0的消息时、CAN_readMessage 返回 true 并且消息数据被正确复制。 当我发送一个非零 ID 时、它返回 false。 为了验证 ID 过滤是否是问题、我将 CAN_setupMessageObject 中的消息 ID 更改为5、此时它仅在 ID 为5的消息上返回 true。 我在《技术手册》中读到、必须使用消息 ID 掩码和 flags 参数手动设置滤波、这两个参数都已设置为0 (CAN_MSG_OBJ_NO_FLAGS)。 那么、为什么要过滤消息、如何禁用所有消息过滤呢? 我也希望接收 EXT 和 RTR 消息、这些消息也会被过滤掉。
以下是我的 DriverLib 版本的相关源代码供参考:
//
//
// CAN_setupMessageObject
//
//
无效
CAN_setupMessageObject (uint32_t base、uint32_t Objid、uint32_t msgid、
            CAN_MsgFrameType 帧、CAN_MsgObjType msgType、
            uint32_t msgIDMask、uint32_t flags、uint16_t msgLen)
  uint32_t cmdMaskReg = 0U;
  uint32_t maskReg = 0U;
  uint32_t arbReg = 0U;
  uint32_t msgCtrl = 0U;
  //
  //检查参数。
  //
  assert (CAN_isBaseValid (base));
  assert ((Objid <= 32U)&&(Objid >0U));
  assert (msgLen <= 8U);
  //
  //等待忙位清零
  //
  while ((HWREGH (base + CAN_O_IF1CMD)& CAN_IF1CMD_BUSY)== CAN_IF1CMD_BUSY)
  {
  }
  switch (msgType)
  {
    //
    //发送消息对象。
    //
    案例 CAN_MSG_OBJ_TYPE_TX:
    {
      //
      //设置要发送的消息方向。
      //
      arbReg = CAN_IF1ARB_DIR;
      中断;
    }
    //
    //远程帧接收远程,带有自动发送消息对象。
    //
    案例 CAN_MSG_OBJ_TYPE_RxTx_REMOTE:
    {
      //
      //为远程接收器将消息方向设置为 Tx。
      //
      arbReg = CAN_IF1ARB_DIR;
      //
      //如果看到匹配的标识符,则将此对象设置为自动应答。
      //
      msgCtrl =(uint32_t)((uint32_t) CAN_IF1MCTL_RMTEN |
                 (uint32_t) CAN_IF1MCTL_UMASK);
      中断;
    }
    //
    //发送远程请求消息对象(CAN_MSG_OBJ_TYPE_TX_REMOTE)
    //或接收消息对象(CAN_MSG_OBJ_TYPE_RX)。
    //
    默认值:
    {
      //
      //将消息方向设置为读取。
      //
      arbReg = 0U;
      中断;
    }
  }
  //
  //根据扩展帧或标准帧设置值
  //
  if (帧== CAN_MSG_FRAME_EXT)
  {
    //
    //为29位标识符屏蔽配置屏蔽寄存器。
    //
    if (((flags & CAN_MSG_obj_use_ID_filter)== CAN_MSG_obj_use_ID_filter)
    {
      maskReg = msgIDMask & CAN_IF1MSK_MSK_M;
    }
    //
    //为此消息设置29位版本的标识符
    //对象。 将消息标记为有效并设置扩展 ID 位。
    //
    arbReg ||(msgid & CAN_IF1ARB_ID_M)| CAN_IF1ARB_MSGVAL |
         CAN_IF1ARB_XTD;
  }
  其他
  {
    //
    //为11位标识符屏蔽配置屏蔽寄存器。
    //
    if (((flags & CAN_MSG_obj_use_ID_filter)== CAN_MSG_obj_use_ID_filter)
    {
      MaskReg =((msgIDMask << CAN_IF1ARB_STD_ID_S)和
           CAN_IF1ARB_STD_ID_M);
    }
    //
    //为此消息设置11位版本的标识符
    //对象。 低18位设置为零。 将消息标记为
    //有效。
    //
    arbReg |=((msgid << CAN_IF1ARB_STD_ID_S)和 CAN_IF1ARB_STD_ID_M)|
         CAN_IF1ARB_MSGVAL;
  }
  //
  //如果呼叫者希望在扩展 ID 位上进行筛选,则将其置位。
  //
  maskReg |=(flags & CAN_MSG_obj_use_EXT_filter);
  //
  //呼叫者希望在消息方向字段上进行筛选。
  //
  maskReg |=(flags & CAN_MSG_obj_use_DIR_filter);
  //
  //如果请求任何过滤,请将 UMASK 位置位,使用屏蔽寄存器
  //
  if (((flags & CAN_MSG_obj_use_ID_filter)|
    (flags & CAN_MSG_OBJ_USE_DIR_FILTER)|
    (flags & CAN_MSG_OBJ_USE_EXT_FILTER)!= 0U)
  {
    msgCtrl |= CAN_IF1MCTL_UMASK;
  }
  //
  //设置传输的数据长度。
  //这适用于 Tx 邮箱。
  //
  msgCtrl |=((uint32_t) msgLen 和 CAN_IF1MCTL_DLC_M);
  //
  //如果这是单次传输或 FIFO 的最后一个邮箱,则设置 EOB 位。
  //如果这不是 FIFO 中的最后一个入口,则将 EOB 位保留为0。
  //
  if ((flags & CAN_MSG_OBJ_FIFO)== 0U)
  {
    msgCtrl |= CAN_IF1MCTL_EOB;
  }
  //
  //如果应启用发送中断,则启用它们。
  //
  msgCtrl |=(flags & CAN_MSG_OBJ_TX_INT_ENABLE);
  //
  //如果应该启用接收中断,则启用它们。
  //
  msgCtrl |=(flags & CAN_MSG_OBJ_RX_INT_ENABLE);
  //
  //设置 Control (控制)、ARB (ARB)和 Mask (掩码)位,以便将其传送到
  //消息对象。
  //
  cmdMaskReg |= CAN_IF1CMD_ARB;
  cmdMaskReg |= CAN_IF1CMD_CONTROL;
  cmdMaskReg |= CAN_IF1CMD_MASK;
  cmdMaskReg |= CAN_IF1CMD_DIR;
  //
  //写出寄存器以编程报文对象。
  //
  assert (maskReg =0);  //{TODO}删除
  HWREG_BP (base + CAN_O_IF1MSK)= maskReg;
  HWREG_BP (base + CAN_O_IF1ARB)= arbReg;
  HWREG_BP (base + CAN_O_IF1MCTL)= msgCtrl;
  //
  //将数据传输到消息对象 RAM
  //
  HWREG_BP (base + CAN_O_IF1CMD)=
  cmdMaskReg |(Objid & CAN_IF1CMD_MSG_NUM_M);
//
//
// CAN_readMessage
//
//
布尔
CAN_readMessage (uint32_t base、uint32_t Objid、
        uint16_t * msgData)
  bool 状态;
  uint16_t msgCtrl = 0U;
  //
  //检查参数。
  //
  assert (CAN_isBaseValid (base));
  assert ((Objid <= 32U)&&(Objid!= 0U));
  //
  //设置要读取的消息数据 A、数据 B 和控制值
  //从报文对象请求数据时。
  //
  //将报文对象传输到报文对象 IF 寄存器。
  //
  HWREG_BP (base + CAN_O_IF2CMD)=
  (((uint32_t) CAN_IF2CMD_DATA_A |(uint32_t) CAN_IF2CMD_DATA_B |
   (uint32_t) CAN_IF2CMD_CONTROL |(Objid & CAN_IF2CMD_MSG_NUM_M)|
(uint32_t) CAN_IF2CMD_ARB);
  //
  //等待忙位清零
  //
  while ((HWREGH (base + CAN_O_IF2CMD)& CAN_IF2CMD_BUSY)== CAN_IF2CMD_BUSY)
  {
  }
  //
  //读取 IF 控制寄存器。
  //
  msgCtrl = HWREGH (base + CAN_O_IF2MCTL);
  //
  //查看是否有可用的新数据。
  //
  if (((msgCtrl & CAN_IF2MCTL_NEWDAT)=CAN_IF2MCTL_NEWDAT)
  {
    //
    //从 CAN 寄存器中读出数据。
    //
    CAN_readDataReg (msgData、(base + CAN_O_IF2DATA)、
            (msgCtrl & CAN_IF2MCTL_DLC_M);
    状态= true;
    //
    //现在清除新的数据标志
    //
    HWREG_BP (base + CAN_O_IF2CMD)=((uint32_t) CAN_IF2CMD_TXRQST |
                    (Objid & CAN_IF2CMD_MSG_NUM_M);
    //
    //等待忙位清零
    //
    while ((HWREGH (base + CAN_O_IF2CMD)& CAN_IF2CMD_BUSY)==
        CAN_IF2CMD_BUSY)
    {
    }
  }
  其他
  {
    状态= false;
  }
  退货(状态);
提前感谢、
Dan
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    请下载我的应用报告 http://www.ti.com/lit/sprace5 。 它有许多经过测试的示例、包括一个用于接受屏蔽滤波的示例。 我还敦促您查看提供的调试提示。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    我查看了随附的 PDF 并查看验收滤波示例、但没有参考如何在实践中完全禁用验收滤波。 有关发现的解决方案、请参阅我的其他意见。 我认为此注释将是对您的 PDF 的一个很好的补充。

    Dan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我通过实验独立解决了这个问题。 我发现要禁用消息 ID 过滤、您必须将标志设置为按 ID 过滤、然后将所有过滤位设置为0 (无关)、如下所示:

    CAN_setupMessageObject()
      G_CAN_BASE、             // CAN 总线选择
       G_CAN_Rx_obj_id、        //专用 RX 邮箱 ID
       0、                   //消息 ID (无关)
       CAN_MSG_FRAME_STD、       //不支持扩展 ID
       CAN_MSG_OBJ_TYPE_RX、     // RX 邮箱
       0x00000000、             //接受所有消息 ID
       CAN_MSG_OBJ_USE_ID_FILTER、 //按 ID 过滤(不直观)
       8);                   //消息长度(无关)

    虽然这个问题解决了、但必须通过 CAN_MSG_OBJ_USE_ID_FILTER 启用滤波、然后禁用每个位、这样才能禁用滤波、这是非常不直观的、我相信 API 会从修订版中受益。 至少应在 DriverLib API 文档中添加注释。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Dan、

    我同意这种说法是反直觉的、令人困惑的。 我将提交更新请求、以添加相应的注释。

    另一个注意事项是、当您在 e2e 帖子中包含代码片段时、请使用适当的格式化工具。 这将打开代码段的相应颜色、使其更易于阅读。 请参阅要使用的图标上的附加图像。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢你哈雷什-我将来会这样做的!