☰
STM32开发避坑指南:从环境搭建到调试器与串口通信高频问题排查
2026/9/27 11:02:06 网站建设 项目流程

第一次拿到 STM32 开发板,大概率是兴奋的。点亮一颗 LED、跑个串口打印,那种成就感能让你动力满满。但接下来的一周,你可能会陷入"下载失败—连不上调试器—代码烧进去没反应—查了半天发现是配置错了"的循环里。作为一个从 F103C8T6 摸到 F407、再到 H743 的老玩家,我这些年踩过的坑,不少都是网上资料讲一半、文档里找不到、论坛帖子早就沉底的老问题。这篇文章就把这些高频坑整理成一份可以直接对照排查的避坑清单,覆盖环境搭建、烧录下载、调试器使用、串口通信、定时器应用,还有工程规范。适合正在做课程设计、毕业设计,或者刚开始用 STM32 做产品的读者参考。

1. 开发环境与工程模板:第一道隐形门槛

1.1 Keil5 同时兼容 C51 和 STM32:不是装上就完事

很多人电脑里会同时装 Keil C51 和 Keil MDK,因为课程设计可能同时涉及 51 单片机和 STM32。这时候最容易踩的坑是:安装顺序不讲究,导致双击 STM32 工程时 Keil 打不开,或者打开之后找不到芯片。

正确做法是:先装 MDK(也就是 Keil uVision5),再装 C51 支持包。如果装反了,或者你已经无法确定顺序,最简单的处理办法是去 Keil 官网下载对应的 C51 安装包,直接安装,安装程序会检测到现有 uVision5 并自动集成。装完后打开两边的工程都正常,不要两个版本分开装两套 IDE,那样维护起来很麻烦。

另外,STM32 芯片能在 Keil 里被识别,依赖的是芯片支持包(Device Family Pack)。MDK 安装目录下默认只有少量器件包,你需要单独下载 STM32 系列对应的 Pack。最常见的现场是:打开一个别人发给你的工程,Keil 提示Device/Software Pack not installed,然后你在 Pack Installer 里找半天也找不到对应型号,或者下载速度极慢。

1.2 芯片包装不上时的排查路径

Pack 装不上,大部分原因是网络问题。官方 Pack Installer 联网下载经常卡住,这时候我建议直接去 ST 官网或者 Keil 官网手动下载.pack文件,然后双击导入。.pack本质是一个压缩包,双击后会调用 Pack Installer 自动安装,你也可以用解压软件解开后手动放到 Keil 的ARM/PACK目录下,不过不推荐手动解压,因为会漏掉一些索引信息。

还有一个小细节:Keil 5.23 和 5.39 对 Pack 版本的兼容性完全不同。老版本 MDK 打不开新 Pack,新版本 MDK 又可能不认老工程里的某些器件型号。如果翻看旧项目,建议把 MDK 升级到 5.36 以上,基本能兼容绝大多数 STM32 老工程。新项目我目前都用 5.39,稳定,没遇到什么奇怪问题。

注意:如果你看到的是Error: Device not found之类的提示,先检查 Pack 是否真的装上了,可以在Project - Manage - Pack Installer里搜到芯片型号并看到绿色勾,才算就绪。

1.3 标准库和 HAL 库怎么选,新建工程的模板坑

这是个老生常谈但永远有人纠结的问题。我的建议分两个场景:如果你是做课设或毕设,需要用代码细节展示学习成果的,用标准库或者直接操作寄存器,代码更透明,也更方便答辩时讲原理;如果你是开发实际产品、追求项目进度和维护效率,用 HAL 库。HAL 库的封装层很高,但配合 CubeMX 初始化代码,调试串口、I2C、SPI 这些外设确实快得飞起。但要注意,用 HAL 库有一个明显的痛点:库函数跳转深、封装层级多,Debug 时单步跟踪很痛苦,建议配合数据手册直接对照寄存器状态来排查,不要死磕代码跳转。

