硬汉嵌入式论坛

 找回密码
 立即注册
查看: 490|回复: 6
收起左侧

[CAN/FDCAN] STM32H723系列芯片同时使用CAN1和CAN3问题跟踪

[复制链接]

8

主题

57

回帖

81

积分

初级会员

积分
81
发表于 2025-6-4 22:09:12 | 显示全部楼层 |阅读模式
本帖最后由 Ainit 于 2025-6-4 22:11 编辑

STM32H723系列芯片同时使用CAN1和CAN3进行数据发送会出现异常,具体出现在当两组CAN均初始化打开时,通过CAN收发器只能接收到CAN3发送的数据,并且检查CAN1是正常初始化成功的。只是调用发送时无法正常发送。两路CAN都是设置成500K波特率,检查发现CAN发送时调用
[C] 纯文本查看 复制代码
HAL_StatusTypeDef HAL_FDCAN_AddMessageToTxFifoQ(FDCAN_HandleTypeDef *hfdcan, const FDCAN_TxHeaderTypeDef *pTxHeader,
                                                const uint8_t *pTxData)
函数会一直进入
[C] 纯文本查看 复制代码
   /* Check that the Tx FIFO/Queue is not full */
    if ((hfdcan->Instance->TXFQS & FDCAN_TXFQS_TFQF) != 0U)
    {
      /* Update error code */
      hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_FULL;

      return HAL_ERROR;
    }
具体情况还不清楚。继续排查。

网上看到一篇文章多路CAN公用相同的内存,里面说
Message Ram Offset (RAM消息地址偏移):范围0-2560,使用几个FDCAN就将2560平均分给几个,比如使用一个FDCAN1就填0,范围就是将RAM地消息0-2560分给FDCAN1。使用FDCAN1和FDCAN2,FDCAN1就填0,FDCAN2就填1280,FDCAN1范围就是0-1280,FDCAN2范围则是1281-2560。三个就以此类推。
不清楚是否是问题点。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2025-6-5 08:07:36 | 显示全部楼层
1、RAM分配是共享的2560字,合理分配就行

https://forum.anfulai.cn/forum.php?mod=viewthread&tid=104728



2、然后就是看下你的错误状态寄存器,这个比较重要。
回复

使用道具 举报

6

主题

306

回帖

324

积分

高级会员

积分
324
发表于 2025-6-5 08:07:50 | 显示全部楼层
我只使用过CAN1,没问题,你看下勘误手册中有没有关于这方面的说明?
回复

使用道具 举报

19

主题

337

回帖

394

积分

高级会员

积分
394
发表于 2025-6-5 09:52:43 | 显示全部楼层
消息 RAM 可以看我的这篇博客。我在 H7 上同时使用 CAN1 CAN2 是正常工作的

https://blog.csdn.net/whj123999/article/details/122028836
回复

使用道具 举报

8

主题

57

回帖

81

积分

初级会员

积分
81
 楼主| 发表于 2025-6-7 14:58:27 | 显示全部楼层
王海靖 发表于 2025-6-5 09:52
消息 RAM 可以看我的这篇博客。我在 H7 上同时使用 CAN1 CAN2 是正常工作的

https://blog.csdn.net/whj1 ...

好的,已经参考你的文章重新配置了一下各个CAN的内存
回复

使用道具 举报

8

主题

57

回帖

81

积分

初级会员

积分
81
 楼主| 发表于 2025-6-7 15:08:23 | 显示全部楼层
eric2013 发表于 2025-6-5 08:07
1、RAM分配是共享的2560字,合理分配就行

https://forum.anfulai.cn/forum.php?mod=viewthread&tid=104728
...

好的,已经将两路CAN的初始化重新验证了一下。再继续看看问题定位在哪里。
回复

使用道具 举报

8

主题

57

回帖

81

积分

初级会员

积分
81
 楼主| 发表于 2025-6-13 17:29:55 | 显示全部楼层
