STM32
文章平均质量分 80
ST公司拥有强大的MCU产品线与嵌入式外设IC,学好STM32是嵌入式研发的基本功。
Wallace Zhang
博客初衷:
将学习到的知识分享给大家,一起学习,同时自己又能再一次提高对知识的理解(费曼定理)
2011年 - 2018年(电气工程师,研发自动化设备)
2018年 - 2021年(电气工程师 + 电子工程师,研发机器人)
2021年 - 至今(嵌入式MCU开发工程师,研发机器人)
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
STM32+CubeMX开发笔记汇总(更新2025.11.18)
只会用HAL库,不会完全不理会寄存器,只能算是入门。别扯寄存器开发周期长什么的,移植会很困难。在高手面前,这些都是问题。在高手看来,怎样提高效率与减少空间才值得品味。原创 2021-07-13 21:47:53 · 7900 阅读 · 2 评论
-
STM32F103_Bootloader程序开发16 - 记得喂狗!!!从下载区搬运固件到App区的时候。
摘要: 在开发FOC电机控制板bootloader的OTA功能时,发现将固件切片大小从256改为512后升级失败率显著增加。问题表现为上位机发送完固件后无响应,Flash中下载区固件完整但App区不完整。最终定位原因是OP_Flash_Copy()函数搬运固件时间过长导致看门狗超时重启。由于控制板无串口日志,排查耗时较长。解决方案:在搬运每个切片后及时喂狗。项目已开源,地址见Gitee/GitHub(150字) (注:实际字数149,含标点)原创 2025-11-18 11:50:41 · 325 阅读 · 5 评论 -
STM32 - Embedded IDE - GCC - 编译器设置的最佳方案
有些同学刚从Keil或者IAR等开发环境切换到VScode + GCC开发环境时,不知道构建器怎样设置最合适。所谓最合适就是代码体积更小,降低堆栈的要求,提高代码的执行效率等等。原创 2025-11-10 19:02:10 · 557 阅读 · 1 评论 -
STM32 - Embedded IDE - GCC - rt_thread_nano的终端msh>不工作的排查与解决
RT-Thread的MSH终端正常工作依赖链接脚本中的关键段定义。FSymTab和VSymTab段保存了shell命令的符号表,而.rti_fn*段则处理系统自动初始化函数。当链接脚本缺失这些段定义时,会导致符号表丢失和初始化失败,表现为MSH终端无法识别命令。解决方法是在链接脚本中明确保留这些段,并定义相应的边界符号(如__fsymtab_start/end),确保RT-Thread能正确加载命令和完成初始化。这两部分缺一不可,共同保障了RT-Thread系统的正常运行。原创 2025-09-08 20:16:49 · 767 阅读 · 0 评论 -
STM32 - Embedded IDE - GCC - GCC 环境下rt_thread nano3.13调度器不工作的排查与解决
本文分析了RT-Thread在不同编译器下的入口处理机制差异。在Keil编译器中,RT-Thread使用$Sub$$main和$Super$$main符号重定向透明地拦截main函数调用,先执行系统初始化。而在GCC编译器下,由于缺乏类似功能,RT-Thread定义了entry()作为新入口点,必须修改启动文件将bl main改为bl entry才能确保系统先完成rtthread_startup()初始化。这种差异反映了不同编译器的设计理念,RT-Thread通过适配确保了系统服务在用户代码执行前完成必要初原创 2025-09-08 10:30:40 · 1026 阅读 · 0 评论 -
STM32 - Embedded IDE - GCC - 解决 RT-Thread Nano 3.1.3 在 ARM GCC 14.3 编译器中的 Thumb-2 条件指令错误
本文介绍了在使用CubeMX6.5生成HAL库代码并移植RT-Thread Nano 3.1.3版本时遇到的编译错误问题。错误源于ARM编译器14.3.1版本对Thumb-2指令集的严格要求,需要在条件执行指令前添加IT块。作者通过在context_gcc.S文件中四个关键位置添加IT指令(如IT EQ等),成功解决了VSTMDBEQ、MOVEQ等条件指令的编译问题。最终修改后的代码能够顺利通过编译。该案例展示了处理ARM编译器版本兼容性问题时的典型解决方案。原创 2025-09-05 11:54:53 · 390 阅读 · 0 评论 -
STM32F103_Bootloader程序开发15 - 从Keil到vscode + EIDE + GCC的迁移实践
本文总结了STM32项目从Keil迁移到GCC开发环境时遇到的几个关键问题及解决方案。主要问题包括:1)EIDE插件与J-Link+RTT日志方案不兼容,改为USART2输出日志;2)GCC编译的Bootloader跳转APP时出现HardFault故障,通过注释SCB->VTOR设置解决。文章还提供了OTA升级流程图和项目开源地址,分析了不同编译器导致行为差异的原因(中断时机与向量表处理的区别)。原创 2025-09-04 19:35:32 · 1308 阅读 · 0 评论 -
STM32 - Embedded IDE - GCC - 如何将编译得到的.bin固件添加CRC32校验码
本文介绍了如何在VSCode+EIDE环境下为STM32固件添加CRC32校验码。主要步骤包括:1)准备crc_add.bat和srec_cat.exe工具;2)修改脚本中的输入输出文件名;3)配置构建器选项添加后处理命令;4)编译后自动生成带CRC校验的固件文件。该方法可确保固件完整性,防止IAP升级时出现"变砖"问题。文章提供了GitHub和Gitee源码链接,方便开发者参考实现。原创 2025-09-04 19:18:55 · 574 阅读 · 0 评论 -
STM32 - Embedded IDE - GCC - 如何在工程中定义一段 NoInit RAM 内存
Keil中创建NoInit内存区域的方法与验证 在Keil中通过图形界面配置IRAM2区域(起始地址0x20000000,大小8字节)创建NoInit内存。关键步骤包括: 在MEMORY段定义RAM_NOINIT区域 在SECTIONS段使用(NOLOAD)属性标记.noinit段 通过__attribute__((section(".noinit")))将变量分配到该区域 验证方法: 查看.map文件确认变量地址 检查编译后内存占用情况 确保变量在复位后保持原值 该技术适用于需要保持断原创 2025-09-03 15:08:42 · 664 阅读 · 0 评论 -
STM32 - Embedded IDE - GCC - 使用 GCC 链接脚本限制 Flash 区域
本文对比了Keil和EIDE在限制Flash存储区域的不同方法。Keil通过图形界面在IROM1中设置起始地址(如0x8000000)和大小(如0x10000/64KB)来限定Flash范围;而EIDE则需修改链接文件(.ld)实现相同功能,同样可限定Flash在指定地址范围内(如0x08000000~0x0800FFFF)。两种工具分别采用可视化配置和文本配置方式实现对Flash区域的空间限制。原创 2025-09-03 11:17:05 · 410 阅读 · 0 评论 -
STM32 - Embedded IDE - GCC - 如何在工程中生成.bin格式固件
摘要 默认情况下,Keil MDK工程配置不会自动生成.bin格式固件文件。通过修改构建器选项设置,在"After Build/Rebuild"部分添加相应的转换命令,保存后重新构建项目即可成功生成.bin格式的固件输出文件。这一设置调整解决了默认配置下缺少.bin文件的问题。原创 2025-09-02 17:43:52 · 373 阅读 · 0 评论 -
STM32 - Embedded IDE - GCC - 在C、C++混合开发,C++编译器选项增加“-fno-exceptions“,可以进一步缩小代码的大小
摘要:禁用C++异常处理优化STM32内存占用 在STM32G431RBT6(128KB内存)上开发FOC电机控制项目时,通过添加"-fno-exceptions"编译选项禁用C++异常处理机制,使程序大小从53,884B降至49,444B,节省了4.335KB空间。该优化会禁用try-catch异常处理,并使标准库函数在失败时直接终止而非抛出异常。由于嵌入式开发通常不使用C++标准库和异常处理,且simpleFOC库不受影响,此优化在节省内存的同时不会对项目功能造成负面影响。原创 2025-08-28 13:57:55 · 543 阅读 · 0 评论 -
STM32 - Embedded IDE - GCC - 解决编译器选项里勾选“链接时优化(-flto)”时,编译失败!
摘要 链接时优化(LTO)是一种跨模块的编译优化技术,在链接阶段进行全局优化,包括内联跨文件函数调用、全程序死代码消除、常量传播和循环优化等。实验显示启用LTO后代码大小减少约5.5KB(从58.52KB降至52.9KB)。LTO优势包括代码体积缩减10-30%、性能提升5-15%,但会延长编译时间、增加内存消耗并可能影响调试。实现时需注意处理系统调用函数等依赖问题。原创 2025-08-27 17:14:32 · 385 阅读 · 0 评论 -
STM32 - Embedded IDE - GCC - 重定向printf到串口
摘要:不同编译器下重定向printf到串口的实现方式不同:ARMCC(Keil-MDK)使用fputc()函数,而GCC则使用_write()函数。关键区别在于GCC/newlib环境下printf()函数通过_write()实现输出重定向,而非fputc()。这一差异需要开发者在跨平台开发时特别注意。(98字)原创 2025-08-22 09:26:21 · 321 阅读 · 0 评论 -
STM32 - Embedded IDE - GCC - 显著减少固件的体积
摘要 在嵌入式开发中,使用--specs=nano.specs选项可让编译器采用newlib-nano代替默认的newlib库,显著减少代码体积。newlib-nano针对资源受限的MCU(如STM32G431)进行了优化,裁剪了不必要的功能(如完整printf/scanf、浮点支持等)。测试结果显示,启用该选项后,RAM占用从13.03KB降至10.56KB,FLASH占用从73.34KB降至44.61KB,优化效果显著,尤其适合Flash和RAM紧张的嵌入式系统。原创 2025-08-15 09:24:45 · 704 阅读 · 0 评论 -
STM32 - Embedded IDE - GCC - 解决LWRB库在GCC编译器会编译失败,在ARMCC编译器时却正常编译
摘要 在将EIDE + ARMCC开发环境迁移至EIDE + GCC时,lwrb库出现编译错误,原因是GCC不支持atomic_ulong类型。解决方案是在lwrb.h中通过定义LWRB_DISABLE_ATOMIC 1全局禁用原子操作特性。此举主要影响跨上下文的内存序保证,但在单生产者单消费者模式下影响有限。对于中断或多线程并发场景,建议通过配置临界区保护机制(如关中断或RTOS互斥量)来确保线程安全。 (字数:150)原创 2025-08-15 09:22:30 · 479 阅读 · 0 评论 -
STM32F103_Bootloader程序开发14 - 警惕!别在main()函数里设置中断向量表VTOR
摘要:STM32中断向量表(SCB->VTOR)应在SystemInit()函数中重定位,而非main()函数。系统启动流程中,SystemInit()是最早可安全执行C代码的地方,若在main()中设置VTOR,会导致在设置前可能出现中断,从而跳转到错误的中断服务程序。规范做法是在system_stm32f1xx.c文件的SystemInit()函数中完成VTOR设置,确保在任何可能产生中断的操作前完成重定向。文末提供了基于STM32F103的标准SCB实现项目地址和IAP升级测试结果。原创 2025-08-04 20:15:00 · 871 阅读 · 0 评论 -
STM32F103_Bootloader程序开发13 - 巧用逆向拷贝,实现固件更新的“准原子”操作,无惧升级中的意外掉电
本文针对STM32F103 IAP Bootloader中固件搬运函数存在的潜在风险进行优化。当固件更新过程中意外掉电时,传统顺序拷贝可能导致App区被部分写入但校验通过,造成系统崩溃。 关键改进点: 采用逆向拷贝技术,将向量表(包含栈指针和复位向量)作为最后一步写入 新增OP_Flash_ReverseCopy()函数实现从尾部开始的固件迁移 确保即使掉电,App区要么完全有效,要么完全无效 该方案使固件更新具备"准原子性",大幅提升系统可靠性。项目代码已开源,包含详细的注释和边界检查原创 2025-08-03 18:13:58 · 1767 阅读 · 0 评论 -
FreeRTOS | STM32H7串口中断调用FreeRTOS API,导致程序卡死
文章目录一、前言二、串口中断调用xQueueSendFromISR2.1、串口中断回调函数(usart.c)2.2、stm32h7xx_it.c三、调试3.1、串口中断后,程序卡死3.2、卡死原因四、NIVC中断优先级4.1、串口中断优先级4.2、FreeRTOS配置文件的MAX_SYSCALL_INTERRUPT_PRIORITY一、前言在网络上搜寻了相关的问题,看一下其他人有没有碰到这个问题。实际上有较多CSDN的博主都碰到这个问题,但能把问题说清楚的博主真的很少。这篇CSDN博文解决了我的问题,只原创 2021-06-09 21:22:22 · 7137 阅读 · 4 评论 -
STM32F103_Bootloader程序开发12 - IAP升级全流程
本教程使用正点原子战舰板开发。》上一章节实现App跳转bootloader,接着,跳转到bootloader后,下位机要发送报文‘C’给IAP上位机,表示我准备好接收固件数据。原创 2025-07-04 18:54:24 · 599 阅读 · 0 评论 -
STM32F103_Bootloader程序开发11 - 实现 App 安全跳转至 Bootloader
想象一下,我们的单片机 App 正在稳定地运行着,突然我们想给它升级一下,添加个新功能。我们该如何安全地通知它:“嘿,准备好接收新固件了” ? 这就需要 App 和 Bootloader 之间建立一个可靠的"秘密握手"机制。整个流程就像一次精心策划的"交接仪式":项目地址:现在,我们来看看 App 程序需要增加哪些代码来实现这个"交接仪式"。这个文件负责处理从 App 跳转到 Bootloader 的所有核心逻辑。代码亮点解析: 变量的定义: 函数:头文件很简单,主要是声明 函数,以便在其他文件中(比如原创 2025-07-02 19:00:00 · 1309 阅读 · 0 评论 -
STM32F103_Bootloader程序开发10 - 实现IAP通讯看门狗与提升“跳转状态机”的健壮性
在嵌入式系统的生命周期中,固件更新(IAP,In-Application Programming)是不可或缺的一环。一个设计精良的Bootloader不仅是产品迭代的基石,更是系统稳定性的最后一道防线。在本系列之前的文章中,我们已经成功实现了通过Ymodem协议进行固件的下载、校验与搬运。这个问题看似简单,背后却隐藏着巨大的风险。想象一下,当现场的设备收到一条进入IAP模式的指令后,它跳转到了Bootloader。原创 2025-07-01 19:43:41 · 1337 阅读 · 0 评论 -
STM32F103_Bootloader程序开发09 - 恰到好处的Ymodem协议
这是一个完全解耦的YModem协议下位机实现,专门为STM32F103系列微控制器设计。接收来自任何数据源的YModem格式数据(串口、网口、蓝牙、文件等)验证数据包的完整性(CRC16校验)将固件数据写入Flash存储器的指定区域提供传输进度反馈完全独立于通信接口,支持任意数据源。原创 2025-06-25 15:12:04 · 1832 阅读 · 0 评论 -
STM32F103_LL库+寄存器学习笔记12.3 - 串口DMA高效收发实战3:支持多实例化的版本
《STM32F103_LL库+寄存器学习笔记12.2 - 串口DMA高效收发实战2:进一步提高串口接收的效率》基于上一个版本,进一步提升代码的模块化水平,支持多实例化。如上所示,收发大量的数据,没有丢包。项目地址:github:gitee(国内):1.2、bsp_usart_drive.h1.3、main.c原创 2025-06-21 16:53:25 · 905 阅读 · 0 评论 -
STM32F103_Bootloader程序开发08 - 将App下载缓存区的固件搬运到App区,运行新的App程序(op_flash.c与op_flash.h)
如上所示,开始完成op_flash模块与fw_verify模块。上一章节使用J-Flash将App_crc.bin下载到咱项目定义的”App下载缓存区“,起始地址0x08040000、大小0x30000。然后,通过soft_crc32.c的函数Calculate_Firmware_CRC32_SW()对App_crc.bin进行CRC32校验。详细请回头看上一章节《CRC32校验成功,证明"App下载缓冲区"的固件完整性没有问题。原创 2025-06-07 19:09:07 · 1124 阅读 · 0 评论 -
STM32F103_Bootloader程序开发07 - 使用J-Flash将App_crc.bin烧录到App下载缓存区,再校验CRC32,确认固件完整性
本章节做一个实验“校验一遍App缓存区的固件”,看看能不能通过CRC32校验。在OTA升级流程上,当bootloader程序接收完上位机下发的App固件到App下载缓存区后,bootloader程序要对App下载缓存区的固件进行CRC32校验。项目地址:gitee(国内): https://gitee.com/wallace89/MCU_Develop/tree/main/bootloader07_stm32f103_check_crc32。原创 2025-05-31 10:31:51 · 994 阅读 · 0 评论 -
STM32F103_Bootloader程序开发06 - IAP升级用的App.bin增加CRC32校验码,确保固件完整性,防止“变砖”
crc_add.bat脚本有没有将改动固件的内容呢?让ChatGPT帮我检查一下。原创 2025-05-30 09:25:18 · 1064 阅读 · 16 评论 -
STM32F103_Bootloader程序开发05 - Keil修改生成文件的路径与文件名,自动生成bin格式文件
这是 ARM Keil 自带的一个命令行工具,用于将编译生成的目标文件(axf/elf格式)转换为其他格式(比如 bin、hex)。原创 2025-05-29 21:02:24 · 882 阅读 · 0 评论 -
STM32F103_Bootloader程序开发04 - App跳转模块(app_jump.c与app_jump.h)
本章节的目的是上一章节《[[STM32F103_Bootloader程序开发03 - 启动入口与升级模式判断(boot_entry.c与boot_entry.h)]]》学会使用"C/C++的构造函数(constructor)机制"让我们自己编写的函数在main()之前先运行。本章节将结合上一章节的代码,梳理“无须deinit"的实现过程。如上所示,摘自bootloader开源项目。原创 2025-05-28 19:07:03 · 1673 阅读 · 7 评论 -
STM32F103_Bootloader程序开发03 - 启动入口与升级模式判断(boot_entry.c与boot_entry.h)
强烈建议大家去学习一下这个优秀的开源项目。我暂时将bootloader程序分别五个模块,先从"启动入口与升级模式判断"模块开始吧。代码分别是boot_entry.c与boot_entry.h。项目刚开始,boot_entry.c与boot_entry.h会随着项目的推进会增加一些代码。项目地址:gitee(国内): https://gitee.com/wallace89/MCU_Develop/tree/main/bootloader03_stm32f103_boot_entry。原创 2025-05-26 20:47:11 · 1338 阅读 · 0 评论 -
STM32F103_Bootloader程序开发02 - Bootloader程序架构与STM32F103ZET6的Flash内存规划(flash_map.h)
在工业设备和机器人项目中,固件远程升级能力已成为提升设备维护性与生命周期的关键手段。本文将围绕STM32平台,系统性介绍一个简洁、可靠的Bootloader程序设计思路。每个模块各司其职,既保证了流程的清晰、易维护,又为后续功能拓展(如安全保护、异常处理)预留了接口。通过模块化设计,能够高效实现与上位机的安全固件升级,显著提升系统的可靠性和可维护性。原创 2025-05-25 19:04:47 · 1356 阅读 · 2 评论 -
STM32F103 HAL多实例通用USART驱动 - 高效DMA+RingBuffer方案,量产级工程模板
前阵子完成的LL库与寄存器版本的代码,有一个明显的缺点是不支持多实例化。最近,计划基于HAL库系统地梳理一遍bootloader程序开发。在bootloader程序开发项目里,需要用到HAL库的串口驱动代码。所以,继续把代码优化优化,将多实例化模块做出来。bsp_usart_hal 驱动代码特点总结:支持多实例通用管理DMA收发全流程、双缓冲高效传输RingBuffer无缝缓存机制健壮的错误统计与自恢复机制工程化量产导向测试效果如下,接收与发送都没有丢包。原创 2025-05-24 19:38:03 · 1096 阅读 · 0 评论 -
STM32F103_Bootloader程序开发01 - 什么是IAP?跟OTA有什么关系?
IAP,中文一般称为“应用程序内编程”或“在应用中自编程”。本质含义:MCU 在运行用户代码(App或Bootloader)时,通过自身的代码(而不是用外部编程器/仿真器)来擦写和更新片上 Flash 内容。典型的应用场景:在系统上线后,通过串口、CAN、USB、以太网等接口下载新固件,并写入指定Flash区,完成固件升级。实际场景:工程师用串口工具将固件下载到MCU,MCU通过IAP代码将固件烧写到App区。OTA,直译就是“空中下载”或者“远程升级”。原创 2025-05-23 18:02:34 · 1333 阅读 · 0 评论 -
STM32F103_LL库+寄存器学习笔记12.2 - 串口DMA高效收发实战2:进一步提高串口接收的效率
通过优化代码算法,在串口空闲中断回调里不需要暂时关闭DMA接收,达到提高串口接收的效率。在IDLE接收中断里关闭DMA接收会导致接收过程中有数据丢失风险(关DMA的瞬间如果有数据到来,会丢帧!原创 2025-05-20 18:51:53 · 956 阅读 · 0 评论 -
STM32F103_LL库+寄存器学习笔记24 - TIM产生中心PWM波,中心对齐模式1 + PWM模式2(FOC算法专用)
之前的笔记使用HAL库实现三相中心对齐且互补的PWM波形,本章节将采用LL库与寄存器方式实现。详细的解释请看之前的HAL库笔记。原创 2025-05-18 10:27:07 · 1666 阅读 · 0 评论 -
STM32F103_LL库+寄存器学习笔记23 - PWM波形输出及软件方式调整周期与占空比
脉宽调制(PWM)是 STM32 定时器最常用的输出模式之一,广泛应用于电机驱动、LED 调光、伺服控制和功率管理等场景。本篇文章将以 TIM5 为例,从寄存器层面深入剖析 PWM 输出的原理与实现步骤。通过本篇博客,你不仅能掌握 CubeMX 及 LL 库的调用,更能从底层寄存器视角构建完整的 PWM 输出思维,为后续复杂控制奠定坚实基础。本章节使用TIM5生成周期为1ms的PWM波形,占空比50%。并介绍如何通过软件方式改变PWM波形的周期与占空比。原创 2025-05-14 18:27:21 · 1244 阅读 · 0 评论 -
STM32F103_LL库+寄存器学习笔记22 - 基础定时器TIM实现1ms周期回调
如上所示,STM32F103有两个基本定时器TIM6与TIM7,所谓「基本定时器」,即功能最简单的定时器。原创 2025-05-13 19:03:44 · 1105 阅读 · 0 评论 -
STM32F103_LL库+寄存器学习笔记12.1 - 串口DMA高效收发实战:引入ringbuffer结构(开源库lwrb)
在STM32串口通信中,传统中断方式处理效率低、耦合度高,难以应对高频收发场景。为此,本章引入ringbuffer结构,配合USART1的DMA机制,实现接收数据的自动搬运与发送数据的非阻塞输出。ringbuffer作为中间缓冲区,有效解耦了硬件DMA与用户代码逻辑,不仅提升了数据处理效率,也增强了系统稳定性和可扩展性。效果如下:如上所示,从SSCOM串口助手与单片机的全局变量看来,单片机没有丢包。单片机一共发送356607bytes,接收344960bytes。原创 2025-05-12 18:50:53 · 753 阅读 · 0 评论 -
STM32F103_HAL库+寄存器学习笔记21 - CAN接收过滤器:CPU减负神器,提升系统效率的第一道防线
在STM32F103的CAN总线应用中,硬件过滤器(Filter)承担着关键角色。本章将从寄存器层面深入剖析CAN接收过滤器的工作机制与配置方法,帮助理解如何高效筛选关键信息,减轻CPU负担。通过合理使用过滤器,不仅能提升系统整体运行效率,还能显著降低接收溢出风险。文章将结合HAL库操作与直接寄存器配置,全面构建底层视角下的CAN接收优化思路。原创 2025-04-27 21:39:18 · 1413 阅读 · 0 评论 -
STM32F103_HAL库+寄存器学习笔记20 - CAN发送中断+ringbuffer + CAN空闲接收中断+接收所有CAN报文+ringbuffer
如上所示,在[[STM32F103_HAL库+寄存器学习笔记19 - CAN发送中断+CAN接收中断+接收所有CAN报文+ringbuffer数据结构]]的基础上,为CAN发送也安排上强大的ringbuffer(环形缓冲区)。CAN发送有三个发送邮箱,为什么还另外需要ringbuffer?原创 2025-04-24 19:09:04 · 1390 阅读 · 0 评论
分享