新建工程模板的坑,几乎每个新手都踩过:

  • 启动文件选择错误:STM32F103 有大容量(HD)、中容量(MD)、小容量(LD)之分,启动文件startup_stm32f10x_hd.s、startup_stm32f10x_md.s不能乱选,选错会导致中断向量错位,代码跑飞但你完全找不到原因。

  • SystemInit 没有被调用:标准库工程的系统时钟初始化就在SystemInit()里,如果漏掉,芯片会跑在 8MHz 内部时钟,你配置了 72MHz 的外设频率,一切就全乱了。

  • 魔术棒 Target 页的晶振频率没填对:这里填的 Xtal 值会影响调试器的时钟配置。实际板子 8MHz 晶振,这里填了 25MHz,下载后程序波特率、定时时长全错。

  • 头文件路径没加全:编译报各种No such file or directory,核心就是 Include Paths 里少了标准库的底层目录。

三者叠加,就是新手最典型的"工程能编译、板子不干活"之谜。

2. 烧录下载连环报错:连接问题先从硬件查起

2.1 下载器连接失败的常见原因

"No target connected" 大概是 STM32 玩家遇到最多的报错。很多人第一反应是驱动问题或者代码问题,但实际上,八成以上是物理连接问题。当时的典型排查顺序是:

  1. USB 识别是否正常:设备管理器里能不能看到STM32 STLink或者ST-Link Debug设备。如果看不到,换 USB 口、换线、重装驱动,按这个顺序来。

  2. 接线是否正确:SWD 只需要 4 根线——SWDIO、SWCLK、GND、VCC(即 3V3),个别老版本板子还要接 NRST。杜邦线接错位置是最常见的低级错误,尤其是 SWDIO 和 SWCLK 很容易接反,接反的典型现象是下载器和芯片之间握手不稳定,报错信息飘忽不定。

  3. 目标板供电是否正常:ST-Link 输出 3.3V 的电流有限,给整个板子供电时如果电流需求稍大,电压就会被拉偏,导致握手失败。排查办法很简单:单独给板子供电,ST-Link 只接 SWDIO、SWCLK、GND,不接 VCC。

  4. 目标电压检测问题:ST-Link 需要通过 VCC 引脚检测目标板电压,一些 ST-Link 在检测不到目标电压时直接拒绝输出调试时钟。如果板子单独供电,记得把 SWD 排线的 VCC 引脚也接上,否则部分 L 型仿真器会报错。

  5. 线材质量问题:杜邦线太长或用劣质线,SWD 时钟频率较高时波形劣化,握手不稳。工业场景下建议直接用 2.54mm 的排线,长度控制在 10cm 以内。

以上五步检查完,90% 的连接问题都能解决。

2.2 "Error: Flash Download failed" 报错的完整排查链路

这种报错比 "No target connected" 更进一步,说明调试器已经连上了芯片,但写入 Flash 失败。典型的现场是:

load "D:\\stm32 prohect\\2-1 stm32工程模板\\Objects\\project.axf" error: Flash Download failed - "Cortex-M3"

哪怕你把工程路径、文件名摆正了,它还是报。这个报错背后通常是这几类原因:

  • Flash 编程算法选错:在魔术棒Utilities - Settings - Flash Download里,你需要选择正确的编程算法,比如 STM32F103C8T6 是STM32F10x Med-density Flash 64K,如果你的工程配置用的是 High-density 64K,就没法和芯片匹配。类似地,F1 系列 128K 和 256K 擦写地址也不一样,选错必报错。

  • 下载地址越界:如果你改过下载起始地址,比如做 BootLoader 时把 IROM 起始地址改到 0x08008000,但复位向量和中断向量表配置没跟上,下载可能成功,但程序一跑就飞。这个不算下载失败,但表现类似。真正的下载地址越界是 Flash 容量不够,算法检查后直接拒绝。

  • 芯片处于读保护状态:芯片选项字节被设置了 RDP 保护,单纯下载会提示失败。这时用 ST-Link Utility 执行Target - Erase Chip,或者先用Option Bytes把 Read Protection 设置为 Disabled。很多"板子买回来第一次烧就报错"的情况,其实是二手板子带着别人的读保护设置。

2.3 ST-Link Utility 的使用时机与固件升级

很多人装完 Keil 和 ST-Link 驱动就直接用,不知道还有 ST-Link Utility 这个工具。它最实用的场景有两个:

第一,验证物理连接是否正常。用Connect按钮读一下芯片 ID,比如 F103 会显示STM32F10x M3 0x411,确认通信链路没问题,问题就锁定在 Keil 配置而不是硬件。

第二,批量擦除或者解除保护。Keil 里擦除失败时,Utility 的Full Chip Erase成功率要高得多,因为它绕开了 Keil 的 Flash 算法逻辑,直接走 ST 官方协议。

