你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32G474 CANFD 用例详解

[复制链接]
STMCU小助手 发布时间:2021-12-8 22:00
前景提要
CANFD基础知识可参考前篇:
Jetson Xavier/XavierNX/TX2 CANFD 配置使用
STM32 CANFD 基础知识
本篇用起来, 连接关系如下:

20210222185812381.png


CAN收发器均选用支持2M及以上CANFD的收发器, LPUART到PC用STLINK连接.

STM32工程搭建
STM32CubeMX配置步骤如下:

MCU选择: 打开 STM32CubeMX, 点击 ACCESS TO MCU SELECTOR, 选择 STM32G474VETx

调试端口配置为SWD: Pinout & Configuration -> System Core -> SYS -> Debug 选择 Serial Wire

Pinout & Configuration -> System Core -> RCC -> HSE 选择 Crystal/Ceramic Resonator

Clock Configuration(我板子上用的外部12M晶振, 主频配置成160MHz, FDCAN的时钟来自PCLK1=160MHz):
20210222185828575.png


开启100us定时器中断: Pinout & Configuration -> Timers -> TIM6 -> 勾选Activated, Prescaler设置为160-1, Counter Period设置为100-1 -> 勾选TIM6中断:

20210222185846781.png


20210222185905935.png


LPUART1配置: Pinout & Configuration -> Connectivity -> LPUART1 -> Mode选择异步Asynchronous, 关闭 Overrun 和 DMA on RX Error, 波特率配置为2M-8-N-1:

20210222185926920.png


FDCAN1配置: Pinout & Configuration -> Connectivity -> FDCAN1, Mode选择FD, Frame Format设置FD mode with BirRate Switshing启用位速率变换, Auto Retransmission设置为Enable开启自动重传, Trasmit Pause设置为Enable开启传输暂停, 速率和采样点设置参考上一篇 STM32 CANFD 基础知识的位时间和采样点小节, Nominal仲裁段设置500Kbit/s(160M/NPre/(1+NTSeg1+NTSeg2) = 160M/4/(1+63+16) = 500Kbit/s), 采样点0.8((1+NTSeg1)/(1+NTSeg1+NTSeg2)=64/80=0.8); Data数据段设置为2Mbit/s((160M/DPre/(1+DTSeg1+DTSeg2) = 160M/4/(1+63+16) = 500Kbit/s)), 采样点0.75((1+DTSeg1)/(1+DTSeg1+DTSeg2)=15/20=0.75), Std Filter Nbr标准帧过滤器数量直接设为最大28, Ext Filters Nbr扩展帧滤波器数量直接设为最大8(虽然后面并没有全用上), 勾选FDCAN1 interrupt 0中断, 引脚也从默认调整到板子上用的引脚PD0/PD1:

20210222185949803.png


20210222190005173.png


FDCAN2, FDCAN3的设置同FDCAN1, 注意引脚要从默认改为板子上用的, 最终引脚位置为:

20210222190054536.png


Project Manager -> Project -> Browse 选择工程位置(Project Location), 填入工程名(Project Name), Toolchain/IDE 选择 MDK-ARM, 把Minimum Heap Size改为0x1000, Minimum Stack Size改为0x1000. 或者更大一点.

Project Manager -> Code Generator -> 勾选Copy only the necessary library files, 还有Generate peripheral initialization as a pair of .c/.h files per periphral

点击右上角 GENERATE CODE 按钮生成代码, 点击Open Project按钮打开工程.

Keil配置, Keil 点击魔术棒或者Project -> Options for Target ..., 默认配置Debug为ST-link Debugger, 点击Setting:

Flash Download选项卡 -> 勾选Reset and Run, 这样下载后可以自动复位运行.
Pack选项卡, 去掉默认的Enable勾选
到此配置结束. 下面是手动添加的代码详解

串口配置
为 LPUART1 添加printf支持:

  1. #include <stdio.h>

  2. #ifdef __GNUC__
  3. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
  4. #else
  5. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
  6. #endif /* __GNUC__ */

  7. PUTCHAR_PROTOTYPE
  8. {
  9.   HAL_UART_Transmit(&hlpuart1, (uint8_t *)&ch, 1, 0xFFFF);
  10.   return ch;
  11. }