双路CAN已经调试正常了。有需要朋友可以参考一下,设置两路CAN波特率均为500K
[C] 纯文本查看 复制代码
/*
*********************************************************************************************************
*	函 数 名: bsp_InitCan1
*	功能说明: 初始CAN1
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************
*/
void bsp_InitCan1(void) {
  /*                Bit time configuration:
  Bit time parameter         | Nominal      |  Data
  ---------------------------|--------------|----------------
  fdcan_ker_ck               | 20 MHz       | 20 MHz
  Time_quantum (tq)          | 50 ns        | 50 ns
  Synchronization_segment    | 1 tq         | 1 tq
  Propagation_segment        | 23 tq        | 1 tq
  Phase_segment_1            | 8 tq         | 4 tq
  Phase_segment_2            | 8 tq         | 4 tq
  Synchronization_Jump_width | 8 tq         | 4 tq
  Bit_length                 | 40 tq = 2 祍 | 10 tq = 0.5 祍
  Bit_rate                   | 0.5 MBit/s   | 2 MBit/s
 */

  //  HAL_FDCAN_DeInit(&hfdcan1); /* 先清除以前的设置 */
  hfdcan1.Instance = FDCAN1;
  hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_BRS; /* 传统模式 */
  hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;         /* 模式设置  */
  hfdcan1.Init.AutoRetransmission = ENABLE;
  hfdcan1.Init.TransmitPause = DISABLE;    /* 关闭传输暂停 */
  hfdcan1.Init.ProtocolException = ENABLE; /* 关闭协议异常处理 */
  hfdcan1.Init.NominalPrescaler = 1;       /* 分频系数 */
  hfdcan1.Init.NominalSyncJumpWidth = 8;   /* 重新同步跳跃宽度 */
  hfdcan1.Init.NominalTimeSeg1 = 31;       /* tsg1范围:2~256 */
  hfdcan1.Init.NominalTimeSeg2 = 8;        /* tsg2范围:2~128 */

  hfdcan1.Init.DataPrescaler =
      0x01; /* CAN时钟分配设置,一般设置为1即可,全部由PLL配置好,tq =
               NominalPrescaler x (1/ fdcan_ker_ck),范围1-32 */
  hfdcan1.Init.DataSyncJumpWidth =
      0x04; /* 用于动态调节  Phase_Seg1和 Phase_Seg1,所以不可以比Phase_Seg1和
               Phase_Seg1大,范围1-16 */
  hfdcan1.Init.DataTimeSeg1 =
      0x05; /* 特别注意这里的Seg1,这里是两个参数之和,对应位时间特性图的
                                                                       Pro_Seg +
               Phase_Seg1,范围 */
  hfdcan1.Init.DataTimeSeg2 = 0x04; /* 对应位时间特性图的 Phase_Seg2 */

  hfdcan1.Init.MessageRAMOffset = 0; /* 信息RAM偏移 */

  hfdcan1.Init.StdFiltersNbr = 1;   /* 标准信息ID滤波器编号 */
  hfdcan1.Init.ExtFiltersNbr = 0;   /* 扩展信息ID滤波器编号 */
  hfdcan1.Init.RxFifo0ElmtsNbr = 4; /* 接收FIFO0元素编号 */
  hfdcan1.Init.RxFifo0ElmtSize =
      FDCAN_DATA_BYTES_8;           /* 接收FIFO0元素大小:8字节 */
  hfdcan1.Init.RxFifo1ElmtsNbr = 4; /* 设置Rx FIFO1的元素个数,范围0-64 */
  hfdcan1.Init.RxFifo1ElmtSize =
      FDCAN_DATA_BYTES_24;       /* 设置Rx
                                   FIFO1中每个元素大小,支持8,12,16,20,24,32,48或者64字节
                                 */
  hfdcan1.Init.RxBuffersNbr = 0; /* 接收FIFO0元素编号 */
  hfdcan1.Init.TxEventsNbr = 0;  /* 发送事件编号 */
  hfdcan1.Init.TxBuffersNbr = 0; /* 发送缓冲编号 */
  hfdcan1.Init.RxBufferSize =
      0; /* 设置Rx Buffer中每个元素大小,支持8,12,16,20,24,32,48或者64字节 */
  hfdcan1.Init.TxFifoQueueElmtsNbr = 2; /* 发送FIFO序列元素编号 */
  hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; /* 发送FIFO序列模式 */
  hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_8; /* 发送大小:8字节 */

  if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK) {
    /* 初始化 */
  }

  sFilterConfig1.IdType = FDCAN_STANDARD_ID;     /* 标准ID */
  sFilterConfig1.FilterIndex = 0;                /* 滤波器索引 */
  sFilterConfig1.FilterType = FDCAN_FILTER_MASK; /* 滤波器类型 */
  sFilterConfig1.FilterConfig =
      FDCAN_FILTER_TO_RXFIFO0;       /* 过滤器0关联到FIFO0 */
  sFilterConfig1.FilterID1 = 0x0000; /* 32位ID */
  sFilterConfig1.FilterID2 =
      0x0000; /* 如果FDCAN配置为传统模式的话,这里是32位掩码 */
  /* 过滤器配置 */
  if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig1) != HAL_OK) {
    /* 滤波器初始化 */
  }
  /* 设置Rx FIFO0的wartermark为1 */
  HAL_FDCAN_ConfigFifoWatermark(&hfdcan1, FDCAN_CFG_RX_FIFO0, 2);
  HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0);

  HAL_FDCAN_Start(&hfdcan1); /* 开启FDCAN1 */
}