另外,ST-Link 硬件本身有固件版本。老版本 ST-Link(红色外壳那种)在 Keil 5.30 以上可能提示固件过旧,建议用 ST-Link Utility 里的Firmware Update升级。升级过程不能断电,否则变砖。现在新版的 ST-Link V2 一般出厂固件就比较新,但如果你是从抽屉里翻出来的古董货,这一步还是得做。

3. 调试器下一步一步跟:Debug 模式的隐藏陷阱

3.1 禁用 JTAG 后连不上调试器:SWD 复用冲突

想把 JTAG 的引脚释放出来当普通 GPIO 用,这是很多做过正经项目的开发者都会做的事。但这里有个知名大坑:一旦代码里执行了GPIO_Remap_SWJ_Disable,下一次下载时调试器就彻底连不上芯片了。原因是这个函数把 SWD 的调试引脚也一并释放了,SWDIO 和 SWCLK 变成了普通 GPIO,调试器自然无法继续访问内核。

你可能会想:把板子复位一下,重新下载?没用,因为已有的代码上电后又会立刻执行禁用操作,调试器无法抢先连接。

这个坑的解法有三个:

  1. 在代码里不要用GPIO_Remap_SWJ_Disable,只用GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE),这个宏只禁用 JTAG,保留了 SWD 引脚功能。

  2. 如果已经踩进去了,用 ST-Link Utility 的Connect under reset功能:按住板子的复位键,点击连接,在连接成功的瞬间松开复位键。这样可以在芯片执行用户代码前抓住内核。

  3. 如果没有复位键,需要短接 BOOT0 到 3.3V 并重新上电,让芯片从系统存储器(BootLoader)启动,此时用户代码不会执行,调试器就能连上了。连上之后擦除 Flash,再恢复 BOOT0,问题解决。

这个坑我建议用解法 2 的变体作为首选:在 Keil 的 Debug 设置里勾选Reset and Run,同时启用Debug under reset mode,大部分情况下能直接避开。

提示:Debug 模式下如果发现断点无效、程序跑飞,优先怀疑时钟树或 Flash 等待周期配置,而不是代码逻辑问题。H743 这类高频芯片尤其容易出现因 Flash 延迟周期不够导致的随机复位。

3.2 延时函数 delay 卡死:时钟配置与 SysTick 的双重陷阱

delay()卡死,是另一个高频到让人无语的问题。表面现象是程序跑着跑着,在延时函数里出不来了。

我总结过最常见的三类原因:

  • SysTick 没配好:标准库中延迟函数通常依赖SysTick,如果你在初始化里把 SysTick 关了,或者滴答中断优先级设置得高于某个正在执行的任务,中断嵌套会导致延时逻辑错乱。典型的特征是:延时几十毫秒变成几分钟,最后干脆死锁。

  • 时钟频率和实际不符:这是更大的隐藏坑。你的板子用 8MHz 晶振,代码却按 72MHz 配置了 PLL,延时函数的节拍计算全部按 72MHz 来,而实际 SysTick 时钟源头如果是从 AHB 分频来的,数值就会完全对不上。表现是延时时间严重拉长,看起来就像卡死了。

  • 看门狗捣乱:如果开了 IWDG 且没有及时喂狗,延时函数运行时间过长,超过了看门狗溢出时间,芯片反复复位,在调试界面里看起来就是"运行到 delay 卡住"。实际上芯片早就复位重跑了,只是断点位置恰好总在延时函数附近。

排查这三类问题,建议直接在延时函数里加一个 GPIO 翻转,用示波器或者逻辑分析仪观察周期。看不到工具的话,可以在 Debug 界面里手动修改寄存器值,先改小 SysTick 重装载值,看程序行为是否有变化,这是最直接的验证手段。

3.3 看门狗、低功耗模式打断调试的典型场景

Debug 模式下最令人崩溃的事情是:全速跑没问题,单步跟踪就复位。这通常是看门狗在起作用。因为你在断点停住时,CPU 暂停了,但看门狗外设仍然在跑,一旦溢出就复位。

解法很经典:利用 Cortex-M 内核的调试冻结功能。在 Keil Debug 设置或代码里配置 DBGMCU 控制寄存器,让时钟在 CPU 停止时也停止。标准库中的DBGMCU_Config(DBGMCU_WWDG_STOP | DBGMCU_IWDG_STOP, ENABLE)可以把独立看门狗和窗口看门狗在调试模式下冻结。启动文件之后尽早调用这行代码,Debug 时的世界就清净了。

