解码CAN总线方法的多条消息

时间:2019-06-25 11:58:34

标签: c stm32 can-bus

我有一条CAN总线消息,它由3部分组成。 解码的最佳方法是什么?

我的想法是在对第一部分进行解压缩时使用3个FIFO,将其存储在FIFO中,而对其他2个部分相同。

然后我将这3个Fifos组合成一条消息。

总消息长度为64字节PDU长度

我正在使用以下功能来获取总线数据

HAL_CAN_GetRxMessage

can bus

2 个答案:

答案 0 :(得分:0)

考虑到标准CAN消息的长度为8个字节,您可以将消息声明为uin64_t,然后使用|将相应的信号合并为消息。

示例:

uint64_t message = 0;
uint8_t incomingBytes[8] = {0};

for(int i=0; i<8; i++)
{
    message = message <<8;
    message |= incomingBytes[i];
}

如果您想将VIN数据解释为string,那么

 char vindata [9];
 memcpy(vindata, incomingBytes, 8);
 vindata[8] = '\0';

答案 1 :(得分:0)

使用来自here的上一个问题的答案,您可以将该位字段与纯uint8_t [64]结合使用。例如

typedef struct
{
  uint8_t data[64];
  can_received_t received;
} msg_t;

在接收到数据时将其填满,将其写入相应的数据字节,然后将该位置1以指示已部分接收到该消息。在您收到所有部分之前,该结构才被认为是完整的。

队列/ FIFO只能满足一个目的,那就是将某件事的执行延迟到以后,当有更多时间时才执行。这里没有理由这样做。您的CAN消息解码可能类似于:

msg_t msg;

switch(received_can_id)
{
  ...
  case CANID_FOO:  
    memcpy(&msg.data[FOO_INDEX], rec_data, FOO_SIZE);
    msg.received |= RECEIVED_FOO;
    break;

  case CANID_BAR:
    memcpy(&msg.data[BAR_INDEX], rec_data, BAR_SIZE);
    msg.received |= RECEIVED_BAR;
    break;
  ...
}

if(msg.received == RECEIVED_ALL)
{
  use(&msg); // do something
  memset(&msg, 0, sizeof msg); // reset everything
}

这是相当快速的代码,无需排队。