复制代码

100us定时器
因为用最大64字节测试的, 实测只发送的情况下, 1s传输最多2490+约2500帧, 再多就丢帧了, 也就是400us/帧, 保守一点, 这里设置500us传一帧, 如果没传出去, 100us后有一次重传的机会, 这就是100us定时器的由来.

  1. /* USER CODE BEGIN 2 */
  2. HAL_TIM_Base_Start_IT(&htim6);  //Starts the TIM Base generation in interrupt mode.
  3. /* USER CODE END 2 */

  4. uint8_t tim6_flag = 0;
  5. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  6. {
  7.     if(htim->Instance == TIM6) {
  8.         tim6_flag = 1;
  9.     }
  10. }
复制代码

FDCAN配置
主要是标准帧滤波器, 扩展帧滤波器设置, 开启新消息接收中断, 开启Bus-Off中断, 设置发送传输延时补偿等.

  1. FDCAN_FilterTypeDef sFilterConfig1;

  2. void fdcan1_config(void)
  3. {
  4.   sFilterConfig1.IdType = FDCAN_STANDARD_ID;
  5.   sFilterConfig1.FilterIndex = 0;
  6.   sFilterConfig1.FilterType = FDCAN_FILTER_RANGE;
  7.   sFilterConfig1.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
  8.   sFilterConfig1.FilterID1 = 0x00;
  9.   sFilterConfig1.FilterID2 = 0x7FF;
  10.   if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig1) != HAL_OK)
  11.   {
  12.     Error_Handler();
  13.   }

  14.   sFilterConfig1.IdType = FDCAN_EXTENDED_ID;
  15.   sFilterConfig1.FilterIndex = 0;
  16.   sFilterConfig1.FilterType = FDCAN_FILTER_RANGE;
  17.   sFilterConfig1.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
  18.   sFilterConfig1.FilterID1 = 0x00;
  19.   sFilterConfig1.FilterID2 = 0x1FFFFFFF;
  20.   if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig1) != HAL_OK)
  21.   {
  22.     Error_Handler();
  23.   }

  24.   /* Configure global filter on both FDCAN instances:
  25.   Filter all remote frames with STD and EXT ID
  26.   Reject non matching frames with STD ID and EXT ID */
  27.   if (HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE) != HAL_OK)
  28.   {
  29.     Error_Handler();
  30.   }

  31.   /* Activate Rx FIFO 0 new message notification on both FDCAN instances */
  32.   if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
  33.   {
  34.     Error_Handler();
  35.   }

  36.   if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_BUS_OFF, 0) != HAL_OK)
  37.   {
  38.     Error_Handler();
  39.   }

  40.   /* Configure and enable Tx Delay Compensation, required for BRS mode.
  41.         TdcOffset default recommended value: DataTimeSeg1 * DataPrescaler
  42.         TdcFilter default recommended value: 0 */
  43.   HAL_FDCAN_ConfigTxDelayCompensation(&hfdcan1, hfdcan1.Init.DataPrescaler * hfdcan1.Init.DataTimeSeg1, 0);
  44.   HAL_FDCAN_EnableTxDelayCompensation(&hfdcan1);

  45.   HAL_FDCAN_Start(&hfdcan1);
  46. }
复制代码

这里设置了用一个标准帧滤波器设置了标准帧的全接收, 也可以用掩码的方式设置全接收:
  1.   sFilterConfig1.FilterType = FDCAN_FILTER_MASK;
  2.   sFilterConfig1.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
  3.   sFilterConfig1.FilterID1 = 0;
  4.   sFilterConfig1.FilterID2 = 0;
复制代码
用一个扩展帧滤波器设置了扩展帧的全接收, 消息扔到RXFIFO0中, 设置了RXFIFO0的新消息来的中断, 也可以扔到RXFIFO1中.

有别于STM32H7, STM32G474在STM32CubeMX软件中能设置的最大标准帧滤波器是28个, 扩展帧滤波器是8个, 这里程序中只各用了一个(index = 0), 如果想用更多, 不知可否手动更改stm32g4xx_hal_fdcan.c中213行这个值, 如把扩展帧滤波器数量从8改为28, 有兴趣试试:
  1. #define SRAMCAN_FLE_NBR                  ( 8U)         /* Max. Filter List Extended Number      */