低功耗模式也有类似的问题。单片机进入STOP或STANDBY模式后,调试器同样会脱连。有些人会觉得芯片坏了,其实是内核时钟被低功耗逻辑关掉了。解决办法是,在调试阶段先把低功耗相关代码打注释掉,业务逻辑稳定后再加回来。掉了的坑,能少踩一个是一个。

4. 串口通信乱码与虚拟串口的实战排障

4.1 串口乱码:不起眼的时钟配置是根源

串口输出的乱码,第一反应永远不要是检查代码里的波特率寄存器,而是先确认时钟树。我见过一个很有意思的案例:两块一模一样的板子,一块乱码,一块正常,最后发现是正常那块经过了校准,而乱码那块外部晶振虚焊,导致实际频率偏了。

STM32 串口波特率的计算公式是Baud = Fck / (16 * (UARTDIV)),Fck 是外设时钟。如果你的 Fck 按 36MHz(APB1 最高频率)配置,但实际上 PCLK1 是 42MHz 或 8MHz,那算出来的波特率自然是错的。排查路径是:

  1. 在系统时钟初始化后,读RCC->CFGR和RCC->CR确认 PLL 配置,确保HSEON、PLLON标志位置位。

  2. 核对外部晶振频率。很多核心板的晶振是 8MHz,但也有 25MHz 的版本。代码模板里写的是 8MHz,装到 25MHz 板子上,UART 分频计算直接翻三倍,乱码没跑了。

  3. 用一个已知波特率的 USB-TTL 模块回环测试,排除对端工具问题。

乱码还有一个隐蔽来源:GPIO 复用配置错误。USART1 的 TX 是 PA9,RX 是 PA10,如果你复用推挽配置没开对,TX 输出阻抗异常,数据线波形变差,一样会导致误码率上升,这类问题用示波器看 TX 引脚电平转换就能立刻确定。

4.2 USB 虚拟串口收发数据:驱动与缓冲逻辑

做上位机通信时,用 STM32 的 USB 虚拟串口(VCP)非常方便,省掉了外部 USB-TTL 芯片。但它的坑也不少。

首先是驱动。ST 官方的 VCP 驱动在 Windows 上偶尔安装不干净,导致设备管理器里显示黄色感叹号。解决办法是去 ST 官网下载最新的STM32 Virtual COM Port Driver,右键更新驱动时手动指定到驱动目录。这个坑不大,但很磨人。

其次是收发缓冲。HAL 库的CDC_Receive_FS回调接收的数据长度不稳定,因为 USB CDC 是包传输,一包数据可能是 1 字节也可能是 64 字节。如果你按"收到一次回调就是一条完整消息"来设计协议,早晚出问题。正确思路是:把 USB 接收的数据放入一个环形缓冲区,主循环里按帧头、帧尾或者固定长度拆包解析。

发送方向的坑也常见:CDC_Transmit_FS是异步发送,如果你在发送函数返回后立刻修改了缓冲区内容,实际发送的数据可能已经被破坏了。严谨的写法是等报告状态返回USBD_OK后再回收缓冲区,或者干脆用双缓冲方案。

4.3 波特率误差计算与常见板载 CH340 坑

串口还有一个很容易被忽略的工程点:波特率误差。以 115200 为例,如果系统时钟不是标准的整数倍,分频结果会有误差,超过 2% 就很可能在长报文传输时出错。

STM32F103 的 USART 分频寄存器支持小数部分,但 HAL 库和标准库都可能因为特殊的 PCLK 频率(比如 45MHz 而非 36MHz)计算出不理想的分频值。建议实际验证一下:让单片机发送 1000 个字节的循环数据,上位机完整校验,确认无误码再定波特率。

市面上的 USB-TTL 模块的坑也不小。CH340 基本是默认选择,但旧的 CH340 驱动在 Win10/Win11 上容易失灵,表现是识别为USB-Serial但打开即报错。解决办法是装新版驱动,CH340 的驱动目前官方一直在更新,或者选择 CP2102 芯片的模块作备选。另外注意 CH340 模块上的 TTL 电平是 3.3V 还是 5V,有些模块上标了 5V/3.3V 跳线,接错轻则通信乱码,重则损坏引脚。