void bsp_InitCan3(void) {
  /*                Bit time configuration:
 Bit time parameter         | Nominal      |  Data
 ---------------------------|--------------|----------------
 fdcan_ker_ck               | 20 MHz       | 20 MHz
 Time_quantum (tq)          | 50 ns        | 50 ns
 Synchronization_segment    | 1 tq         | 1 tq
 Propagation_segment        | 23 tq        | 1 tq
 Phase_segment_1            | 8 tq         | 4 tq
 Phase_segment_2            | 8 tq         | 4 tq
 Synchronization_Jump_width | 8 tq         | 4 tq
 Bit_length                 | 40 tq = 2 祍 | 10 tq = 0.5 祍
 Bit_rate                   | 0.5 MBit/s   | 2 MBit/s
*/

  //  HAL_FDCAN_DeInit(&hfdcan1); /* 先清除以前的设置 */
  hfdcan3.Instance = FDCAN3;
  hfdcan3.Init.FrameFormat = FDCAN_FRAME_FD_BRS; /* 传统模式 */
  hfdcan3.Init.Mode = FDCAN_MODE_NORMAL;         /* 模式设置  */
  hfdcan3.Init.AutoRetransmission = ENABLE;
  hfdcan3.Init.TransmitPause = DISABLE;    /* 关闭传输暂停 */
  hfdcan3.Init.ProtocolException = ENABLE; /* 关闭协议异常处理 */
  hfdcan3.Init.NominalPrescaler = 1;       /* 分频系数 */
  hfdcan3.Init.NominalSyncJumpWidth = 8;   /* 重新同步跳跃宽度 */
  hfdcan3.Init.NominalTimeSeg1 = 31;       /* tsg1范围:2~256 */
  hfdcan3.Init.NominalTimeSeg2 = 8;        /* tsg2范围:2~128 */

  hfdcan3.Init.DataPrescaler =
      0x01; /* CAN时钟分配设置,一般设置为1即可,全部由PLL配置好,tq =
               NominalPrescaler x (1/ fdcan_ker_ck),范围1-32 */
  hfdcan3.Init.DataSyncJumpWidth =
      0x04; /* 用于动态调节  Phase_Seg1和 Phase_Seg1,所以不可以比Phase_Seg1和
               Phase_Seg1大,范围1-16 */
  hfdcan3.Init.DataTimeSeg1 =
      0x05; /* 特别注意这里的Seg1,这里是两个参数之和,对应位时间特性图的
                                                                                               Pro_Seg +
                                       Phase_Seg1,范围 */
  hfdcan3.Init.DataTimeSeg2 = 0x04; /* 对应位时间特性图的 Phase_Seg2 */

  hfdcan3.Init.MessageRAMOffset = 1280; /* 信息RAM偏移 */
  hfdcan3.Init.StdFiltersNbr = 1;       /* 标准信息ID滤波器编号 */
  hfdcan3.Init.ExtFiltersNbr = 0;       /* 扩展信息ID滤波器编号 */
  hfdcan3.Init.RxFifo0ElmtsNbr = 2;     /* 接收FIFO0元素编号 */
  hfdcan3.Init.RxFifo0ElmtSize =
      FDCAN_DATA_BYTES_8;           /* 接收FIFO0元素大小:8字节 */
  hfdcan3.Init.RxFifo1ElmtsNbr = 0; /* 设置Rx FIFO1的元素个数,范围0-64 */
  hfdcan3.Init.RxFifo1ElmtSize =
      FDCAN_DATA_BYTES_8;        /* 设置Rx
                                    FIFO1中每个元素大小,支持8,12,16,20,24,32,48或者64字节
                                  */
  hfdcan3.Init.RxBuffersNbr = 0; /* 接收FIFO0元素编号 */
  hfdcan3.Init.TxEventsNbr = 0;  /* 发送事件编号 */

  hfdcan3.Init.TxBuffersNbr = 0; /* 发送缓冲编号 */
  hfdcan3.Init.RxBufferSize =
      FDCAN_DATA_BYTES_8; /* 设置Rx
                             Buffer中每个元素大小,支持8,12,16,20,24,32,48或者64字节
                           */

  hfdcan3.Init.TxFifoQueueElmtsNbr = 2; /* 发送FIFO序列元素编号 */
  hfdcan3.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; /* 发送FIFO序列模式 */
  hfdcan3.Init.TxElmtSize = FDCAN_DATA_BYTES_8; /* 发送大小:8字节 */

  if (HAL_FDCAN_Init(&hfdcan3) != HAL_OK) {
    /* 初始化 */
  }

  sFilterConfig3.IdType = FDCAN_STANDARD_ID;     /* 标准ID */
  sFilterConfig3.FilterIndex = 0;                /* 滤波器索引 */
  sFilterConfig3.FilterType = FDCAN_FILTER_MASK; /* 滤波器类型 */
  sFilterConfig3.FilterConfig =
      FDCAN_FILTER_TO_RXFIFO0;       /* 过滤器0关联到FIFO0 */
  sFilterConfig3.FilterID1 = 0x0000; /* 32位ID */
  sFilterConfig3.FilterID2 =
      0x0000; /* 如果FDCAN配置为传统模式的话,这里是32位掩码 */
  /* 过滤器配置 */
  if (HAL_FDCAN_ConfigFilter(&hfdcan3, &sFilterConfig3) != HAL_OK) {
    /* 滤波器初始化 */
  }
  /* 设置Rx FIFO0的wartermark为1 */
  HAL_FDCAN_ConfigFifoWatermark(&hfdcan3, FDCAN_CFG_RX_FIFO0, 2);
  HAL_FDCAN_ActivateNotification(&hfdcan3, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0);

  HAL_FDCAN_Start(&hfdcan3); /* 开启FDCAN3 */
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 03:40 , Processed in 0.043904 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表