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.

[参考译文] TMS320F28075:CAN 接受过滤-设置有时不成功

Guru**** 2595805 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/675460/tms320f28075-can-acceptance-filtering---setup-sometimes-not-successful

器件型号:TMS320F28075

大家好

目前、我在设置 CAN 接受过滤时遇到问题。 在某些情况下(当设置 CAN 寄存 器时、总线上同时有流量)、我仍然会收到不需要的消息。 注意:大多数情况下验收滤波工作、只有在某些情况下才工作。

我在参考手册(SPRUHM9B)第21.14节的注释中发现、通过将 MsgVal 位复位为0来设置 CAN 寄存器时、应该处理正在进行的总线通信。 我之前没有考虑过这一点、因此我添加了 MsgVal 复位。 不幸的是、行为没有改变。

MsgVal 复位之前的代码如下所示:

#define HWREGH (x)(*(volatile UINT16 *)(x))
#define HWREG (x)(*(volatile UINT32 *)(x)

) void CanDriver::setupReceiveMailbox (const MailboxDefinition& MsxDef) const
{
// Message parameters
UINT32 messageBoxIndex;//
针对消息标识符使用的消息标识符 UINT32或 U32位标识符!
uint32 ui32MsgIDMask;//!<启用标识符过滤时使用的消息标识符掩码。
//寄存器缓冲
区 uint32 ui32Cmdlet;
uint32 ui32MaskReg;
uint32 ui32ArbReg;
uint32 ui32MsgCtrl;

messageBoxIndex = mbxDef.m_iMailboxNr;//!<消息对象 ID (编号)
ui32MsgID = mbxDef.m_canIdentifier;//!<用于11或29位标识符的 CAN 消息标识符。
ui32MsgIDMask = 0x7FF &~ mbxDef.m_canMask;//!<启用标识符滤波时使用的消息标识符掩码。

ui32CmdMaskReg =(CAN_IF1CMD_DIR |//写入消息框对象
CAN_IF1CMD_DATA_A | CAN_IF1CMD_DATA_B |//设置 CAN 数据
CAN_IF1CMD_MASK |//设置 ID 掩
码 CAN_IF1CMD_ARB |//设置仲裁值 CAN_IF1CMD_CONTROL



寄存器);//设置 CM1CMD_Control 寄存器。
//将11位掩码标识符放入
寄存器中字段的高位//。
ui32MaskReg =((ui32MsgIDMask << CAN_IF1ARB_STD_ID_S)& CAN_IF1ARB_STD_ID_M);

//使用屏蔽寄存器设置 UMASK 位以启用。
ui32MsgCtrl = CAN_IF1MCTL_UMASK;

//配置仲裁寄存器。
//为此报文对象设置标识符的11位版本。
//将低18位设置为零。
//将消息框标记为有效。
ui32ArbReg =((ui32MsgID << CAN_IF1ARB_STD_ID_S)& CAN_IF1ARB_STD_ID_M)| CAN_IF1ARB_MSGVAL;

if (!mbxDef.m_bOverwriteProtection){
//如果这不是 FIFO 中的最后一个条目,则将其标记为最后一个条目。
ui32MsgCtrl |= CAN_IF1MCTL_EOB;
}

DINT;
//等待 BUSY 位清零
while (HWREGH (CAN_BASE + CAN_O_IF1CMD)& CAN_IF1CMD_BUSY)
{
}
//启用接收中断
ui32RXMsgCtrl |= CAN_IF1MCTL_IE;

/写入程序对象。
HWREARB (CAN_BASE + CAN_O_IF1CMD + 2)= ui32CmdMaskReg >> 16;

HWREGH (CAN_BASE + CAN_O_IF1MSK)= ui32MaskReg & 0xFFFF;
HWREGH (CAN_BASE + CAN_IF1MSK + 2)= ui32MaskReg + HW1UCC_CC_1 +

UCCH_CLK
+ 0x32_CC_REFH

(UCC_BIST_CLK + 0x32_CLK + UCLK + UCLK + UCC_BI_BI_BI_CLK + UCC_BIST_CLK + 0x32_CLK + UCC_CLK + UCC_BI_CLK + UCC_BI_BI_BI_CLG + 0x32_CLG + UCC_BIST_BI_BI_BI

//将消息对象传输到 ui32ObjID 指定的消息对象。
HWREGH (CAN_BASE + CAN_O_IF1CMD)= messageBoxIndex & CAN_IF1CMD_MSG_NUM_M;
EINT;
} 

在 MsgVal 复位后、看起来像:

#define HWREGH (x)(*(volatile UINT16 *)(x))
#define HWREG (x)(*(volatile UINT32 *)(x)

) void CanDriver::setupReceiveMailbox (const MailboxDefinition& MsxDef) const
{
// Message parameters
UINT32 messageBoxIndex;//
针对消息标识符使用的消息标识符 UINT32或 U32位标识符!
uint32 ui32MsgIDMask;//!<启用标识符过滤时使用的消息标识符掩码。
//寄存器缓冲
区 uint32 ui32Cmdlet;
uint32 ui32MaskReg;
uint32 ui32ArbReg;
uint32 ui32MsgCtrl;

messageBoxIndex = mbxDef.m_iMailboxNr;//!<消息对象 ID (编号)
ui32MsgID = mbxDef.m_canIdentifier;//!<用于11或29位标识符的 CAN 消息标识符。
ui32MsgIDMask = 0x7FF &~ mbxDef.m_canMask;//!<启用标识符滤波时使用的消息标识符掩码。

ui32CmdMaskReg =(CAN_IF1CMD_DIR |//写入消息框对象
CAN_IF1CMD_DATA_A | CAN_IF1CMD_DATA_B |//设置 CAN 数据
CAN_IF1CMD_MASK |//设置 ID 掩
码 CAN_IF1CMD_ARB |//设置仲裁值 CAN_IF1CMD_CONTROL



寄存器);//设置 CM1CMD_Control 寄存器。
//将11位掩码标识符放入
寄存器中字段的高位//。
ui32MaskReg =((ui32MsgIDMask << CAN_IF1ARB_STD_ID_S)& CAN_IF1ARB_STD_ID_M);

//使用屏蔽寄存器设置 UMASK 位以启用。
ui32MsgCtrl = CAN_IF1MCTL_UMASK;

//配置仲裁寄存器。
//为此报文对象设置标识符的11位版本。
//将低18位设置为零。
//将消息框标记为有效。
ui32ArbReg =((ui32MsgID << CAN_IF1ARB_STD_ID_S)& CAN_IF1ARB_STD_ID_M)| CAN_IF1ARB_MSGVAL;

if (!mbxDef.m_bOverwriteProtection){
//如果这不是 FIFO 中的最后一个条目,则将其标记为最后一个条目。
ui32MsgCtrl |= CAN_IF1MCTL_EOB;
}

DINT;
//等待 BUSY 位清零
while (HWREGH (CAN_BASE + CAN_O_IF1CMD)& CAN_IF1CMD_BUSY)
{
//

清除 MsgVal 位以避免总线流量干扰写入访问
HWREGH (CAN_O_IF1CMD)+ CAN_IF1CMD + CAN_CMD+ CAN_CMD+ CAN_CMD+ CAN_CMD+ CMD+ CMD+ CMD+ CMD+ CMD+ CMD+ CAN_CMD+ CMD+ CMD+ CMD+ CMD+ CMD+ CMD+


HWREGH (CAN_BASE + CAN_O_IF1ARB + 2)= 0;

//将报文对象传输到 ui32ObjID 指定的报文对象。
HWREGH (CAN_BASE + CAN_O_IF1CMD)=(messageBoxIndex & CAN_IF1CMD_MSG_NUM_M);
//等待 BUSY 位清零
while (HWREGH (CAN_BASE + CAN_O_IF1CMD)& CAN_IF1CMD_BUSY)
{
}

//启用
RX32_MCMI

中断|中断以将消息写入到 RX32_OUT 寄存器。
HWREARB (CAN_BASE + CAN_O_IF1CMD + 2)= ui32CmdMaskReg >> 16;

HWREGH (CAN_BASE + CAN_O_IF1MSK)= ui32MaskReg & 0xFFFF;
HWREGH (CAN_BASE + CAN_IF1MSK + 2)= ui32MaskReg + HW1UCC_CC_1 +

UCCH_CLK
+ 0x32_CC_REFH

(UCC_BIST_CLK + 0x32_CLK + UCLK + UCLK + UCC_BI_BI_BI_CLK + UCC_BIST_CLK + 0x32_CLK + UCC_CLK + UCC_BI_CLK + UCC_BI_BI_BI_CLG + 0x32_CLG + UCC_BIST_BI_BI_BI

//将消息对象传输到 ui32ObjID 指定的消息对象。
HWREGH (CAN_BASE + CAN_O_IF1CMD)= messageBoxIndex & CAN_IF1CMD_MSG_NUM_M;
EINT;
} 

正如我说过的、它没有改变行为、接受填充仍然不能一直工作。
有什么想法吗? 我错过了什么吗? 考虑调用 setupReceiveMailbox 方法时可能存在总线通信...

谢谢 Benjo

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

    Benjo、

               TRM 的最新版本为 SPRUHM9D (http://www.ti.com/lit/ug/spruhm9d/spruhm9d.pdf)。 请使用此版本、因为许多文档错误已修复。

     

    由于可以异步接收、我觉得这里可能存在竞态条件。 您自己在评论中提到了这一点:"在调用 setupReceiveMailbox 方法时、请考虑可能存在总线流量"。 我认为这可能是正在发生的情况。 也许您可以进行一个受控试验、在这个试验中、您可以控制消息传输到28075的精确时刻。 在配置接受屏蔽之前和之后发送有效和无效的 MSGID。 发送数千帧以检查是否接收到无效帧。