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.

[参考译文] TMS320F28379D:使用 CAN 位域 API,如何在 setupMessageObject()中设置掩码

Guru**** 2549940 points
Other Parts Discussed in Thread: C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1362424/tms320f28379d-using-can-bitfield-api-how-to-set-the-mask-in-setupmessageobject

器件型号:TMS320F28379D
主题中讨论的其他器件:C2000WARE

您好!  

我使用的 F28379D 器件具有 CAN 通信功能、 由于应用程序的需要、我使用的是 bitfield CAN、参考 C2000Ware_5_01_00_00\device_support\f2837xd\examples\cpu1\can_loopback_bitfields\cpu01\示例

示例代码在器件上完美运行。 我注意到, 示例中提供的 setupMessageObject()函数似乎没有为消息过滤设置掩码。 (还随附源文件)

//
// setupMessageObject - Setup message object as Transmit or Receive
//
void setupMessageObject(uint32_t objID, uint32_t msgID, msgObjType msgType)
{

    //
    // Use Shadow variable for IF1CMD. IF1CMD should be written to in
    // single 32-bit write.
    //
    union CAN_IF1CMD_REG CAN_IF1CMD_SHADOW;
    
    //
    // Wait for busy bit to clear.
    //
    while(CanbRegs.CAN_IF1CMD.bit.Busy)
    {
    }

    //
    // Clear and Write out the registers to program the message object.
    //
    CAN_IF1CMD_SHADOW.all = 0;    
    CanbRegs.CAN_IF1MSK.all = 0;
    CanbRegs.CAN_IF1ARB.all = 0;
    CanbRegs.CAN_IF1MCTL.all = 0;

    //
    // Set the Control, Mask, and Arb bit so that they get transferred to the
    // Message object.
    //
    CAN_IF1CMD_SHADOW.bit.Control = 1;
    CAN_IF1CMD_SHADOW.bit.Arb = 1;
    CAN_IF1CMD_SHADOW.bit.Mask = 1;
    CAN_IF1CMD_SHADOW.bit.DIR = 1;

    //
    // Set direction to transmit
    //
    if(msgType == MSG_OBJ_TYPE_TRANSMIT)
    {
        CanbRegs.CAN_IF1ARB.bit.Dir = 1;
    }

    //
    // Set Message ID (this example assumes 11 bit ID mask)
    //
    CanbRegs.CAN_IF1ARB.bit.ID = (msgID << CAN_MSG_ID_SHIFT);
    CanbRegs.CAN_IF1ARB.bit.MsgVal = 1;

    //
    // Set the data length since this is set for all transfers.  This is
    // also a single transfer and not a FIFO transfer so set EOB bit.
    //
    CanbRegs.CAN_IF1MCTL.bit.DLC = messageSize;
    CanbRegs.CAN_IF1MCTL.bit.EoB = 1;

    //
    // Transfer data to message object RAM
    //
    CAN_IF1CMD_SHADOW.bit.MSG_NUM = objID;
    CanbRegs.CAN_IF1CMD.all = CAN_IF1CMD_SHADOW.all;
}

我想为 RX 消息对象添加屏蔽以供应用使用。 我似乎很难找到有关此器件的 bitfield CAN 示例的更多示例、因此我最好的猜测是如下所示:

    //
    // Set Message ID (this example assumes 11 bit ID mask)
    //
    CanbRegs.CAN_IF1ARB.bit.ID = (msgID << CAN_MSG_ID_SHIFT);
    CanbRegs.CAN_IF1ARB.bit.MsgVal = 1;
    
    /************************** My adding here /
    // Mask setting:
    CanbRegs.CAN_IF1MSK.bit.Msk = ((uint32_t)0x7FF << CAN_MSG_ID_SHIFT);
    /*************************/

    //
    // Set the data length since this is set for all transfers.  This is
    // also a single transfer and not a FIFO transfer so set EOB bit.
    //
    CanbRegs.CAN_IF1MCTL.bit.DLC = messageSize;
    CanbRegs.CAN_IF1MCTL.bit.EoB = 1;

您能否提供建议、这是否正确?

我试图通过调试和在 getCANMessage (uint32_t Objid)函数中设置断点来弄清 这个问题、以便查看我是否通过不需要的 ID 的传入帧来触发它。 但我不知道为什么、无论收到什么帧、不需要或想要、我都无法到达断点。

感谢您分享对上述2个问题的见解。

此致、

魏  

e2e.ti.com/.../2072.can_5F00_loopback_5F00_bitfields.c

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

    Wei、

               请查看 C:\ti\c2000\C2000Ware_5_02_00_00\driverlib\f2837xd\examples\cpu1\can\ CAN_EX10_MASK.c 。 我在 www.ti.com/lit/SPRACE5中进一步解释了该示例。 了解它是使用 Driverlib 编写的。 不过、它显示了如何配置该模块进行消息对象过滤。 一旦您了解了此示例、您就可以轻松地在位字段中模仿配置。

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

    尊敬的 Wei:

    您添加的代码看起来正常。 屏蔽用于插座过滤、请 也设置 IF1MSK 寄存器中的 MDIR 位:

    调用 setupMessageObject()后,您可以手动检查 CAN RAM,确保掩码值已正确传输到 CAN RAM。

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

    感谢 Hareesh 和 QJ。

    正如您建议的那样、我已经添加了 MDIR 位的设置、并且根据 TEC doc 频率5、也设置了 umask 位。 (我只为 RX 对象设置这些、因为我不关心应用中的 TX 对象过滤)。  

    CanbRegs.CAN_IF1MSK.bit.Msk = ((uint32_t)0x7FF << CAN_MSG_ID_SHIFT);
    if(msgType == MSG_OBJ_TYPE_RECEIVE)
    {
        CanbRegs.CAN_IF1MSK.bit.MDir = 1;
        CanbRegs.CAN_IF1MCTL.bit.UMask = 1;
    }

    寄存器值现在如下所示:


    我猜以上应该是什么? (标准 ID 的有效位中以全1为方式设置的屏蔽意味着只有完全匹配的 RX 帧 ID 才能通过、这就是我想要的)。

    还有一个问题需要更好的理解, MDIR 位的意思是"屏蔽消息方向",但我不清楚它的工作方式——  这是否意味着、比如说、对于一个 RX 消息目标、如果你试图从这个对象发送一个消息、它将被忽略、因为"方向"不匹配?   

    感谢您的回复。

    此致、

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

    尊敬的 Wei:

    我在 C2000Ware_5_02的 C2000 driverlib 库中读取 can.c。 函数 can_setupMessageObject (..) 配置消息掩码、因此您无需将自己的代码添加到函数中。

    MSK 只用于接收的消息。 如果接收到的消息通过了接受过滤、它就会被存储到消息 RAM 中。  消息对象中的 ID 字段被接收的消息的 ID 覆盖。

    若 MDIR=0、则报文方向位(DIR)不会影响验收过滤 这意味着接收到的报文可以写入 DIR = 1 (发送)且 DIR = 0 (接收)的报文对象。 如果 MDIR=1、接收到的报文只能写入 DIR = 0的报文 RAM 中的报文对象。

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

    感谢您的澄清、非常感谢。