ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

STM32从入门到实战:架构、开发环境与外设调试全解析

STM32从入门到实战:架构、开发环境与外设调试全解析 STM32 这颗芯片只要你玩过嵌入式基本绕不开它。我最早接触它的时候是从一块最小系统板开始的当时连晶振怎么接、BOOT引脚是干嘛的都没搞明白烧录一次失败一次折腾了整整一个周末才把第一个 LED 点亮。后来做过的项目从智能小车、鱼缸控制器、USB 虚拟串口设备到 EtherCAT 从站、FOC 驱动、LVGL 界面移植踩过的坑可以说覆盖了从时钟树配置到链接脚本的各个角落。这篇内容我想把 STM32 从“理论”到“能跑起来”这条链路上最关键的东西梳理一遍不是那种抄手册的教程而是我自己反复验证过、觉得真正有用的部分。不管你是刚拿到开发板的新手还是已经做过几个项目但总觉得基础不牢的开发者应该都能从中找到一些对你有用的东西。1. 先把 STM32 的“骨架”摸清楚再动手写代码1.1 系统架构决定了你能做什么、不能做什么很多人拿到 STM32 第一件事就是打开 Keil 新建工程然后开始抄例程。这个顺序其实反了。你得先知道这颗芯片内部是怎么组织的后面遇到问题才知道往哪个方向查。STM32 的核心架构可以理解为几条总线把不同的“功能区”串起来。以最常见的 F1 系列为例Cortex-M3 内核通过 ICode 总线取指令通过 DCode 总线取数据这两条总线挂在 Flash 上。而 SRAM、外设寄存器这些则挂在系统总线上再通过 AHB 和 APB 桥接到各个外设。AHB 是高速总线挂的是 DMA、SRAM、Flash 接口这些APB 是低速总线APB1 通常跑 36MHzAPB2 跑 72MHz串口、定时器、GPIO 这些外设就挂在上面。这个结构直接影响到你后面做 DMA 传输时的数据通路选择。比如你要用串口 DMA 发送数据数据从 SRAM 到 USART 的数据寄存器走的是 AHB 到 APB 的路径这时候你就要注意 APB 的时钟频率和 DMA 通道的映射关系。我见过不少人 DMA 配置了半天没反应最后发现是 DMA 通道选错了因为不同外设对应的 DMA 通道是固定的不是随便选的。再说时钟树。STM32 的时钟源有 HSI内部高速时钟、HSE外部高速时钟、LSI、LSE 这几种。HSI 精度一般做串口通信容易出问题所以正经项目基本都用 HSE 加 PLL 倍频。以 F103 为例8MHz 的晶振经过 PLL 9 倍频得到 72MHz 的系统时钟然后 AHB 不分频APB1 二分频得 36MHzAPB2 不分频得 72MHz。这个配置你在 SystemInit 函数里能看到但很多人从来不看他直接就用默认的。结果一旦换了晶振频率串口波特率就全乱了。提示如果你用的是 HSE但板子上的晶振没起振STM32 会自动切到 HSI 运行。这时候程序还能跑但所有基于 HSE 计算的波特率、定时器周期都会偏。判断方法很简单在初始化后读一下 RCC_GetClocksFreq 的返回值看看是不是你预期的频率。1.2 存储器映射与启动模式的关系STM32 的地址空间是 4GB从 0x00000000 到 0xFFFFFFFF。其中 Flash 通常映射在 0x08000000 开始的位置SRAM 在 0x20000000。但芯片复位后它会根据 BOOT 引脚的状态把不同的区域映射到 0x00000000 地址。这就是所谓的启动模式。BOOT0 和 BOOT1 的组合决定了三种启动方式从主 Flash 启动、从系统存储器启动、从嵌入式 SRAM 启动。系统存储器里存的是出厂固化的 Bootloader支持通过串口下载程序。很多人用 ST-Link 烧录习惯了不知道串口下载这回事其实当你 ST-Link 不在手边的时候用 USB 转串口加 BOOT 跳线也能救急。这里有个容易踩的坑有些板子把 BOOT0 直接接地了你想用串口下载就得把跳线帽拔了再插到高电平。还有下载完之后一定要把 BOOT0 恢复成低电平再复位否则程序不会从 Flash 启动。我第一次用串口下载的时候就是忘了这一步以为下载失败了又重新下了一遍白白折腾了半小时。1.3 芯片第一脚怎么确认——一个看似简单但经常翻车的问题“STM32 芯片第一脚怎么确认”这个问题在搜索里出现频率很高说明确实有很多人在这上面栽过跟头。芯片表面通常有一个小圆点或者一个斜切角那个位置对应的就是第 1 脚。但不同封装标记方式不一样LQFP 封装一般是在一角有个圆点QFN 封装可能是背面有个散热焊盘加一个标记点。更稳妥的方法是看芯片表面的丝印文字方向。把芯片放正丝印文字从左到右正常阅读的时候左下角就是第 1 脚然后逆时针排列。这个方法我用了很多年基本没出过错。如果你实在不确定拿万用表打一下二极管档测一下 VSS 和 VDD 之间的压降找到电源引脚之后再对照数据手册的引脚定义表来反推。焊接的时候也要注意LQFP 封装的引脚很密拖焊的时候容易连锡。我的习惯是先用助焊剂涂一遍然后用刀头烙铁加少量焊锡快速拖过去最后用吸锡线把多余的锡吸掉。QFN 封装更麻烦底部散热焊盘必须接地而且要用热风枪从背面吹正面吹容易把塑料本体吹变形。2. 开发环境搭建从标准库到 HAL 库的选择逻辑2.1 Keil 安装与芯片包的坑Keil MDK 是 STM32 开发最常用的 IDE 之一但它的安装过程有几个地方容易出问题。首先是版本选择Keil5 和 Keil4 的芯片包格式不一样Keil5 用的是 Pack 格式。如果你同时要开发 C51 和 STM32需要把两个版本的 Keil 装在不同目录下否则会冲突。我试过装在一起结果 C51 的编译器把 STM32 的工程文件关联搞乱了后来老老实实分开装才解决。芯片包的安装也是个高频问题。Keil5 本身不带任何芯片的支持包你需要去官网下载对应的 Device Family Pack。比如 STM32F1 系列要装 Keil.STM32F1xx_DFPF4 系列要装 Keil.STM32F4xx_DFP。装完之后在新建工程时才能看到对应的芯片型号。有时候网络不好在线安装会失败这时候可以下载离线包双击安装。注意如果你用的是 Keil 的社区版代码大小限制是 32KB。超过这个限制编译会报错。做小项目够用但一旦移植了 LVGL 或者跑了 RTOS很容易超。这时候要么换用 CubeIDE要么购买正式授权。2.2 标准库、HAL 库、LL 库到底选哪个这个问题争论了很多年我的看法是根据项目阶段来选。标准库Standard Peripheral Library是 ST 早期推出的代码直观寄存器操作封装得比较薄适合学习和需要精细控制的场景。但 ST 已经不再维护它了新芯片比如 H7 系列根本不提供标准库支持。HAL 库Hardware Abstraction Layer是 ST 现在主推的配合 CubeMX 使用可以图形化配置引脚和时钟生成初始化代码。它的优点是跨系列移植方便F1 上写的 HAL 代码稍微改改就能跑到 F4 上。缺点是代码效率偏低中断处理里套了太多层函数调用对时间敏感的场景不太友好。LL 库Low Layer介于两者之间它提供了一层轻量级的封装既保留了寄存器操作的效率又有一定的可读性。我现在的习惯是初始化用 CubeMX 生成 HAL 代码然后在关键的中断和循环里直接用 LL 库或者寄存器操作来提速。库类型优点缺点适用场景标准库代码直观、效率高不再维护、新芯片不支持老项目维护、学习原理HAL 库跨系列移植方便、生态好效率偏低、代码臃肿快速原型、复杂外设LL 库效率与可读性平衡覆盖外设不全时间敏感场景2.3 新建工程的完整流程与常见报错用标准库新建工程的时候你需要手动添加启动文件、系统初始化文件、外设驱动文件还要在 Keil 里设置头文件包含路径和宏定义。宏定义这里特别容易漏比如 STM32F10X_HD 这个宏不定义的话启动文件里的中断向量表就对不上程序一跑就进 HardFault。用 CubeMX 新建工程就简单很多选好芯片型号配置好时钟树和引脚点生成代码就行。但生成的工程默认用的是 HAL 库如果你想要标准库或者 LL 库需要在 Project Manager 里改设置。编译报错里最常见的是 “cannot open source input file” 和 “undefined symbol”。前者一般是头文件路径没加对后者通常是源文件没添加到工程里。还有一个经典的报错是 “load … project.axf error: flash download failed”这个多半是 Flash 算法没选对在 Keil 的 Options for Target 里 Debug 选项卡的 Settings 里要选对芯片对应的 Flash 算法。3. 那些绕不开的外设从 GPIO 到 USB 的实战细节3.1 GPIO 与按键电路设计中的电气考量点亮一个 LED 是所有人的第一个 STM32 程序但就是这 simplest 的 GPIO 操作里面也有不少门道。STM32 的 GPIO 有八种模式输入浮空、输入上拉、输入下拉、模拟输入、开漏输出、推挽输出、推挽复用、开漏复用。驱动 LED 一般用推挽输出因为推挽能同时提供拉电流和灌电流能力。但这里有个电流限制的问题。STM32 单个 GPIO 的最大输出电流是 25mA整个芯片所有 GPIO 加起来不能超过 150mA。如果你直接用一个 GPIO 驱动大功率 LED不加限流电阻轻则 LED 烧掉重则芯片引脚损坏。正确的做法是串一个限流电阻阻值根据 LED 的正向压降和期望电流来算。比如红色 LED 正向压降 1.8V期望电流 10mA供电 3.3V那么电阻就是 (3.3 - 1.8) / 0.01 150 欧姆。按键电路设计也有讲究。最简单的接法是按键一端接 GPIO另一端接地GPIO 配置成输入上拉。按下时 GPIO 读到低电平松开时读到高电平。但机械按键有抖动需要在软件里做消抖。我一般用 20ms 的延时消抖就是在检测到电平变化后延时 20ms 再读一次如果状态一致就确认。更好的做法是用定时器中断定期扫描按键状态这样不阻塞主循环。提示如果按键离 MCU 比较远最好在 GPIO 和按键之间串一个 100 欧姆左右的电阻再并一个 100nF 的电容到地做硬件消抖。这样软件里只需要很短的消抖时间甚至不用消抖。3.2 定时器从延时到 PWM 到输入捕获STM32 的定时器是功能最丰富的外设之一也是很多人觉得最难啃的部分。基本定时器只能计数通用定时器多了输入捕获和输出比较高级定时器还多了死区控制和刹车输入专门给电机控制用的。先说延时函数。很多人用 HAL_Delay 或者自己写的循环延时但循环延时在不同优化等级下时间不一样而且不精确。用定时器做延时才靠谱。配置一个定时器预分频器设成 72-1这样计数频率就是 1MHz每计数一次是 1 微秒。自动重装载值设成你要延时的微秒数启动定时器后轮询更新标志位就行。PWM 输出是定时器另一个高频用法。控制 LED 亮度、驱动舵机、调电机转速都靠它。配置的时候要注意频率和占空比的计算。假设系统时钟 72MHz预分频器设成 72-1自动重装载值设成 1000-1那么 PWM 频率就是 72MHz / 72 / 1000 1kHz。占空比通过比较寄存器来设设成 500 就是 50% 占空比。输入捕获用来测频率和占空比。配置成上升沿捕获第一次捕获到上升沿时记录计数器的值第二次捕获到上升沿时再记录一次两次之差就是一个周期的时间。这里有个细节如果信号频率很低计数器可能会溢出所以要在溢出中断里做一个溢出计数最后把溢出次数乘以重装载值再加上差值才是完整周期。3.3 串口通信从轮询到 DMA 到 PID 调试串口是调试和通信最常用的接口。最简单的用法是轮询发送但这样会阻塞 CPU。中断发送好一些但每发一个字节进一次中断波特率高的时候中断太频繁。DMA 发送是最省 CPU 的方式配置好 DMA 通道和串口的数据寄存器地址启动传输后 CPU 就可以去干别的事了。接收这边更复杂一些。如果你不知道对方什么时候发数据、发多长就需要用空闲中断加 DMA 的方式。串口空闲中断会在总线空闲一个字节时间后触发这时候你去读 DMA 的剩余传输数量就能算出收到了多少字节。这个方案我用了很多年非常稳定。串口还有一个常见用途是调试 PID 参数。做电机控制或者温控的时候你需要实时看当前值、目标值和输出值。用串口把这三个值打印出来配合上位机的波形显示工具调参效率会高很多。我一般会定义一个简单的协议比如每帧以 0xAA 0x55 开头后面跟三个 float 数据最后加一个校验字节。上位机解析这个协议就能实时绘图。3.4 USB 虚拟串口没有串口芯片也能通信很多 STM32 芯片自带 USB 外设可以做成 USB 虚拟串口设备CDC 类这样插上 USB 线就能在电脑上看到一个串口不需要额外的 CH340 或者 CP2102 芯片。这个功能在 F103、F407 这些经典型号上都有。实现 USB 虚拟串口需要用到 ST 的 USB 库配置起来步骤不少。首先要使能 USB 时钟配置 USB 引脚一般是 PA11 和 PA12然后在 USB 库的中断处理里调用相应的回调函数。发送数据的时候调用 CDC_Transmit_FS 函数接收数据在 CDC_Receive_FS 回调里处理。这里有个坑USB 的时钟必须是 48MHz而系统时钟不一定是 48MHz 的整数倍。F103 的 USB 时钟是从 PLL 分频来的PLL 输出 72MHzUSB 预分频器只能选 1.5 分频得到 48MHz。这个 1.5 分频是固定的不能改。如果你把系统时钟配成别的频率USB 就枚举不出来了。注意USB 虚拟串口在 Windows 上需要驱动虽然 Windows 10 之后自带 CDC 驱动但有些精简版系统可能没有。如果设备管理器里显示未知设备可以手动安装 ST 的 VCP 驱动。4. 进阶实战从智能小车到 EtherCAT 的项目经验4.1 两轮差速小车的控制逻辑与调试两轮差速小车是很多人做过的项目看起来简单但要做好也不容易。核心是电机控制、编码器测速和 PID 调节这三块。电机控制一般用 PWM 加 H 桥驱动。PWM 频率选 10kHz 到 20kHz 之间比较合适太低会有啸叫太高开关损耗大。H 桥驱动芯片比如 L298N 或者 TB6612注意它们的逻辑电平和 STM32 的 3.3V 是否兼容。L298N 是 5V 逻辑直接接 3.3V 的 GPIO 可能识别不了高电平需要加电平转换。编码器测速用定时器的编码器模式最方便。STM32 的通用定时器支持正交编码器接口把编码器的 A 相和 B 相接在定时器的两个通道上硬件自动计数你只需要定期读计数器的值就能算出速度。这里要注意编码器的线数和轮子的周长换算成实际速度。PID 调节是小车能走直线的关键。两个电机即使型号相同实际转速也会有差异。用增量式 PID 分别控制两个电机的转速让它们跟随同一个目标值。调参的时候先调 P让系统有响应但不振荡再加 I消除稳态误差D 一般用得少因为编码器噪声大的时候 D 项会放大噪声。4.2 基于 STM32 的智能鱼缸控制器鱼缸控制器这个项目我做过好几个版本功能从最简单的定时开关灯到后来的自动喂食、水温控制、水位检测、手机远程监控。这里挑几个关键技术点说说。水温控制用 DS18B20 数字温度传感器单总线协议一个 GPIO 就能读温度。但单总线对时序要求很严中断开着的时候容易读失败。我的做法是在读温度的时候关中断读完再开。或者用定时器加 DMA 来模拟单总线时序这样不占用 CPU。水位检测用超声波模块 HC-SR04Trig 引脚发一个 10 微秒的高电平然后 Echo 引脚会输出一个高电平高电平的持续时间就是声波往返的时间。距离等于时间乘以声速再除以二。这里要注意温度对声速的影响冬天和夏天测出来的距离会有偏差要求高的话得做温度补偿。自动喂食用舵机控制一个旋转料盘定时转动一定角度把鱼食倒进缸里。舵机控制就是 50Hz 的 PWM脉宽 0.5ms 到 2.5ms 对应 0 到 180 度。用定时器的一个通道输出 PWM改比较寄存器的值就能控制角度。4.3 EtherCAT 从站与 FOC 驱动的技术门槛EtherCAT 和 FOC 这两个方向门槛比较高但也是工业控制里很有价值的方向。EtherCAT 从站需要专门的从站控制器芯片比如 LAN9252 或者 AX58100STM32 通过 SPI 或者并口和它通信。协议栈部分可以用开源的 SOEM 或者商业协议栈。FOC磁场定向控制用于无刷电机的矢量控制。核心思想是把三相电流通过 Clarke 变换和 Park 变换转到旋转坐标系下在 d-q 轴上分别控制励磁分量和转矩分量。STM32 的定时器支持互补 PWM 输出和死区插入正好用来驱动三相逆变桥。ADC 要配置成由定时器触发采样在 PWM 周期的特定时刻采集相电流。这两个方向都需要比较深的数学和电机学基础不是看几篇教程就能上手的。我的建议是先把手头的电机转起来用六步换相的方式跑通再慢慢过渡到 FOC。EtherCAT 的话先找一个带从站控制器的开发板把厂商提供的例程跑通再研究协议栈的移植。5. 调试与排错那些让你抓狂的问题怎么定位5.1 延时函数卡死的几种可能“STM32 延时函数 delay 卡死”是个高频问题。卡死的原因通常有几种一是时钟没配置对系统时钟比预期慢很多导致延时时间被拉长二是中断优先级配置有问题延时函数里等标志位的时候被高优先级中断打断而那个中断里又调用了延时函数形成死锁三是看门狗没喂程序被复位了看起来像卡死。排查的时候先用示波器或者逻辑分析仪看一下 GPIO 有没有输出确认程序到底跑没跑。如果 GPIO 有翻转但周期不对那就是时钟问题。如果 GPIO 完全没动静可能是进了 HardFault。在 HardFault_Handler 里加一个死循环然后连上调试器看调用栈就能定位到出问题的代码位置。5.2 串口通信乱码与丢包串口乱码最常见的原因是波特率不匹配。STM32 的波特率是从 APB 时钟分频来的如果你的系统时钟不是标准值算出来的波特率会有误差。误差超过 3% 左右就会开始出现乱码。用外部晶振可以把这个误差降到很低内部 HSI 的话误差会大一些。丢包的问题更复杂。如果接收方处理不过来数据就会丢。用 DMA 接收加空闲中断可以缓解这个问题但如果数据量特别大还是需要加一个环形缓冲区。发送方这边如果两个数据包之间间隔太短接收方可能来不及处理。加一个帧间隔时间比如每帧之间等 10ms能解决大部分丢包问题。5.3 禁用 JTAG 保留 SWD 的正确操作STM32 的 PA13、PA14、PA15、PB3、PB4 这几个引脚默认是 JTAG 功能。如果你想把它们当普通 GPIO 用需要禁用 JTAG。但禁用的时候要注意不能把 SWD 也禁了否则下次就下载不了程序了。正确的做法是调用 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE)这个函数只禁用 JTAG保留 SWD。禁用之后 PA15、PB3、PB4 就可以当普通 GPIO 用了。但 PA13 和 PA14 还是 SWD 的 SWDIO 和 SWCLK不能动。注意如果你不小心把 SWD 也禁了别慌。把 BOOT0 拉高让芯片从系统存储器启动然后用串口下载一个新的程序进去把 SWJ 配置改回来就行。5.4 Flash 下载失败的排查链路“load … project.axf error: flash download failed” 这个报错我遇到过很多次原因也各不相同。排查的时候按这个顺序来先确认调试器连接正常在 Keil 的 Debug 设置里点一下连接测试然后检查 Flash 算法是否选对不同型号的 STM32 对应的 Flash 算法不一样再看芯片是否被读保护了如果读保护开了需要先解除保护才能下载最后检查供电是否稳定电压不够的时候下载也会失败。还有一种情况是芯片进入了低功耗模式调试器连不上。这时候需要把 BOOT0 拉高复位后再连接然后擦除芯片恢复正常模式。6. 代码组织与工程管理的一些个人习惯6.1 标准库工程的目录结构我自己的标准库工程一般会分成这几个目录CMSIS 放内核相关的文件Startup 放启动文件Library 放标准库驱动Hardware 放自己写的外设驱动User 放主函数和业务逻辑Doc 放文档和笔记。每个目录下再按功能分子目录比如 Hardware 下面有 LED、Key、Usart、Timer 等。这样组织的好处是移植的时候很方便。换一个同系列的芯片只需要替换 CMSIS 和 Startup 里的文件Library 和 Hardware 基本不用动。如果换到不同系列比如从 F1 换到 F4Library 要换Hardware 里的寄存器操作可能要改但 User 层的业务逻辑基本可以保留。6.2 用宏定义做条件编译做项目的时候经常需要在不同硬件版本之间切换或者需要打开关闭某些调试功能。用宏定义做条件编译是最方便的方式。比如定义一个 DEBUG_ENABLE 宏打开的时候串口打印调试信息关闭的时候不打印。再定义一个 BOARD_V1 和 BOARD_V2根据不同的板子版本编译不同的引脚定义。这些宏定义放在一个统一的头文件里比如 config.h所有源文件都包含它。这样改配置的时候只需要改一个地方不用满工程找。6.3 版本管理与代码备份STM32 的工程文件很多尤其是用 CubeMX 生成的工程每次重新生成都会覆盖一些文件。用 Git 做版本管理的时候要把自动生成的文件和手动修改的文件分开。我的做法是把 CubeMX 生成的代码放在一个目录自己写的代码放在另一个目录CubeMX 重新生成的时候只覆盖它自己的目录不会影响我的代码。备份也很重要。我见过太多人因为硬盘坏了或者误删了工程目录几个月的代码全没了。除了 Git 远程仓库我还会定期把整个工程打包存到网盘或者移动硬盘里。花几分钟做备份能省掉几天的重写时间。7. 从理论到项目给不同阶段开发者的建议7.1 新手最容易走的弯路新手最常见的问题是一上来就想做复杂的项目比如智能小车或者四轴飞行器结果卡在某个外设配置上挫败感很强。我的建议是从点灯开始然后按键控制灯然后串口打印然后定时器中断然后 PWM 调光然后 ADC 采集然后串口 DMA一步一步来。每个外设单独跑通再组合起来。另一个弯路是只看视频不动手。看视频的时候觉得都懂了自己写的时候发现连工程都建不起来。嵌入式是个动手的活看十遍不如自己写一遍。哪怕是把例程抄一遍抄的过程中也会遇到各种问题解决这些问题才是真正学到东西的时候。7.2 中级开发者如何突破瓶颈做过几个项目之后很多人会觉得自己什么都会一点但什么都不精。这时候需要选一个方向深入下去。比如你对电机控制感兴趣就深入研究 FOC把 Clarke 变换、Park 变换、SVPWM 的数学推导搞清楚自己写一遍代码。或者你对通信感兴趣就研究 EtherCAT、CANopen、Modbus 这些协议把协议栈的源码读一遍。读数据手册和参考手册也是突破瓶颈的关键。很多人只看中文教程不看原版手册。中文资料虽然好理解但翻译质量参差不齐有些关键参数翻译错了会误导人。养成看英文原版手册的习惯遇到不懂的术语查一下慢慢就习惯了。7.3 毕业设计选题的一些思路基于 STM32 的毕业设计每年都有大量学生在做选题的时候要注意几点一是要有一定的技术含量不能只是把几个模块拼在一起二是要有实际应用场景不能为了做而做三是要有可展示的成果答辩的时候能演示。比较受欢迎的选题方向有智能家居控制、健康监测设备、工业数据采集、电机控制系统、物联网终端。选的时候结合自己的兴趣和实验室的条件如果实验室有电机和驱动器做电机控制就比较好如果有传感器和无线模块做物联网方向就合适。提示毕业设计不要贪大求全把一个点做深比做十个点都浅尝辄止要好。比如做智能台灯就把光照传感器、人体感应、调光算法、手机控制这几个点做扎实比堆一堆用不上的功能强。7.4 代码开发工具的新选择除了 Keil 和 CubeIDE现在也有一些新的工具可以尝试。比如 VS Code 加 PlatformIO 插件可以跨平台开发 STM32代码补全和调试体验都不错。还有开源的 OpenOCD 配合 GDB 做调试虽然配置麻烦一点但灵活性很高。如果你用 ST-Link 调试ST-Link Utility 这个工具值得装一个。它可以独立于 IDE 烧录和读取芯片还能查看 Flash 内容、修改选项字节。有时候 IDE 连不上芯片用 ST-Link Utility 却能连上可以用来排查是 IDE 配置问题还是硬件问题。8. 写在最后的一些零散经验做 STM32 开发这些年我觉得最重要的不是记住多少寄存器而是建立起一套自己的调试方法论。遇到问题的时候先判断是硬件问题还是软件问题然后逐步缩小范围。示波器、逻辑分析仪、万用表这些工具要会用很多时候看一眼波形比读一百行代码都管用。还有就是要养成看数据手册的习惯。STM32 的参考手册有一千多页不需要从头看到尾但用到哪个外设就去看对应的章节。手册里有很多细节是教程里不会讲的比如某个寄存器的某个位在特定模式下才有意义这些细节往往就是解决问题的关键。最后说一个我自己的小习惯每做一个项目我都会在代码里写一个 README 文件记录这个项目的硬件连接、引脚分配、关键配置和遇到的问题。过几个月再回头看这个项目或者别人接手这个项目的时候这个 README 能省很多时间。好记性不如烂笔头这话在嵌入式开发里特别对。
返回列表