复制代码

FDCAN2, FDCAN3的配置和FDCAN1类似.

Bus-Off处理
如果CANH, CANL短接, 或者和其它节点的传输速率/采样点不一致, 会引发Bus-Off, 上面开启了Bus-Off中断, 发生Bus-Off时, 直接在中断中初始化FDCAN外设:

  1. void HAL_FDCAN_ErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t ErrorStatusITs)
  2. {
  3.   //__HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_BUS_OFF);
  4.   if(hfdcan->Instance == FDCAN1) {
  5.     MX_FDCAN1_Init();
  6.     fdcan1_config();
  7.   } else if(hfdcan->Instance == FDCAN2) {
  8.     MX_FDCAN2_Init();
  9.     fdcan2_config();
  10.   } else if(hfdcan->Instance == FDCAN3) {
  11.     MX_FDCAN3_Init();
  12.     fdcan3_config();
  13.   } else {
  14.   }
  15. }
复制代码

新消息接收处理

直接把接收的消息通过2M波特率的串口打印出来.
  1. FDCAN_RxHeaderTypeDef RxHeader1;
  2. FDCAN_RxHeaderTypeDef RxHeader2;
  3. FDCAN_RxHeaderTypeDef RxHeader3;

  4. //RxHeader1.DataLength => can_dlc
  5. //0x00000 => 0
  6. //0x10000 => 1
  7. //0x20000 => 2
  8. //0x30000 => 3
  9. //0x40000 => 4
  10. //0x50000 => 5
  11. //0x60000 => 6
  12. //0x70000 => 7
  13. //0x80000 => 8
  14. //0x90000 => 12
  15. //0xA0000 => 16
  16. //0xB0000 => 20
  17. //0xC0000 => 24
  18. //0xD0000 => 32
  19. //0xE0000 => 48
  20. //0xF0000 => 64
  21. uint8_t dlc2len[]={0,1,2,3,4,5,6,7,8,12,16,20,24,32,48,64};
  22. uint8_t can_dlc2len(uint32_t RxHeader_DataLength)
  23. {
  24.   return dlc2len[RxHeader_DataLength>>16];
  25. }

  26. uint8_t cnt = 0;
  27. uint8_t brs[] = {'-', 'B'};
  28. uint8_t esi[] = {'-', 'E'};
  29. void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
  30. {
  31.   if((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != 0) {
  32.     //HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader2, RxData2);
  33.     //RxHeader2.Identifier++;
  34.     //fdcan2_transmit(RxHeader2.Identifier, RxData2);

  35.     //HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader1, RxData1);
  36.     //memset(&RxHeader1, 0, sizeof(FDCAN_RxHeaderTypeDef));

  37.     HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader1, RxData1);
  38.     if (hfdcan->Instance == FDCAN1) {
  39.                 printf("fdcan1, ");
  40.         } else if (hfdcan->Instance == FDCAN2) {
  41.                 printf("fdcan2, ");
  42.         } else if (hfdcan->Instance == FDCAN3) {
  43.                 printf("fdcan3, ");
  44.         }
  45.     printf("0x%8X, %02d, %c, %c:",RxHeader1.Identifier,
  46.                                   can_dlc2len(RxHeader1.DataLength),
  47.                                   brs[RxHeader1.BitRateSwitch>>20 & 0x1],
  48.                                   esi[RxHeader1.ErrorStateIndicator>>31 & 0x1]);
  49.     for(cnt = 0; cnt < can_dlc2len(RxHeader1.DataLength); cnt++) {
  50.       printf(" %02X", RxData1[cnt]);
  51.     }
  52.     printf("\n\r");


  53.     //if (hfdcan->Instance == FDCAN1) {
  54.     //  HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader1, RxData1);
  55.     //  //echo
  56.     //  RxHeader1.Identifier++;
  57.     //  fdcan1_transmit(RxHeader1.Identifier, RxHeader1.DataLength, RxData1);
  58.     //} else if(hfdcan->Instance == FDCAN2) {
  59.     //  HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader2, RxData2);
  60.     //  //echo
  61.     //  RxHeader2.Identifier++;
  62.     //  fdcan2_transmit(RxHeader2.Identifier, RxHeader2.DataLength, RxData2);
  63.     //} else if(hfdcan->Instance == FDCAN3) {
  64.     //  HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader3, RxData3);
  65.     //  //echo
  66.     //  RxHeader3.Identifier++;
  67.     //  fdcan3_transmit(RxHeader3.Identifier, RxHeader3.DataLength, RxData3);
  68.     //} else {
  69.     //  
  70.     //}
  71.   }
  72. }
