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.

[参考译文] TM4C123GH6PM:无法创建 CAN FIFO

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/611432/tm4c123gh6pm-unable-to-create-can-fifo

器件型号:TM4C123GH6PM

在我的应用中、我面临数据丢失。 因此我尝试使用7个报文对象创建 FIFO。
但数据仅在最低的对象中接收。 下面是我的代码

空 CAN_Config (空)

//为 CAN TX 和 RX 启用端口 E
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE);//启用 Porte
GPIOPinConfigure (GPIO_PE4_CAN0RX);//为 CAN 接收功能配置 PE4
GPIOPinConfigure (GPIO_PE5_CAN0TX);//为 CAN 发送功能配置 PE5
GPIOPinTypeCAN (GPIO_Porte _BASE、GPIO_PIN_4 | GPIO_PIN_5);//启用 CAN 的引脚类型
SysCtlPeripheralEnable (SYSCTL_Periph_CAN0);

//初始化 CAN0
CANInit (CAN0_BASE);
IntEnable (INT_CAN0);

//启用 CAN 外设上的中断
CANIntEnable (CAN0_BASE、CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
CANEnable (CAN0_BASE);


(小部分

void CAN_info (uint32_t 波特率、uint8_t samplingPoint)

//为 CAN 发送和接收分配 CAN 位时序结构值
// ToDo:当前的 bit_time_q 在所有 baudRates 中都是常数;需要对其进行验证。
如果(波特率= 1000)

GetBittime.ui32SyncPropPhase1Seg=15;
GetBittime.ui32Phase2Seg=4;
GetBittime.ui32SJW=3;
GetBittime.ui32QuantumPrescaler=4;

其他

// ToDo:不支持波特率;将其作为错误处理。


//设置为该 CAN 分配值
CANBitTimingSet (CAN0_BASE、GetBitTime);

//为接收数据分配 CAN 消息对象结构成员
sMsgObjectRx.ui32MsgIDMask = 0xFFFF;

//前5个消息对象设置了 MSG_OBJ_FIFO 来指示
//它们是 FIFO 的一部分。
sMsgObjectRx.ui32Flags =(MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER | MSG_OBJ_EXDED_ID | MSG_OBJ_FIFO);
sMsgObjectRx.pui8MsgData = pui8MsgData;
sMsgObjectRx.ui32MsgLen = 8;


//前三个消息对象设置了 MSG_OBJ_FIFO 来指示
//它们是 FIFO 的一部分。
CANMessageSet (CAN0_BASE、2、&sMsgObjectRx、MSG_OBJ_TYPE_RX);
CANMessageSet (CAN0_BASE、3、&sMsgObjectRx、MSG_OBJ_TYPE_RX);
CANMessageSet (CAN0_BASE、4、&sMsgObjectRx、MSG_OBJ_TYPE_RX);
CANMessageSet (CAN0_BASE、5、&sMsgObjectRx、MSG_OBJ_TYPE_RX);
CANMessageSet (CAN0_BASE、6、&sMsgObjectRx、MSG_OBJ_TYPE_RX);

//最后一个消息对象没有设置 MSG_OBJ_FIFO 来指示这一点
//这是最后一条消息。
sMsgObjectRx.ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER;
CANMessageSet (CAN0_BASE、7、&sMsgObjectRx、MSG_OBJ_TYPE_RX);

空 CANIntHandler (空)

uint32_t ui32Status;

//读取 CAN 中断状态以查找中断原因
ui32Status = CANIntStatus (CAN0_BASE、CAN_INT_STS_CAUST);

//如果原因是控制器状态中断,则获取状态
if (ui32Status = CAN_INT_INTID_STATUS)


//读取控制器状态
ui32Status = CANStatusGet (CAN0_BASE、CAN_STS_CONTROL);
//设置错误标志
G_bErrFlag = 1;

//检查原因是否是我们正在使用的消息对象1
//发送消息。

否则、如果(ui32Status = 1)

//---- 发送中断--- //
//如果此条件为真,则发生 TX 中断
//消息对象1、消息 TX 完成。 清除
//消息目标中断。

CANIntClear (CAN0_BASE、1);

G_ui32MsgCount_Tx++;

//清除错误标志
G_bErrFlag = 0;



//------ 接收中断--- //
//如果此条件为真,则发生 RX 中断
//报文对象2、报文 RX 完成。

否则 if (ui32Status = 2)

G_ui32MsgCount_Rx++;
CANMessageGet (CAN0_BASE、2、&sMsgObjectRx、1);
//清除错误标志
G_bErrFlag = 0;

否则 if (ui32Status = 3)

G_ui32MsgCount3_Rx++;
CANMessageGet (CAN0_BASE、3、&sMsgObjectRx、1);
//清除错误标志
G_bErrFlag = 0;

否则 if (ui32Status = 4)

G_ui32MsgCount4_Rx++;
CANMessageGet (CAN0_BASE、4、&sMsgObjectRx、1);
//清除错误标志
G_bErrFlag = 0;

否则 if (ui32Status = 5)

G_ui32MsgCount5_Rx++;
CANMessageGet (CAN0_BASE、5、&sMsgObjectRx、1);
//清除错误标志
G_bErrFlag = 0;

否则 if (ui32Status = 6)

G_ui32MsgCount6_Rx++;
CANMessageGet (CAN0_BASE、6、&sMsgObjectRx、1);
//清除错误标志
G_bErrFlag = 0;

否则 if (ui32Status = 7)

G_ui32MsgCount7_Rx++;
CANMessageGet (CAN0_BASE、7、&sMsgObjectRx、1);
//清除错误标志
G_bErrFlag = 0;

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Jibin、您好!
    首先、我只看到有六个 msg 对象设置为 FIFO、而不是主题标题中所示的7个。 其次、我想知道为什么要为前5个 msg 对象启用中断。 我建议您为 FIFO 中的最后一个 msg 对象启用中断。 因此、当 FIFO 接收到最后一个消息进入消息对象#7时、它将生成中断。 然后、在 ISR 中、您将从从2到7的 msg 对象中读取。 第三、我想知道为什么您没有使用 msg 对象1启动 FIFO。 从 msg 对象2开始。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    使用 CAN FIFO 模式时需要注意一个字。 如果您在不断接收和读取 FIFO 中的数据、并且数据的顺序很重要、那么这可能不起作用。 在 FIFO 模式下、如果您在接收进入 FIFO 的帧时读取 FIFO 中的邮箱、则不能保证数据帧的顺序。 当您接收到一个帧的突发时、FIFO 就会工作、其中所有帧都适合于 FIFO、并且在下一次突发发生之前都可以读取、或者帧的接收顺序并不重要。 如果您的应用不是这种情况、那么您最好尽量减少中断例程中花费的时间、这样您就可以始终在下一帧进入之前响应和读取数据。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    为了便于说明、即使在实现 FIFO 后、您仍然缺少帧? 我在您的代码中没有看到您设置消息 ID 的位置、但是、由于您使用结构初始化每个邮箱、所有6个邮箱(2-7)将是相同的。 您希望接收的所有具有相同 ID 的 CAN 帧吗? 您可以设置 MSG_OBJ_USE_ID_FILTER 标志、但随后将掩码设置为全部为1、这意味着 ID 的任何位都不会被屏蔽。

    我注意到、对于邮箱7、您没有设置 MSG_OBJ_EXDED_ID 标志。 我不认为这是邮箱3中没有收到消息的原因、但 FIFO 中的所有邮箱都应该具有相同长度的 ID。