您好!
在技术参考手册中、我没有找到清除 CAN 接收邮箱的 MsgLst 位的正确序列的说明。
在第21.12.9节中、TRM 报告"MsgLst 不会自动复位"、但是如果寄存器将其清零、则中没有任何位。
相反、可以通过分别向 TXRQST 和 ClrIntPnd 位写入1来清除 NewDat 和 IndPnd 位。
我找到了以下基于读取-修改-写入操作的序列。
-------- 我的代码---
//局部变量
uint32_t msgCtrl = 0;
//
//--读取步骤---
//读取数据 A、数据 B、控制信息并清除 NewDat e IntPnd 位
//
HWREG_BP (CANB_BASE + CAN_O_IF2CMD)=(CAN_IF2CMD_DATA_A | CAN_IF2CMD_DATA_B |
CAN_IF2CMD_CONTROL | CAN_IF2CMD_TXRQST | CAN_IF2CMD_CLRINTPND |(Objid & CAN_IF2CMD_MSG_NUM_M);
//
//等待忙位清零
//
while ((HWREG_BP (CANB_BASE + CAN_O_IF2CMD)& CAN_IF2CMD_BUSY)!= 0)
{
;
}
//
//读出 IF 控制寄存器(保存在一个局部变量中)。
//
msgCtrl = HWREG_BP (CANB_BASE + CAN_O_IF2MCTL);
//
//--修改步骤---
//重置局部变量中的 MsgLst、NewDat 和 IntPnd 位(在读取步骤中、通过写入 IF2CMD、NewDat 和 IntPnd 已经在邮箱中被清除)。
//
msgCtrl &=~(CAN_IF2MCTL_MSGLST | CAN_IF2MCTL_NEWDAT | CAN_IF2MCTL_INTPND);
//
//--写入步骤---
//寄存器上的写入控制图像
//
HWREG_BP (CANB_BASE + CAN_O_IF2MCTL)= msgCtrl;
//
//将 CAN_IF2MCTL 传送到邮箱
//
HWREG_BP (CANB_BASE + CAN_O_IF2CMD)=(CAN_IF2CMD_DIR | CAN_IF2CMD_CONTROL |(Objid & CAN_IF2CMD_MSG_NUM_M));
//
//等待忙位清零
//
while ((HWREG_BP (CANB_BASE + CAN_O_IF2CMD)& CAN_IF2CMD_BUSY)!= 0)
{
;
}
-------- 我的代码的末尾---
该序列在写入步骤 MsgLst 位等于0的意义上有效。
但是、由于以下情况、我不确定这是清除 MsgLst 位的好方法。
假设一个新消息在读取步骤之后和写入步骤之前存储在接收邮箱中:邮箱中的 NewDat 和 IntPnd 位被设置为1。 但是、在写入步骤中、我会强制这两个值都为0。
然后、如果我再次从邮箱读取 NewDat、我将发现它等于0、因此我不知道新消息已经到达并且丢失!
在没有报文丢失或其他有害副作用的情况下清零 MsgLst 位的正确方法是什么?
谢谢你。
此致、
演示