复制代码

注意注释中 RxHeader.DataLength => can_dlc 的对应关系.

示例如图:

20210222190024669.png


图中消息来自fdcan2, can_id为0x18FF0005, 64字节数据, 开启了BRS和ESI, :后面是64字节的十六进制数据.

printf还是比较耗时间的, 这里仅做低负载下的演示, 实际使用不建议中断中这么搞.

发送处理
发送开启了BRS和ESI, 如果发送失败, 就延时100us后重发一次.

  1. #include <string.h>

  2. FDCAN_TxHeaderTypeDef TxHeader1;
  3. FDCAN_TxHeaderTypeDef TxHeader2;
  4. FDCAN_TxHeaderTypeDef TxHeader3;

  5. typedef struct {
  6.   uint8_t flag;
  7.   FDCAN_TxHeaderTypeDef TxHeader;
  8.   uint8_t TxData[64];
  9. } FDCAN_SendFailTypeDef;

  10. FDCAN_SendFailTypeDef fdcan1_send_fail = {0};
  11. FDCAN_SendFailTypeDef fdcan2_send_fail = {0};
  12. FDCAN_SendFailTypeDef fdcan3_send_fail = {0};

  13. void fdcan1_transmit(uint32_t can_id, uint32_t DataLength, uint8_t tx_data[])
  14. {
  15.   TxHeader1.Identifier = can_id;
  16.   TxHeader1.IdType = FDCAN_EXTENDED_ID;
  17.   if(can_id < 0x800) {  //exactly not right
  18.     TxHeader1.IdType = FDCAN_STANDARD_ID;
  19.   }
  20.   TxHeader1.TxFrameType = FDCAN_DATA_FRAME;
  21.   TxHeader1.DataLength = DataLength;
  22.   TxHeader1.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
  23.   TxHeader1.BitRateSwitch = FDCAN_BRS_ON;
  24.   TxHeader1.FDFormat = FDCAN_FD_CAN;
  25.   TxHeader1.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
  26.   TxHeader1.MessageMarker = 0;        //marker++;        //Tx Event FIFO Use
  27.   if(HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader1, tx_data) != HAL_OK) {
  28.     fdcan1_send_fail.flag = 1;
  29.     memcpy(&fdcan1_send_fail.TxHeader, &TxHeader1, sizeof(FDCAN_TxHeaderTypeDef));
  30.     memcpy(fdcan1_send_fail.TxData, tx_data, can_dlc2len(DataLength));
  31.   }
  32. }

  33. int main(void)
  34. {
  35.   ...
  36.   /* USER CODE BEGIN 2 */
  37.   fdcan1_config();
  38.   fdcan2_config();
  39.   fdcan3_config();

  40.   for(uint8_t i = 0; i < 64; i++) {
  41.     TxData1<i> = i;
  42.     </i>TxData2 = i;
  43.     TxData3 = i;
  44.   }

  45.   HAL_TIM_Base_Start_IT(&htim6);
  46.   uint32_t count = 0;
  47.   uint32_t cnt_100us = 0;
  48.   uint32_t cnt_500us = 0;
  49.   /* USER CODE END 2 */

  50.   /* Infinite loop */
  51.   /* USER CODE BEGIN WHILE */
  52.   while (1)
  53.   {
  54.     /* USER CODE END WHILE */

  55.     /* USER CODE BEGIN 3 */
  56.     if(tim6_flag && count < 1000) {
  57.       tim6_flag = 0;
  58.       TxData1[0] = count >> 8 & 0xFF;
  59.       TxData1[1] = count & 0xFF;

  60.       ++cnt_100us;
  61.       cnt_500us = cnt_100us / 5;
  62.       if(cnt_500us && (cnt_100us%5==0) ) {
  63.         switch(cnt_500us) {
  64.           case 1: fdcan1_transmit(0x123, FDCAN_DLC_BYTES_64, TxData1);
  65.                   fdcan1_transmit(0x124, FDCAN_DLC_BYTES_64, TxData1);
  66.                   fdcan1_transmit(0x125, FDCAN_DLC_BYTES_64, TxData1); break;
  67.           case 4: fdcan1_transmit(0x12345678, FDCAN_DLC_BYTES_64, TxData1); break;
  68.           case 5: fdcan1_transmit(0x12345679, FDCAN_DLC_BYTES_64, TxData1); break;
  69.           case 6: fdcan1_transmit(0x1234567A, FDCAN_DLC_BYTES_64, TxData1); break;
  70.           case 7: /* next send */ break;
  71.           case 8: break;
  72.           case 20: ++count; cnt_100us = 0; break; //10ms
  73.         }
  74.       } else {  //fail retransmission once
  75.         if(fdcan1_send_fail.flag) {
  76.           fdcan1_transmit(fdcan1_send_fail.TxHeader.Identifier,
  77.                           fdcan1_send_fail.TxHeader.DataLength,
  78.                           fdcan1_send_fail.TxData);
  79.           fdcan1_send_fail.flag = 0;
  80.         }
  81.         if(fdcan2_send_fail.flag) {
  82.           fdcan2_transmit(fdcan2_send_fail.TxHeader.Identifier,
  83.                           fdcan2_send_fail.TxHeader.DataLength,
  84.                           fdcan2_send_fail.TxData);
  85.           fdcan2_send_fail.flag = 0;
  86.         }
  87.         if(fdcan3_send_fail.flag) {
  88.           fdcan3_transmit(fdcan3_send_fail.TxHeader.Identifier,
  89.                           fdcan3_send_fail.TxHeader.DataLength,
  90.                           fdcan3_send_fail.TxData);
  91.           fdcan3_send_fail.flag = 0;
  92.         }
  93.       }
  94.     }
  95.   }
  96.   /* USER CODE END 3 */  
  97. }