5. 定时器与测距测频:外设应用最容易出错的三个方面

5.1 定时器模式的配置:PWM、捕获、编码器别搞混

STM32 定时器是功能最丰富也最容易混淆的外设。一个 TIM2 可以有四个通道,每个通道都能独立工作在输入捕获、输出比较、PWM 输出等模式。如果你把通道 1 配成 PWM 输出,通道 2 配成输入捕获,又要求两路同步,就很容易踩进模式冲突的坑。

我的经验是:在配置定时器之前,先在纸上画一下信号流——时钟源从哪里来,预分频后到计数器,比较器到引脚,引脚到复用功能。这个步骤花两分钟,能省下两小时调试时间。

PWM 模式下常见的坑是频率对但占空比不对,这通常是ARR和CCR的关系没理清。PWM 频率由ARR决定,占空比由CCR决定。如果设置 CCR 大于 ARR,输出就是 100% 高电平;如果 CCR 为 0,输出就是 0%。很多人调发现电机全速转、PWM 波形是一条直线,就是这俩寄存器关系搞反了。

输入捕获和输出比较在数据结构上的差异也容易让人蒙圈。输入捕获是读取计数器快照,你要先配置边沿检测;输出比较是设置一个目标值,到点产生中断或翻转电平。两者虽然共用比较寄存器,但工作逻辑完全不同。

5.2 捕获测频率与超声波测距的实现细节

用输入捕获测频率是 STM32 的基本操作,但很多人第一次测出来的数完全不对。问题通常出在低频信号溢出上。

具体场景:测一个 50Hz 的方波信号,捕获周期是 20ms。如果你的定时器计数频率是 72MHz,且没有设置预分频,计数器的 16 位(或 32 位)范围可能完全不够用,计数器在捕获前就发生了溢出回绕,算出来的时间就一团糟。

正确的做法是:

  1. 根据被测信号的最低频率,先确定是否要开预分频,保证一个信号周期内计数器不溢出。
  2. 开定时器溢出中断,在中断里维护一个全局变量记录溢出次数。
  3. 捕获中断里用"总计数 = 当前捕获值 + 溢出次数 × 自动重装载值"来还原真实时间。

超声波测距(HC-SR04)也踩过类似的坑。HC-SR04 要求向 Trig 引脚发送一个 10us 以上的高电平触发,然后用定时器捕获 Echo 引脚回波高电平的宽度,距离 = 高电平时间 × 声速 / 2。

新手经常出现两个问题:一是放着定时器捕获不用,而是用delay写阻塞式采集,程序在等回波期间什么都做不了;二是 Trig 脉冲宽度不够,模块根本没被触发,回波永远不来,程序就卡死在等待里。

我推荐的方案是非阻塞测距:TIM 捕获 Echo 上升沿和下降沿,上升沿进入捕获中断记录起始时间,下降沿进入捕获中断计算差值。主循环里定期查询"是否有新的测距结果"标志位,这样即使声波超时未回,也不影响其他任务运行。

顺带提醒一下:HC-SR04 的回波引脚输出 5V 电平,如果 STM32 是 3.3V 系统,需要加电阻分压或电平转换,直接接在 PA 口上时间久了容易损伤引脚。

5.3 按键电路设计与编码器接线的防抖意识

按键模块电路设计这个热词下,最常见的坑不是按键功能本身,而是上下拉电阻的选择导致按键电平逻辑不稳。STM32 内部虽然有上拉/下拉电阻配置,但外部电路还是建议加一个 10k 上拉电阻,并用 100nF 电容做 RC 滤波。纯靠软件延时消抖的写法,在高温、电源噪声大的环境下会出现误触。

我实际项目中用的消抖方案是状态机加定时扫描:每隔 10ms 扫描一次按键,连续两次读到相同状态才确认电平有效。这种思路比delay(20ms)消抖优雅得多,因为在扫描期间 CPU 还可以去做别的事。

编码器方面,正交编码器的 A/B 相接入 STM32 定时器的编码器模式后,计数器会在编码器旋转时自动增减,方向由 A/B 相相位差决定。接线时最容易犯的错是 A、B 两相接反,导致电机正转计数反而减小。

