大家好
目前、我在设置 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