复制代码

fdcan2, fdcan3和fdcan1的发送类似, 3个发送函数可以合并成一个, 这里没有合并.

发送函数中的DataLength指的是类似FDCAN_DLC_BYTES_64这种的宏定义, 而不是数字64.

这里用can_id < 0x800只是为了简便, 其实不正确, 这种情况下也有可能是扩展帧, 但通常不会这么用.

因为发送最多可以缓存3帧, 所以可以一口气发送3帧, 如case 1处, 也可以一帧一帧发送, 如case 4, case 5, case 6. 这里是1.5ms/3帧或者500us/帧.

因为总线中还有其他节点发送之类的, 有可能发送失败, 这里留了一次发送失败后延时100us重传的机会, 具体情况根据现场可另行调整.

如果fdcan1, fdcan2, fdcan3没有在一个网络中, 可以一口气 fdcan1发送3帧 + fdcan2发送3帧 + fdcan3发送3帧.

一般车辆总线中发送都是最快10ms内把要发的不同ID的数据一股脑发出去(当然也有20ms, 50ms, 100ms周期的数据这里暂不考虑), 所以这里100us中断计数100次就是10ms.

程序中发送1000*6=6000帧后停止发送, 10ms发6帧, 所以10s后数据就发完了.

使用Xavier配合测试一下
把STM32的FDCAN1连到Xavier的CAN1上, Xavier CAN1设置:

  1. #!/bin/sh

  2. sudo modprobe can
  3. sudo modprobe can_raw
  4. sudo modprobe mttcan

  5. sudo ip link set down can0
  6. sudo ip link set can0 type can bitrate 500000 sample-point 0.8 dbitrate 2000000 dsample-point 0.75 fd on restart-ms 100
  7. sudo ip link set up can0
  8. sudo ifconfig can0 txqueuelen 1000

  9. sudo ip link set down can1
  10. sudo ip link set can1 type can bitrate 500000 sample-point 0.8 dbitrate 2000000 dsample-point 0.75 fd on restart-ms 100
  11. sudo ip link set up can1
  12. sudo ifconfig can1 txqueuelen 1000
