资讯动态

STM32控制板整体结构详解:从最小系统到外设调试

发布时间:2026/10/7 2:04:15 来源:尧图企业网站定制
拿到第一块STM32控制板多数人的第一个动作是把卖家给的例程烧进去看LED闪灯。闪完灯之后通常有两种走向一种是觉得“我已经会了”然后从OLED、舵机、超声波一路往外接最后卡在某个模块上另一种是把板子翻来覆去看了半天除了芯片型号和几个引脚名不知道下一步该干什么。我见过不少新手把HC-SR04的ECHO直接怼到3.3V引脚上也见过有人贪方便用板上的3V3给一个额定电流超过1A的舵机供电结果一上电板子反复复位、屏幕花掉。这些问题几乎都指向一件事没有先把一块STM32控制板的整体结构看明白。这篇文章不打算带你调某个具体外设而是把一块板子从头到尾拆开讲一遍从电源、时钟、复位、调试口到芯片内部的总线、外设、中断再到软件工程的结构。把这些看明白后面不管做超声波测距、LCD屏、舵机还是一个简单的物联网网关遇到问题至少知道该查哪一层而不是全网搜一个“跟我的症状一样”的代码来碰运气。1. 先看硬件最小系统与外设分别是什么角色1.1 最小系统不是玄学电源、时钟、复位、调试口一块STM32控制板不管多复杂真正的核心其实是“最小系统”。所谓最小系统就是指能让芯片跑起来所必需的几样东西电源、时钟、复位和调试接口。这四个东西有一个不对程序烧进去都不会有正常反应。很多人拿到板子先看外设、先看屏幕这是本末倒置。试想一下如果芯片供电不稳、时钟没起振、复位信号一直被拉低那么GPIO配置得再漂亮也输出不了正确的电平。顺着最小系统往下看每一块板子的设计都是以这个为基础的。先说电源。常见的STM32开发板一般有一个5V输入可以是USB的5V也可以是从排针单独引进来的5V接着经过一颗LDO变成3.3V给芯片供电。芯片的电源引脚并不只是一个VDD和GND通常还有VDDA、VSSA以及VREF等模拟电源引脚用于ADC等模拟外设。如果板子没有额外处理芯片的模拟电源和数字电源会直接连在一起并加小电容去耦。自己画板时要特别注意模拟电路区的地要尽量靠近VDDA回流数字电源杂波会直接影响ADC采样值。这不只是教科书上的理论我实测过同样的ADC通道电源去耦做得好的板子和随意飞线搭的板子数据跳动幅度能差出好几个LSB。再说时钟。STM32内部有HSI高速内部RC和HSE高速外部晶振。HSI的精度在工厂校准后也不如外部晶振稳定尤其在需要跑串口波特率、USB、CAN这类对时间敏感的通信时偏差会直接变成误码。多数开发板上会有一颗8MHz或者25MHz的晶振作为HSE再通过芯片内部的PLL倍频到系统时钟比如F103系列常见的72MHz。板上的这颗晶振周围会有两个小电容用来匹配负载电容。如果晶振松了、虚焊系统时钟可能跑偏甚至停振。你可以把HSI比作一个“大概准”的闹钟把HSE加PLL比作一个校过时的电子钟误差完全不是一个量级。复位和调试口也属于最小系统的一部分。复位引脚NRST一般接一个上拉电阻和一只电容到地实现上电自动复位和外部按键复位。调试口上现在的开发板几乎都支持SWD只需要SWDIO、SWCLK、GND三条线有的还接NRST用于烧录时的复位控制。相比JTAG要占十几个引脚SWD只占两个引脚这对小封装板子非常重要。很多低价开发板和自制板子都只引出SWD接口所以你的第一个调试器最好支持SWD比如常见的ST-Link、DAP-Link或者某些用CMSIS-DAP方案的调试器。第一次使用前确认接线方向SWDIO和SWCLK不要接反否则调试器常常报“找不到目标芯片”。1.2 引脚地图GPIO、复用功能与启动选择最小系统解决的是“芯片能跑”的问题而板子上真正被反复用到的是GPIO。GPIO全称叫通用输入输出听名字好像就是简单的读电平、写电平但在STM32里每个引脚可以配置成很多模式输入、输出、复用功能、模拟。输入还能选择浮空、上拉、下拉输出可以选择推挽或开漏速度等级也有不同。新手最容易忽略的是“复用功能”这四个字。当一个引脚要作为串口TX、定时器通道、SPI时钟或者I2C数据线使用时它并不只是一个普通IO而是被连接到内部对应的外设上需要先把引脚模式设成复用功能再选择正确的AF编号。以最常见的STM32F103C8T6为例LQFP48封装一共有37个IO其中PA13、PA14、PA15、PB3、PB4默认被JTAG调试接口占用。如果你想把PA15当作普通GPIO输出必须在程序里先禁用JTAG否则这个引脚的信号会被调试逻辑干扰输出电平很可能不是你想要的结果。很多人照着网上的引脚配置写了代码却发现某几个引脚“不听话”原因往往在这里。操作很简单比如在旧标准库里有GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE)在HAL库中就要先调用__HAL_AFIO_REMAP_SWJ_NOJTAG()等函数。但前提是你得知道这个坑的存在。BOOT0和BOOT1的选择也要了解。BOOT0和BOOT1的组合决定了芯片从哪个区域启动一般开发板上有一颗BOOT0跳线默认拉低从主Flash启动正常跑用户程序拉高时再从系统存储器启动配合串口ISP下载。这块板子如果想完全复用BOOT0引脚不行BOOT0是可以复用为普通功能的但需要配置。不要随意把BOOT0接到高电平后上电否则程序不会从Flash跑。注意这里说的禁用JTAG要确认你确实不需要通过JTAG在线调试了再做否则会影响调试器的连接和断点功能。建议拿到板子后第一件事不是看原理图的某个外设部分而是把芯片的引脚定义图打印出来或者贴在桌上。对照自己的板子把电源、地、复位、BOOT、SWD、晶振引脚圈出来再看开发板上还有哪些外设接在哪些引脚上。这个动作花不了半小时但能让你之后少查几百次手册。芯片厂商的官方数据手册里都有引脚图网上的开发板原理图也找得到按上面标的网络名去对应就行。2. 芯片内部的“路网”总线、时钟树与外设的关系2.1 从AHB到APB外设时钟从哪里来硬件上最小系统没问题下一步要面对软件初始化中让人头大的部分为什么我要用某个外设还得先开启它的时钟这不是软件工程师故意折腾人而是芯片内部确实存在一套“供电和通信的路网”。STM32内部有AHB总线、APB1总线和APB2总线。CPU通过AHB访问存储器和DMAAHB又通过桥接器延伸到APB1和APB2各种外设就挂在不同的总线上。每个外设的时钟默认是关闭的为了省电。你要使用USART1就要让RCCReset and Clock Control先把USART1的时钟打开否则寄存器写进去根本没有反应。外设挂在哪条总线直接决定它的时钟频率和配置方式。拿F103来说USART1、SPI1、TIM1、ADC1/2/3挂在APB2时钟最大72MHzUSART2/3、SPI2、I2C1/2、TIM2/3/4等挂在APB1时钟最大36MHz。如果你把APB1的预分频设置为2那么APB1上的定时器时钟会自动变成36MHz的2倍也就是72MHz。这是很多人不理解的地方APB1限制36MHz为什么定时器却能吃到72MHz时钟因为定时器有专门的倍频逻辑。在CubeMX里你可以看到时钟树配置界面中的实际频率但建议你手动算一遍系统时钟→AHB预分频→APBx预分频→定时器倍频这个链条不搞清楚写PWM或输入捕获时会发现频率差了一倍。另一个常见误区是开启外设时钟不等于这个外设就能用还要配置引脚复用和中断。有次我调试SPI读传感器明明SPI时钟已经开了初始化函数也调了但始终读不到数据。最后发现SPI1的NSS引脚被我占用作普通IO影响了片选时序还有一个更常见的问题是只开了外设时钟没有使能外设的中断向量导致中断标志置位但CPU没有反应。所以养成一个习惯拿到一段例程先看它调用了哪些RCC相关函数再看GPIO初始化再看外设初始化最后看中断配置。这四步就是绝大多数外设初始化的骨架。2.2 NVIC与调试组件中断如何进CPUSWD不只是下载用外设数据准备好了怎么通知CPU来处理这就是中断控制器NVIC的工作。STM32有一个专门管理中断的单元叫做NVIC它可以根据外设产生的中断请求决定是否打断当前任务以及中断之间的优先级关系。优先级分抢占优先级和子优先级这两者的数量可以通过优先级分组来调整。比如设置分组2那么2位作为抢占优先级、2位作为子优先级。对于实时性要求高的应用抢占优先级高的中断可以打断低优先级的处理但如果两个中断抢占优先级相同则子优先级高的不能打断同级只能排队等当前中断处理结束。初学者喜欢把所有中断都设成一样的优先级结果碰上两个同时发生的中断程序行为变得难以解释。更严重的是如果你在某个高优先级中断里用阻塞方式等一个低优先级中断置位会发生死锁这就是“delay卡死”的一种常见原因。比如你在UART中断里调用HAL_Delay而HAL_Delay依赖SysTick中断如果SysTick的优先级比UART中断低那么UART中断会一直占着CPUSysTick永远进不来程序就卡死在延时函数里。所以中断服务函数里尽量少用阻塞延时多用标志位和状态机。调试组件是另一个被低估的结构。SWD接口除了下载程序还能用来做实时调试支持在Keil或VSCode的调试视图里看变量、打断点。部分调试器还支持SWO引脚可以输出一条ITM跟踪流用不到额外串口就能打日志。还有更简单的SysTick定时器除了做时间基准也可以用来做精确延时和任务调度。如果你要做第一块控制板的调试环境我建议把Serial Wire ViewerSWV或至少一个串口打印预留出来。遇到程序卡住先在中断里加一个GPIO翻转测一下或者串口打印一条“我到这里了”比对着代码发呆高效得多。3. 第一次上电应该先观察哪些关键点3.1 从原理图开始找电源、地、复位、Boot、LED和跳线当你终于拿到一块新板子先别急着插USB。第一件事是打开卖家或开源社区提供的原理图把上面的网络名扫一遍。找几个关键节点5V输入、3V3输出、GND、NRST、BOOT0、SWDIO、SWCLK、板载LED。很多开发板的引脚旁边会标注功能复用比如xx引脚默认接I2C_SCL、SPI_MISO、UART_TX。这些信息能帮助你判断为什么要用某个引脚以及能不能直接复用。如果找不到原理图就根据芯片型号下载官方数据手册并对照开发板上丝印。然后检查板子是否带电。用万用表测3V3对GND是否短路测5V输入接口的正负极有没有反再看板上的电源指示灯。上电后第一次量3V3正常应该在3.2到3.4V之间不同LDO略有差异。如果量到接近0V或者发热马上断电。不要觉得这一步多余我遇到过看起来全新的板子下面有一颗小电容已经脱落3V3实际上只有1.8V。芯片在这种情况下也能勉强工作但ADC和闪存读写可能随机出错。先测电压再烧程序这是每个工程师重复过无数次的操作。上电之后要做的第二件事是找到启动方式。看BOOT0和BOOT1默认怎么接大部分板子BOOT0拉低从主Flash启动这没问题。如果板上丝印写着BOOT、RST、3V3看清楚跳线方向。有些板子有USB供电和外接5V供电的选择跳线插错的话USB的5V会直接和外部电源打架。我有个朋友用一块板子同时接USB和外部电源看着没问题因为两个LDO都输出3.3V但一个稍微偏高一点就会从另一个LDO的体二极管倒灌长期下来板子老化特别快。所以上电前把跳线看明白尤其是有多个电源来源的控制板。接下来检查板载外设LED接在哪个引脚按键接在哪个引脚有没有板载ST-Link或USB转串口芯片。很多开发板上有一个可跳线断开默认外设的排针比如PA9、PA10默认接着USB转串口。如果你要用这两个引脚做其他事情得先断开跳线否则板载芯片会把信号拉走。这个细节容易被忽略导致你明明配置对了却发现串口数据收不到。具体做法因板而异但原理都是默认外设和你的外设共享引脚先隔离。3.2 供电方案和功耗误区控制板不是电源砖第一块控制板最常见的错误是把板上3V3当成万能电源接了一堆外设。以超声波测距模块HC-SR04为例模块的工作电流虽然不高但ECHO输出的是5V电平直接接到3.3V的STM32引脚上可能没事也可能长期损伤引脚因此需要用电阻分压或电平转换。而舵机就更明显一个小型9g舵机堵转时电流可能超过1A普通开发板上的LDO根本扛不住会造成芯片电压跌落、复位、程序跑飞。你用一块STM32控制板去直接带动舵机电源就像拿一个手机充电头去带动电钻不是不能转是转一会儿就出问题。正确的供电思路是分级。STM32芯片的3.3V只给控制逻辑、LED、传感器这类低功耗器件用舵机、电机、大功率执行器用独立的5V或更高电压电源并把外部电源的地和控制板的地连在一起也就是“共地”。共地非常重要串口、PWM、脉冲信号都以GND为参考如果控制板和舵机电源各有一套地信号会在两个地之间产生压差轻则读数抖动重则烧毁IO。如果控制板可以从USB或5V输入取电就要确认输入电流足够至少留出30%余量。对于5V舵机我一般习惯用一个外部5V 2A以上的电源在舵机电源引脚旁并联一个1000uF电解电容吸收启动浪涌。如果板子上还有电机驱动芯片或者高功率开关布线和电源策略就更讲究了。但这篇文章讨论的是小控制板记住一条就够了不要用3.3V去驱动任何“力气活”。控制信号从3.3V出功率和地线从外部电源走信号地和功率地单点连接。这样设计后后面再接电机驱动、舵机时返工的概率会小很多。我第一次做超声波小车时把电机驱动和STM32共用一个电源电机会一转单片机就死机最后发现是启动瞬间把电压拉到2.7V。后来换成独立电源并把电机驱动的地和控制板的地分开汇流问题才消失。4. 软件工程的整体结构从CubeMX到编译下载4.1 标准库、HAL库、LL库与寄存器不同抽象层次怎么选硬件结构看明白了软件结构也不能糊里糊涂。STM32的软件生态有好几套写法并存直接操作寄存器、标准外设库Standard Peripherals Library、HAL库、LL库。寄存器最底层一切寄存器操作一目了然但写起来慢不适合快速验证标准库已经停止更新但网上大量例程仍基于它以F1系列居多HAL库目前是官方主推用CubeMX可以自动生成工程代码可读性不错但有些地方封装得很厚一旦出错追起来麻烦LL库更接近寄存器效率高但官方例程较少。如果你是第一块板子我的建议是先用HAL库把功能跑通等到需要优化性能或真正搞懂底层时再回头对照LL库和寄存器去看。再说工具链。最经典的组合是Keil MDK STM32CubeMX HAL库很多课程和开发板都用这个资料最多。CubeMX能帮你配置时钟树、引脚功能、外设参数然后生成一个包含HAL库的工程你在生成的main.c里写逻辑。这个过程会用到芯片封装包比如Keil里需要安装对应的Device Family Pack否则新建工程时找不到芯片型号。如果你不喜欢Keil的编辑器和编译速度也可以用VSCode搭配EIDE插件或PlatformIO。PlatformIO里可以添加STM32F1/F4等平台配合Arduino框架或原生STM32框架都能用调试配置可以直接生成launch.json适合习惯vscode风格的人。不管选哪个工具链都是围绕同一个工程结构展开的。一个典型的STM32 HAL工程主要包含这些目录Core用来放主程序、中断入口和CubeMX生成的配置Drivers里是CMSIS内核头文件和对应的HAL驱动启动文件startup_stm32f10x_hd.s或者startup_stm32f411xe.s汇编文件它负责建立中断向量表、初始化堆栈并跳转到main链接脚本也就是后缀为.ld或.icf的文件定义了Flash和RAM的划分。很多新手看到一堆文件夹就慌但你要找的核心其实就几个main.c、stm32f1xx_hal_msp.c、stm32f1xx_it.c、.ld文件、启动文件。理解了每个文件的职责就算哪天编译器报一个undefined symbol你也能大体猜到是启动文件或链接脚本出了问题。4.2 主循环、中断与DMA代码框架怎么搭软件整体结构上不外乎三种执行方式轮询、中断和DMA。轮询就是主循环里不断查询某个标志比如循环里反复读ADC值和按键状态简单直观但CPU忙得没空处理别的事。中断就是外设事件主动打断CPU比如串口收到一个字节进入中断在中断里把数据搬走。DMA则是外设直接通过总线搬运数据到内存CPU只在开始和结束时参与。做第一块控制板时我的建议是先把轮询写熟再引入中断最后才考虑DMA。因为很多问题在轮询阶段就暴露得最清楚比如外设没初始化好、时钟没打开、引脚被占用这些不会因为用了中断和DMA就消失反而会更难排查。拿ADC为例。STM32的ADC经常需要切换通道你可以用扫描模式顺序转换多个通道然后通过ADC中断或DMA把结果搬出来。如果你看到网上有人说ADC切换通道时读到上一次的数据大概率是没有处理好转换启动标志或等待序列结束。正确做法是在每次启动转换前把通道选择设置好然后等待EOC标志或触发DMA搬运。也可以使用注入转换或者双重ADC等更高级的方式但第一块板子没必要上太复杂。先用轮询采集一路确认采样值稳定再扩展到多路扫描最后再用DMA减少CPU占用。这样一步一步扩展出问题能精确定位到是哪一层。另一个典型的例子是串口调试PID。你在控制板上跑一个PID调节系统需要不断把目标值、反馈值、输出量通过串口打到上位机上看曲线。如果串口发送用的是阻塞式的HAL_UART_Transmit并且每次发送都在主循环里等待那么PID周期会被拖慢。更合理的做法是把串口发送放到低优先级循环里或者用DMA发送接收则用空闲中断加DMA把不定长数据一次性收进来。如果习惯用printf打印把fputc重定向到串口即可但注意在HAL库中要处理超时和重入问题否则printf也会成为卡顿源。这种“主干在中断里、数据搬运在DMA里、界面在低速循环里”的思路其实就是整体结构的核心让合适的事情在合适的层级发生。第一块板子不一定要做到这么精细但你要在心里有这个结构图。5. 从整体结构出发两个常见外设的调试思路5.1 超声波测距用定时器输入捕获量回波宽度超声波模块是很多人第一个传感器。HC-SR04有两根控制线TRIG和ECHO。TRIG是输入你给它一个大于10微秒的高电平脉冲模块就会发出8个40kHz的超声波脉冲同时ECHO会输出一个高电平这个高电平的持续时间等于超声波从发射到遇到障碍物再反射回来的时间。距离等于高电平时长乘以声速除以2在常温下声速约340m/s所以时间每毫秒约对应17厘米的距离。这个测量过程如果只用delay延时去等CPU会一直阻塞而且精度随主循环的时序变化。更好的做法是用定时器输入捕获把ECHO接到定时器某个输入捕获引脚配置为上升沿和下降沿各捕获一次两次计数值之差乘上定时器分辨率就是高电平脉宽。接线时要注意电平匹配。HC-SR04的ECHO默认输出5V直接连接到STM32引脚可能有风险。我用过两种处理方式一是用两个电阻做分压把5V拉低到3.3V左右但响应慢一点二是在ECHO和引脚之间串一个1kΩ电阻配合引脚内部上拉利用寄生二极管钳位这样在很多场合能用但不太保险。更稳妥的是用一个电平转换芯片或模块。对于第一块控制板我建议老老实实用分压电阻哪怕多占一个引脚也好过哪天芯片IO损坏。另外如果模块放在遮挡物前面测量结果会跳变这是正常的不要以为是代码问题。注意HC-SR04的ECHO输出是5V最好分压后再进STM32尤其是长期运行或批量制作时不要赌引脚不会坏。在代码结构上可以这样布置TRIG引脚用普通GPIO输出初始化时拉低定时器用来输入捕获配置好上升沿和下降沿两个捕获通道主循环里每隔100ms发一次触发脉冲然后查询一个“测量完成”标志。把测量逻辑放到状态机里主循环就不至于被占死。这个方案既用到了GPIO、定时器、输入捕获也涉及中断和标志位正好把前面讲的总线、时钟和NVIC全部串起来。很多网上的例子都用delay阻塞来实现你能做个跑通的东西以后再改成捕获方式会对整体结构理解更深刻。5.2 SPI屏ILI9341读ID读成a1a1先查时序和读取功能SPI彩屏是另一个能把你折磨一周的外设。很多人调ILI9341时第一步读ID就是想确认屏幕驱动正常。常见的做法是发送读ID命令例如0xD3然后连续读三个字节前两个字节预期是0x93和0x41。结果读回来往往是0xA1、0xA1或者干脆全0xFF。这个a1a1不是真的ID它说明屏的数据线上有信号但不是有效ID数据。出现这种情况先不要怀疑屏坏了要按顺序查几件事接线是否把MISO正确连到MCU的SPI_MISO引脚屏幕是否支持读操作SPI模式和时钟极性有没有配对初始化时序是否完整。我踩过的坑是屏幕模块只引出了MOSI和SCK没有MISO那根本读不到任何数据只能直接初始化显示。有些屏幕虽然引出了MISO但驱动IC的读命令需要先把显示模块从睡眠模式Sleep Out唤醒来才能正确返回ID否则MISO端只会返回某个固定字节。还有一个非常典型的问题SPI配置成了模式0而ILI9341实际工作方式可能是模式0或模式3取决于模块设计。SCK空闲电平不对时数据位会错位读到的东西就变得莫名其妙。所以排查时先用示波器或逻辑分析仪看SCK和MOSI的波形确认命令发送完整再怀疑芯片本身。整体结构思维在这里很有用。屏幕挂在SPI总线上SPI外设挂在某个APB总线上SPI引脚可能和别的功能复用。如果你之前在同一个引脚上初始化过其他外设或者CubeMX里的引脚冲突检查没有报警最后代码运行顺序也可能影响状态。我建议把LCD初始化放在一个明确的初始化函数里在main函数中先初始化时钟、再配置引脚复用、然后配置SPI、最后给屏幕复位脉冲等足够时间后再发初始化命令。读ID失败的时候可以把读ID代码放到屏幕刷色成功之后再测试因为有些屏驱动必须先完成初始化才能正确响应读命令。这是我从一个a1a1的下午里换回来的经验。6. 问题排查顺序与第一块板子的经验6.1 从看电源到看配置一套通用排查顺序最后整理一下我在各种论坛问题帖里最常见到的场景以及对应的排查方向。你可以把它当成一张速查表遇到问题先按这张表从上往下走一遍比盲目重刷代码有效得多。现象优先排查方向板子完全不工作先量3V3电压、NRST电压、BOOT0状态再看晶振有没有起振。没有示波器时用串口打印或LED翻转测试系统时钟是否运行程序下载不了确认调试器型号、连接线序、目标芯片供电再确认Keil或VSCode里的芯片型号和Flash算法最后看芯片读保护是否开启引脚没输出看GPIO配置是否包含时钟使能再看引脚复用冲突JTAG占用、板载外设占用最后看外部负载是否把电平拉低串口乱码确认双方波特率、时钟频率、晶振值一致再用逻辑分析仪看起始位、数据位、停止位是否正常ADC值跳动查模拟电源是否干净、通道切换是否稳定、转换时间是否太短再用一个已知电压做校验CAN突然连不上看总线电平CAN_H和CAN_L之间约2.5V核对波特率配置最后检查收发器供电和终端电阻这些问题都有一个共同点底层结构没检查之前上层代码改一百次也没用。之前我在一个CAN通信项目里天天调软件滤波后来才发现是总线终端电阻没接信号反射导致错误帧结构问题不解决代码只能“猜谜”。6.2 我推荐的第一块控制板入门路线文章最后以我个人带过很多新人的经验收尾。第一块STM32控制板不要用来做毕业设计级别的“大系统”它更适合用来建立一种感觉芯片靠什么跑起来、外设怎么和芯片对话、程序在芯片里是什么流程。建议按这样的顺序走第一步点灯同时用万用表量LED引脚的电压和电流理解输出高低的本质。第二步用串口打印“Hello”连接上位机观察收发理解波特率和电平。第三步用外部按键配合中断配合NVIC配置观察中断如何打断主循环。第四步用定时器输出PWM调占空比控制LED亮度或舵机角度。第五步用ADC采集一个电位器电压和PWM结合起来做一个可调亮度灯。第六步再上SPI屏和I2C传感器体验总线读写。这个路线看起来平淡但它把整个控制板的核心结构覆盖了一遍最小系统、GPIO外设、时钟、NVIC、定时器、ADC、串行总线。做完这些之后再考虑接舵机、电机、超声波、FreeRTOS或者物联网网关你会发现自己已经具备排查问题的基本框架。不要一开始就在网上找一堆含一堆术语的源码来跑那不是学习是猜谜。最后再分享一个小技巧在板子上留一个空闲的LED和一个空闲的串口它们是你调试的“手电筒”。当程序不按预期跑时先用LED闪几次告诉我们它走到了哪段代码再用串口打印关键变量。这个习惯和看懂整体结构一样重要陪我解决过不知多少个“看起来随机发生”的bug。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