news 2026/6/10 21:12:22

STM32F105换GD32F305踩坑实录:5个CAN驱动移植的坑点与填坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32F105换GD32F305踩坑实录:5个CAN驱动移植的坑点与填坑指南

STM32F105换GD32F305踩坑实录:5个CAN驱动移植的坑点与填坑指南

从STM32F105切换到GD32F305的过程看似简单,但实际移植过程中遇到的CAN驱动问题却让我这个老嵌入式工程师踩了不少坑。国产MCU在寄存器命名和功能实现上的细微差异,往往会导致原本在STM32上运行良好的代码在GD32上出现各种诡异行为。本文将详细复盘我在移植过程中遇到的5个典型问题,包括现象描述、原因分析和解决方案,希望能帮助正在进行类似移植的同行少走弯路。

1. CAN初始化失败:SLEEP位的隐藏陷阱

移植后遇到的第一个问题就是CAN初始化失败。在GD32F305上调用HAL_CAN_Init()函数时,总是返回错误状态。经过仔细排查,发现问题出在SLEEP位的处理上。

现象描述

  • STM32F105上CAN初始化正常
  • GD32F305上HAL_CAN_Init()返回错误
  • 调试发现卡在等待CAN_MSR.INAK置位的循环中

原因分析: 两个芯片在初始化后CAN_MCR.SLEEP位都默认为1,但行为却有差异:

  • STM32:设置CAN_MCR.INRQ后,CAN_MSR.INAK会立即置1,不受SLEEP位影响
  • GD32:CAN_MCR.INRQ置1后,只有在SLEEP位为0时CAN_MSR.INAK才会置1

解决方案: 在调用HAL_CAN_Init()前,需要先清除SLEEP位:

// 在HAL_CAN_MspInit()函数末尾添加 CLEAR_BIT(canHandle->Instance->MCR, CAN_MCR_SLEEP);

或者直接调用HAL_CAN_WakeUp()函数唤醒CAN控制器。

2. 连续发送数据异常:发送邮箱逻辑差异

第二个坑出现在连续发送CAN报文时。在GD32上,连续调用HAL_CAN_AddTxMessage()发送两包数据时,第二包数据总是无法发出。

现象描述

  • STM32上连续发送两包数据正常
  • GD32上只能发送第一包数据
  • 无错误标志,但第二包数据未出现在总线上

原因分析: 问题根源在于两个芯片对发送邮箱状态的处理逻辑不同:

特性STM32F105GD32F305
状态寄存器CAN_TSRCAN_TSTAT
邮箱号字段CODE[1:0]NUM[1:0]
行为描述返回下一个空邮箱或优先级最低的邮箱返回下一个将要发送的邮箱或最后一个邮箱

解决方案: 需要修改HAL_CAN_AddTxMessage()中的邮箱选择逻辑:

// 原代码 transmitmailbox = (tsr & CAN_TSR_CODE) >> CAN_TSR_CODE_Pos; // 修改后代码 if(CAN_TSR_TME0 == (tsr & CAN_TSR_TME0)) { transmitmailbox = 0; } else if(CAN_TSR_TME1 == (tsr & CAN_TSR_TME1)) { transmitmailbox = 1; } else if(CAN_TSR_TME2 == (tsr & CAN_TSR_TME2)) { transmitmailbox = 2; } else { transmitmailbox = 3; }

3. CAN接收异常:过滤器配置的坑

第三个问题更加隐蔽:GD32的CAN0(对应STM32的CAN1)能发送数据,却接收不到任何报文。

现象描述

  • STM32上CAN1收发正常
  • GD32上CAN0能发送但接收不到数据
  • 总线信号正常,其他节点能收到GD32发送的数据

原因分析: 问题出在过滤器配置上。两个芯片的过滤器分配机制有差异:

  1. STM32的CAN_FMR.CAN2SB和GD32的CAN_FCTL.HBC1F控制CAN1/CANb的过滤器起始位置
  2. 默认值都是14(0x0E),但代码中未初始化sFilterConfig1.SlaveStartFilterBank
  3. STM32存在与文档不符的行为,即使CAN2SB=0也能接收数据
  4. GD32严格遵循文档,HBC1F=0时CANa无法使用任何过滤器

解决方案: 在调用HAL_CAN_ConfigFilter()前正确初始化过滤器配置:

sFilterConfig1.SlaveStartFilterBank = 14; // 保持与复位默认值一致

4. 第二个CAN接口异常:过滤器配置遗漏

解决了CANa的接收问题后,又发现GD32的CANb(对应STM32的CAN2)无法正常通信。

现象描述

  • 修改过滤器配置后,CANa工作正常
  • 但CANb无法收发数据
  • 总线终端电阻配置正确

原因分析: 原因在于原代码中只配置了CANa的过滤器,没有配置CANb的过滤器。当CAN_FMR.CAN2SB被正确设置后,影响了CANb的默认过滤器行为。

解决方案: 需要为CANb添加独立的过滤器配置:

CAN_FilterTypeDef sFilterConfig2; // 其他配置... sFilterConfig2.FilterBank = 15; // 使用过滤器15,与SlaveStartFilterBank=14匹配 HAL_CAN_ConfigFilter(&hcan2, &sFilterConfig2);

5. 数据发送丢失:超时处理的临界条件

最后一个问题是GD32在连续发送多包数据时会出现数据丢失。

现象描述

  • 连续发送4包数据时,第3包丢失
  • 现象在特定超时值下出现
  • STM32上即使触发超时也能完整发送

原因分析: 问题出在发送超时处理上:

  1. 原代码使用固定超时值200,对于GD32来说太小
  2. GD32执行速度更快,在超时触发时可能正好完成发送
  3. STM32因速度较慢,超时触发时数据还未发送完,实际未终止发送
  4. GD32严格执行终止操作,导致数据被真正丢弃

测试数据对比

芯片超时值范围行为表现
STM32<190丢失第3包
STM32190-300触发超时但完整发送
STM32>300正常发送
GD32<255丢失第3包
GD32255-395触发超时但完整发送
GD32>395正常发送

解决方案: 增大超时值,考虑最坏情况:

// 将各处超时值统一修改为足够大的值 uint32_t timeout = 10000; // 考虑低波特率情况

注意:更完善的解决方案应考虑波特率和时钟频率的影响,动态计算超时值。

移植过程中发现,GD32F305在CAN外设行为上与STM32F105存在多处细微但关键的差异。这些差异往往不会在数据手册中特别标注,需要开发者通过实际测试来发现。建议在移植时:

  1. 仔细对比每个寄存器的位定义
  2. 不要假设默认行为一致
  3. 对关键操作添加充分的调试信息
  4. 边界条件测试要覆盖各种极端情况
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 21:04:06

项目三简易计算器 任务3-3加法计算器

任务描述&#xff1a;单片机连接8位共阳极数码管和4*4矩阵键盘&#xff0c; 利用矩阵键盘定义0~9数字键&#xff0c;并定义、-、*、/、等五个功能键。 编程实现简易计算器功能&#xff0c;完成两个1位十进制数的四则运算。 加法计算器…

作者头像 李华
网站建设 2026/6/10 21:01:31

5分钟引爆Blender纹理革命:Dream Textures深度实战指南

5分钟引爆Blender纹理革命&#xff1a;Dream Textures深度实战指南 【免费下载链接】dream-textures Stable Diffusion built-in to Blender 项目地址: https://gitcode.com/gh_mirrors/dr/dream-textures 还在为3D模型寻找完美纹理而烦恼吗&#xff1f;还在Photoshop和…

作者头像 李华
网站建设 2026/6/10 21:00:43

GSConv+VoVGSCSP(Slimneck报错修正)

参考有温度的AI提供的Slimneck代码进行的报错修改&#xff1a; 链接&#xff1a;YOLOv5改进之YOLOv5GSConvSlim Neck_vovgscsp-CSDN博客 报错&#xff1a; TypeError: conv2d() received an invalid combination of arguments - got (Tensor, Parameter, NoneType, tuple, t…

作者头像 李华
网站建设 2026/6/10 20:56:34

深度解析ReVanced Patches:Android应用补丁技术的3大核心机制

深度解析ReVanced Patches&#xff1a;Android应用补丁技术的3大核心机制 【免费下载链接】ravanced-patches &#x1f9e9; Patches for ReVanced 项目地址: https://gitcode.com/GitHub_Trending/re/ravanced-patches ReVanced Patches是一个专注于为Android应用提供功…

作者头像 李华