复制代码

Xavier也是仲裁段500Kbit/s, 采样点0.8, 数据段2Mbit/s, 采样点0.75.

restart-ms 100设置总线Bus-Off时, 100ms后重启.

设置完后查看设置状态 ip -details -statistics link show can1:

  1. $ ip -details -statistics link show can1
  2. 6: can1: <NOARP,UP,LOWER_UP,ECHO> mtu 72 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 1000
  3.     link/can  promiscuity 0
  4.     can <FD> state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 100
  5.           bitrate 498701 sample-point 0.792
  6.           tq 26 prop-seg 30 phase-seg1 30 phase-seg2 16 sjw 1
  7.           mttcan: tseg1 2..255 tseg2 0..127 sjw 1..127 brp 1..511 brp-inc 1
  8.           dbitrate 2021052 dsample-point 0.736
  9.           dtq 26 dprop-seg 6 dphase-seg1 7 dphase-seg2 5 dsjw 1
  10.           mttcan: dtseg1 1..31 dtseg2 0..15 dsjw 1..15 dbrp 1..15 dbrp-inc 1
  11.           clock 38400000
  12.           re-started bus-errors arbit-lost error-warn error-pass bus-off
  13.           0          0          0          13         20         0         numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
  14.     RX: bytes  packets  errors  dropped overrun mcast   
  15.     64578440   1013451  0       0       0       0      
  16.     TX: bytes  packets  errors  dropped carrier collsns
  17.     952448     15914    0       0       0       0   
复制代码

位速率和采样点的些许误差测试并无影响.

使用 candump -ta -x can1 >24.dat, 这里-ta显示绝对时间, 然后下载STM32程序运行, 上面的6000帧数据全部存到24.dat文件中了, 共计6000行, 这里截取首尾部分显示:

  1. (1613988959.105805)  can1  RX B -  123  [64]  00 00 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
  2. (1613988959.106191)  can1  RX B -  124  [64]  00 00 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
  3. (1613988959.106609)  can1  RX B -  125  [64]  00 00 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
  4. (1613988959.107337)  can1  RX B -  12345678  [64]  00 00 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
  5. (1613988959.107865)  can1  RX B -  12345679  [64]  00 00 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
  6. (1613988959.108332)  can1  RX B -  1234567A  [64]  00 00 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
  7. (1613988959.115791)  can1  RX B -       123  [64]  00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
  8. (1613988959.116215)  can1  RX B -       124  [64]  00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F

  9. ...

  10. (1613988969.087131)  can1  RX B E  12345678  [64]  03 E6 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
  11. (1613988969.087612)  can1  RX B E  12345679  [64]  03 E6 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
  12. (1613988969.088160)  can1  RX B E  1234567A  [64]  03 E6 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
  13. (1613988969.095802)  can1  RX B E       123  [64]  03 E7 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
  14. (1613988969.095935)  can1  RX B E       124  [64]  03 E7 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
  15. (1613988969.096294)  can1  RX B E       125  [64]  03 E7 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
  16. (1613988969.097116)  can1  RX B E  12345678  [64]  03 E7 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
  17. (1613988969.097604)  can1  RX B E  12345679  [64]  03 E7 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
  18. (1613988969.098102)  can1  RX B E  1234567A  [64]  03 E7 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
复制代码

这里前三行的格式问题, ESI的404行之前是-, 404行及以后是E, 暂时不解. 其它正常, ID顺序和数据都对得上.

Xavier发送脚本, ##后面的3表示开启BRS和ESI:

  1. #!/bin/sh

  2. while true; do
  3.     cansend can1 18FF0001##3.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16
  4.     cansend can1 18FF0002##3.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16
  5.     cansend can1 18FF0003##3.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16  
  6.     cansend can1 18FF0004##3.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16
  7.     cansend can1 18FF0005##3.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16
  8.     cansend can1 18FF0006##3.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16  
  9.     sleep 0.01
  10. done
复制代码

可以在LPUART1串口中看到收到的数据, 如上面 新消息接收处理 小节配图.



收藏 评论0 发布时间:2021-12-8 22:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版