这个问题的解法有两个:一是在初始化时通过读取当前计数器的增减方向来判断相序是否正确;二是直接在电机上电后手动转一圈,看计数值是否和实际方向一致。如果反了,把 A、B 对调即可,不用改代码。另一个细节是要开启编码器的滤波功能,防止电机振动产生毛刺计数。

6. 进阶开发的工程化思维:把调试时间花在刀刃上

6.1 串口打印与日志分级:最早建立的调试手段

调试 STM32 有很多方式:LED 翻转、逻辑分析仪、示波器、断点单步。但对于复杂逻辑,最有效率的手段还是串口日志。只要板子上有一个空闲的 UART 口,我建议第一时间把它变成调试串口。

重定向printf到串口,是第一步。标准库的方式是重写fputc,HAL 库则可以直接用HAL_UART_Transmit封装。但纯用printf有个问题:中断和主循环同时打印时,日志会互相穿插,导致可读性极差。

我后来改用简单的日志分级宏,类似LOG_DEBUG、LOG_WARN、LOG_ERROR,配合一个全局调试等级开关。这样量产阶段可以直接关闭 DEBUG 级别日志,保留错误输出,不用重新修改一堆打印代码。日志格式上,建议统一带上时间戳和函数名,定位问题快得多。

6.2 从 VSCode 到 Opencode:代码编辑环境的演进

这几年 VSCode 配合 C/C++ 插件开发 STM32 工程已经很流行了,尤其是用 EIDE 或 PlatformIO 这类扩展管理编译和烧录。VSCode 的最大优势是代码补全、跳转、格式化比 Keil 自带编辑器好用太多。但还是那个问题:最终连接硬件调试时,很多人还是切回 Keil。因为 VSCode 里做 Cortex-M 调试需要配置 OpenOCD 或者 CORTEX-Debug,门槛并不低。

最近比较热的 Opencode 这类 AI 辅助编码工具,也开始有人尝试用于 STM32 代码开发。我的观点是:这类工具对生成初始化代码、外设驱动骨架、解释寄存器位域定义非常高效,但涉及具体硬件时序、中断优先级设计、电源管理等问题时,AI 给出的方案还是要动手验证。毕竟 STM32 应用场景千差万别,单靠"相对合理的标准写法"并不总能保证能在你的板子上一次跑通。

从 Keil 转到 VSCode 后,我最大的体会是:把代码编辑和编译调试分离。Keil 作为编译和烧录的"后端",VSCode 作为写代码的"前端",中间用一个自动化脚本同步文件。这种工作流一开始配置有点麻烦,但稳定之后,开发效率明显提高。

6.3 几个提高效率的习惯:示波器、逻辑分析仪、版本管理

踩坑到最后,真正帮你节省时间的是趁手的工具和规范。硬件的三条建议:

  1. 示波器:如果只让推荐一件工具,就是示波器。查时钟波形、串口波形、PWM 频率全都靠它。入门并不需要多贵,二手示波器或几百元的便携示波器都够用。

  2. 逻辑分析仪:调试 I2C、SPI、CAN 这类协议时,逻辑分析仪配合上位机解码,关键是能抓到信号时序细节,比如 ACK 位、帧间隔、位冲突,这种信息纯靠肉眼看示波器波形很难判断。

  3. Git:STM32 工程的产物很大,编译生成的 .axf、.hex 文档不需要提交,但源码、工程配置文件、原理图版本一定要纳入版本管理。我自己经历过"新功能加完,老功能全挂,回退又找不到之前能跑的版本"的窘境,后面硬是把 Git 用了起来,才结束这种噩梦。

写代码层的三条建议:

  1. 模块分层:驱动层(GPIO/UART/定时器)、中间层(协议解析、数据缓存)、应用层(业务逻辑)分开,调试时直接屏蔽某层,定位速度快很多。

  2. 使用断言和错误返回:HAL 库很多函数会返回状态,但你往往会忽略返回值。强烈建议对所有初始化和关键传输函数做错误检查,把问题暴露在初始阶段,而不是等到程序跑飞了才回头查。

  3. 维护一份自己的踩坑笔记:无论是什么奇怪的问题,解决后花三分钟记录下来。这类经验在下一次遇到同类不报错但效果不对的情况时,能直接照着排查。

我个人的习惯是,每个工程都建一个doc/bugs.md,按模块分类记录踩过的坑和解决办法,比去论坛搜帖子靠谱得多。这次的总结,也算是这份笔记的一次公开整理。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询