拿到一块新开发板,第一反应别急着插线,先把“使用流程”这条主线想清楚。我玩过的板子从ESP32、STM32到imx6ull、T113、Zynq,踩过的坑比写过的代码还多,其中最深刻的体会是:开发板并不难,难的是你永远在“某个环节之间”出问题——不是硬件烧了,不是代码错了,而是环境、工具、编码、启动介质这些“夹缝”里的坑没填上。这篇文章就把我这些年跑开发板的完整流程摊开讲,从选型、硬件认知、环境搭建,到烧录、调试、外设对接,再到中文乱码这类恶心人的问题,一条线走完,适合刚入门的同学,也适合被某个环节卡住的老手对照排查。
1. 拿到开发板之后,先别急着接线:选型与硬件认知
很多人的第一块开发板是跟着教程买的,但教程不会告诉你为什么选这块板子。开发板的本质是一个“最小可用的硬件验证平台”,选型决定你后面三个月的工作量。
1.1 不同芯片方案的定位差异,别用MCU的思路玩MPU
开发板圈子最容易被忽略的一件事,是MCU和MPU的差别。ESP32、STM32、ESP8266这些属于MCU,跑的是裸机或RTOS,资源有限但实时性好;imx6ull、T113、瑞芯微RK3506、Radxa Rock 5B+这些属于MPU,跑的是完整Linux系统,可以挂文件系统、跑应用进程、做网络服务。两者的使用流程完全不一样。
以热词里出现的imx6ull为例,这是NXP的Cortex-A7核心,定位是入门级Linux板卡,类似正点原子、粤嵌的很多板子都用它;T113是全志的异构双核方案,常出现在国产工业控制板里;Zynq7100和axu15egp系列则是带FPGA逻辑的异构SoC,难度直接上一个台阶。我的建议是:如果你只是想学Linux应用开发,优先选imx6ull或T113这类资料全、社区活跃的板子;如果你要做图像采集、硬件加速类项目,再上Zynq或UltraScale+;如果只是做物联网节点、智能硬件原型,ESP32S3这类MCU反而更合适。
各平台定位差异参考这个表:
| 芯片/开发板 | 核心架构 | 典型定位 | 使用门槛 |
|---|---|---|---|
| STM32F407 | Cortex-M4 | 裸机/RTOS,工业控制 | 低 |
| ESP32/ESP32S3 | Xtensa/RISC-V | IoT联网、低功耗 | 低 |
| ESP8266 | Xtensa | WiFi透传、简单控制 | 极低 |
| imx6ull | Cortex-A7 | 入门级Linux | 中 |
| T113 | Cortex-A7双核 | 低成本Linux/裸机 | 中 |
| RK3506 | 多核ARM | 工控/Edge AI | 中 |
| Radxa Rock 5B+ | RK3588 | 高性能Linux/边缘计算 | 中高 |
| Zynq7100/axu15egp | ARM+FPGA | 异构计算、高速数据采集 | 高 |
1.2 硬件资源清单与启动方式,先把板子“认全”
选好板子后,第一步不是看原理图,而是对照板子的硬件资源清单,从上到下过一遍:核心芯片型号、内存大小、存储介质(SD卡 / eMMC / QSPI Flash)、调试接口(串口 / JTAG / SWD)、外设接口(GPIO、I2C、SPI、UART、USB、HDMI、MIPI-CSI)、板载器件(LED、按键、音频Codec、屏幕接口)。
这一步极其重要。就拿ESP32S3开发板来说,它板载了USB转串口芯片、RGB LED、Boot按键和复位按键;但很多人不知道,ESP32S3的USB口可以原生模拟串口,直接插数据线就能烧录,根本不需要额外接USB-TTL。这个特性在它的硬件原理图里写得很清楚,就看你看不看。
再往后是启动方式。Linux类开发板的启动顺序通常是:拨码开关或电阻配置决定从SD卡启动、eMMC启动还是网络启动。我见过太多人把系统烧进SD卡却发现板子没反应,最后发现是拨码开关还停留在eMMC启动档位。拿到板子先看丝印上的“BOOT”或“SW”提示,确认当前启动介质,再去烧镜像。
另外一个容易被忽略的细节是:保存好原理图PDF和芯片数据手册。不要求你全看懂,但遇到引脚冲突、外设初始化失败时,这两个文件是你的救命稻草。ESP32的原理图里会标明每个引脚的复用功能,Zynq的原理图则能让你确认PS端MIO和PL端IO的分配,后面调起来才有的放矢。
2. 主机端环境搭建:VSCode、串口和文件传输
开发板的使用流程里,主机端环境比板子本身更容易卡住。很多新手在开发板上写代码,却用Windows记事本编辑、再用U盘拷过去,这个流程不是不行,而是太低效。正确做法是把PC和开发板连成一套开发环境。
2.1 用VSCode连接开发板的三种路径,按板型选
VSCode连接开发板这个话题,在热词里出现频率极高。实际场景中无非三种路径,对应不同板型:
第一种是Remote-SSH,适合跑Linux系统的开发板(imx6ull、T113、Radxa等)。在VSCode里安装Remote-SSH插件,配置好开发板的IP和用户名,就能直接在Windows/Mac上编辑板内代码,终端也一并接管。这里有个小技巧:开发板用网线直连电脑时,手动给电脑的有线网卡配一个和板子同网段的静态IP(比如板子是192.168.1.10,电脑就配192.168.1.2),SSH连接要比接路由器稳定得多。
第二种是串口监视器功能,适合MCU类板子。ESP32、STM32这类板子在调试阶段最常见的输出途径是串口,VSCode里有Serial Monitor、PlatformIO的串口终端可以直接读取,不用再单独开一个串口工具。但要注意,VSCode的串口插件Win10、Win11下偶尔会占不到端口,这种情况要么重启软件,要么用系统设备管理器确认驱动是否正常。
第三种是配合厂商IDE的方式,比如ESP-IDF在VSCode里有专门插件,Zynq的Vitis也基于Eclipse但可以设置外部编辑器。这种情况下,VSCode主要承担写代码的角色,编译烧录还是在厂商工具链里做。
2.2 开发板挂载Ubuntu:NFS与文件互传的真实用途
热词里有一条“开发板挂载ubuntu”,这个操作的真实场景并不神秘:你在PC上的Ubuntu虚拟机或物理机里交叉编译好了程序,不想每次都用U盘或TF卡拷到开发板,那就用网络把开发板的某个目录挂载到Ubuntu上,或者反过来把Ubuntu的目录共享给开发板。
比较常用的是在开发板上挂载Ubuntu的NFS共享目录。拿imx6ull举例:在Ubuntu里安装nfs-kernel-server,编辑/etc/exports加入一行,指定要共享的目录和允许访问的IP段,然后重启NFS服务;开发板端用mount -t nfs -o nolock :/共享目录 /mnt/nfs就能直接访问。这样做的好处是,编译产物直接落在共享目录里,板子运行时就等同于访问本地文件,省去了反复传输。
反过来,如果只是偶尔传几个小文件,用scp或rsync就够。scp的语法类似cp,但要把目标写成用户@主机:路径的形式。这里有个常见坑:Ubuntu的防火墙默认可能拦NFS端口,mount的时候报错“Protocol not supported”或“Connection timed out”,先执行sudo ufw disable试试,确认是防火墙问题后再改规则。
2.3 串口工具选型与连接注意事项,编码问题从这里埋下
串口是开发板调试的生命线,但这根线经常因为工具选错而“短路”。HyperTerminal早就不行了,国产的SSCOM、XCOM能用但界面老旧,SecureCRT收费,MobaxTerm是个不错的免费选择——它把串口、SSH、SFTP、X11转发整合在一起,一个工具管完开发板的所有远程需求。
热词里提到“imx6ull开发板在屏幕终端中文显示乱码,但是在MobaxTerm可以显示中文”,这个现象背后的本质是编码问题,不是工具问题。开发板的屏幕终端(比如fbterm或Qt应用)如果默认字符编码不是UTF-8,而你的中文字符串又是UTF-8编码,必然乱码;MobaxTerm默认按UTF-8解码,所以正常。这个问题我放在第4章专门说,这里先记一个结论:所有涉及中文显示的地方,先确认编码统一为UTF-8。
串口连接本身的注意事项也很关键:地线必须共地,TXD/RXD要交叉连接,波特率要匹配(常见115200或921600),这三点缺一不可。很多ESP8266和STM32通信不上,八成是TXD和RXD接反了,或者两边的GND没连在一起。
3. 从零跑通一块开发板的标准流程
选好板子、环境搭好之后,进入核心环节:按顺序走完“烧录系统 → 启动验证 → 交叉编译 → 运行程序”这条主线。不同芯片的具体命令不同,但思路完全一致,按这个框架走,换任何板子都能快速上手。
3.1 确认启动介质与镜像烧录方式,别把镜像烧错地方
开发板的“系统镜像”分为两类:一类是MCU的固件(bin/hex),通过串口或调试器直接写入Flash;另一类是MPU的系统镜像(bootloader+kernel+rootfs),写入SD卡或eMMC。这两类的烧录流程完全不同。
MCU类,以ESP32为例:用esptool.py或ESP-IDF的idf.py flash命令烧录,idf.py flash自动检测串口并写入引导程序、分区表和应用程序。ESP32S3需要注意,它有板载USB转串口直连和原生USB两种模式,烧录前确认设备管理器里的端口号,烧录时如果提示“Could not open port”,多半是端口被其他程序占了,或者驱动没装好。
MPU类,以T113和imx6ull为例:一般用balenaEtcher或厂商专用工具把完整镜像写入SD卡。这里有一个核心概念:SD卡被烧录后,整个卡会被划分为boot分区和rootfs分区,Windows下看起来可能是“无法访问”的盘,这是正常的,别去格式化。烧录完成后插入板卡,上电,观察串口日志是否正常打印。如果串口完全没有输出,先检查波特率、TX/RX接线、启动介质拨码三个地方,八成是这三者之一出了问题。
3.2 交叉编译与工具链选择,搞懂“在PC上编译板子的程序”
交叉编译是Linux开发板使用流程里最大的分水岭,很多人在这里被劝退。通俗地说,开发板的CPU架构和PC不同(PC一般是x86_64,板子是ARM或RISC-V),在PC上直接用gcc编出来的程序,板子跑不了。必须用“交叉编译工具链”——一套运行在PC上、但生成板子可执行文件的编译器。
拿ARM Linux开发板来说,常见的工具链是gcc-arm-linux-gnueabihf或aarch64-linux-gnu-gcc。安装后,编译一个C程序只需要把gcc换成arm-linux-gnueabihf-gcc,再指定一下架构选项。比如:
arm-linux-gnueabihf-gcc -march=armv7-a -mfpu=neon -mfloat-abi=hard -o hello hello.c这里选了ARMv7架构、NEON SIMD指令集、硬浮点ABI,如果你板子的SoC支持这些特性,性能会明显优于保守参数。编译完用file命令查看产物架构:
file hello如果你看到“ELF 32-bit LSB executable, ARM, EABI5”,说明交叉编译成功。实操中我建议大家用Makefile或CMake把工具链前缀抽象出来,避免每次手动敲一长串参数。对于imx6ull,工具链前缀是arm-linux-gnueabihf-;对于aarch64的Radxa Rock 5B+,需要前缀aarch64-linux-gnu-;对于T113的RISC-V核,则是riscv64-unknown-linux-gnu-,千万别混用。
3.3 第一个程序的三种跑法,由易到难逐步深入
跑通第一个程序是建立信心的关键,我的建议是由易到难分三步走,每一步都能看到结果。
第一步是脚本验证。登录开发板系统后,写一个最简单的shell脚本:
#!/bin/sh echo "hello from dev board"加执行权限直接跑。这一步主要验证SSH或串口登录是否正常、文件系统是否可写。
第二步是交叉编译C程序。在PC上写好hello.c,用上面的交叉编译命令编出ARM版本,再用scp传到板上执行。这时你会体会到“交叉编译”的真正意义。踩坑提示:如果你的程序用了动态库,板子上必须存在对应的.so库文件;避免动态库依赖的方法是加-static静态编译,但会导致体积变大,建议只在测试时用。
第三步是写一个简单的外设驱动或内核模块,这是Linux开发板的进阶必备技能。一个最简单的内核模块只需要两个函数:
#include <linux/module.h> #include <linux/kernel.h> static int __init hello_init(void) { printk(KERN_INFO "module loaded\n"); return 0; } static void __exit hello_exit(void) { printk(KERN_INFO "module unloaded\n"); } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE("GPL");用板子配套的内核源码和交叉工具链编译出.ko文件,insmod加载,dmesg查看输出。这一步的意义在于,之后你要操作GPIO、I2C等外设时,底层逻辑和这个“Hello World”模块是一样的。
4. 终端中文乱码问题根治,别再靠运气显示中文
热词里有一条特别有意思:“imx6ull开发板在屏幕终端中文显示乱码,但是在MobaxTerm可以显示中文”。这个问题非常有代表性,开发板的中文显示问题几乎人人都会遇到,但很多教程只给一句“设置编码为UTF-8”,治标不治本。
4.1 乱码根源:字符编码不统一,跟工具无关
首先明确:乱码的本质不是板子“坏了”,而是编码不一致。中文在计算机里常见的编码有UTF-8、GBK、GB2312;开发板的Linux系统默认语言环境(locale)一般是英文,也就是LANG=C或LANG=en_US.UTF-8;而你的中文字符串如果是以GBK编码保存的,在UTF-8的终端里显示就会变成“锟斤拷”之类的乱码。
为什么同一个板子在MobaxTerm正常?因为MobaxTerm默认按UTF-8解码串口数据,你的程序或系统输出了UTF-8编码的中文,自然正常。而屏幕终端(比如开发板自带的LCD终端、fbterm、或接的HDMI显示器里的终端)可能运行在C locale或非UTF-8编码下,同一个UTF-8字节流就被错误解析成了拉丁字符。
确认当前locale的方法:
echo $LANG locale如果输出不是zh_CN.UTF-8或en_US.UTF-8,就说明终端环境没有正确配置UTF-8。
再深挖一层,中文文件名的乱码和文件内容的乱码,成因也不同。文件内容乱码是编码解码不匹配;文件名乱码是文件系统挂载时没有指定iocharset或nls=utf8。比如U盘或SD卡以vfat格式挂载时,如果挂载参数里没有加iocharset=utf8,中文文件名大面积乱码。
4.2 实战排查与修复:让开发板真正支持中文
第一步,安装中文字体。Linux系统的字符显示依赖字体包,如果系统里根本没有中文字体,再怎么设置编码也显示不出方框里的汉字。以imx6ull的buildroot系统为例,确保编译配置里包含fontconfig、freetype和一款中文字体(如文泉驿微米黑)。如果系统已经跑起来,可以用以下命令安装:
apt-get install fonts-wqy-microhei或
opkg install fontconfig第二步,设置locale为UTF-8。编辑/etc/profile或~/.bashrc,加入:
export LANG=zh_CN.UTF-8 export LC_ALL=zh_CN.UTF-8但这里有条经验要提醒:不要把LANG直接改到/etc/profile后立刻重启,因为很多精简的板载系统没有生成zh_CN.UTF-8的locale数据,设置后反而会报“Cannot set LC_CTYPE to default locale”一类的错误。正确做法是先确认系统支持:
locale -a有zh_CN.utf8才执行export,没有就只设LANG=en_US.UTF-8,保证UTF-8编码输出。
第三步,如果是屏幕终端(fbterm)乱码而串口正常,重点看fbterm是否加载了中文字体:
fbterm -s 24 -- font-height=24或在~/.fbtermrc里设置font-names=mono, WenQuanYi Micro Hei。fbset和fbterm的配置细节各家板子略有不同,但核心思路都是:fbterm只负责显示,字体和编码由配置决定。
4.3 中文问题的三种场景速查表
| 场景 | 现象 | 根本原因 | 修复方向 |
|---|---|---|---|
| 串口终端中文乱码 | 显示“锟斤拷” | 程序输出编码与终端解码不一致 | 统一为UTF-8,检查LANG |
| 屏幕终端中文乱码 | 显示方块或问号 | 缺少中文字体或fbterm无字体配置 | 安装字体、配置fbterm |
| 文件名中文乱码 | ls看到\xxx\xxx转义 | vfat挂载参数缺iocharset | 挂载加iocharset=utf8 |
顺便说一个嵌入式开发里非常普遍的现象:程序里写死了中文字符串,编译时源文件是GBK编码,但交叉编译器默认按UTF-8处理字符串字面量,导致最终输出乱码。这种问题在VSCode里很容易被忽略,因为VSCode默认按UTF-8读取文件,你看到的源文件是正常的,一编译就露馅。我的建议是:所有源码文件统一保存为UTF-8,文件头可以加一句注释提醒。
5. 外设通信与音频类开发板常见坑
开发板的价值在于它外设丰富。不同板子的外设差异很大,但当你看过足够多的方案之后会发现:外设通信的通用坑就那么几个,电平不匹配、时钟配置不对、寄存器配置错误。
5.1 ESP8266与STM32通信,电平、波特率、共地三座大山
ESP8266和STM32的组合很长一段时间是物联网原型开发的主流配置,ESP8266负责WiFi透传,STM32负责业务逻辑。两者的通信方式一般是UART,看起来简单,实际通关的人不多,主要有三个坑。
第一个坑是电平不匹配。STM32的UART引脚一般是3.3V TTL电平,ESP8266也是3.3V——听起来很匹配,但如果你的STM32核心板上有5V引脚控制或者用了5V供电,一旦串口线接到5V电平的引脚,ESP8266大概率烧掉。我建议查清楚各自的数据手册,尽量用3.3V电平的UART口对接,GND一定先连。
第二个坑是波特率,或者更准确地说,是“波特率余量”。两边默认配置都是115200,但如果两边晶振精度不同(尤其是ESP8266某些模组用内部RC振荡器),实际波特率可能偏移,偶尔出现首个字节乱码。解决办法是使用ESP8266的AT固件里比较宽容的波特率,或者把两边的UART配置改为带奇偶校验,提高容错。
第三个坑是共地。如果两边用两个独立电源供电,却没有接GND,串口通信的参考电平就是悬空的,现象是“偶尔能收到、一操作就死”。串口通信的GND必须连在一起,这是从模拟电路到数字电路都不会变的第一原则。
如果是ESP32与STM32通信,思路一样,但ESP32的UART引脚在Arduino环境下默认是GPIO1/GPIO3,需要确认你用的开发板有没有板载USB转串口把它占用了,避免引脚冲突。
5.2 音频Codec调试:WM8978与STM32F407的协作实例
粤嵌STM32F407ZET6开发板带WM8978音频Codec,这是一个I2S接口的音频芯片,调起来比通信接口复杂,因为音频既有关键的时序信号(MCLK、BCLK、LRCLK),又有控制信号(I2C配置寄存器)。
调试WM8978的第一步,不是写驱动,而是确认I2S的MCLK是否正常。很多开发板的音频方案里,MCLK由STM32的PLL或者外部晶振提供,如果MCLK频率不对,Codec内部时钟就乱,输出就是刺耳的噪音。用示波器量MCLK引脚是最可靠的验证方式,没有示波器也可以试着播放正弦波测试音频,如果频率不对,输出音调会明显偏高或偏低。
第二步是I2C寄存器配置。WM8978的寄存器地址是7位,数据也是7位,需要参考数据手册一张一张写。这里最容易被忽略的是寄存器2的“输出设备使能”和寄存器3的“输入设备使能”,如果没开这两项,可能有I2S数据但耳机没声音。另一个常见坑是软件音量寄存器默认值是0,需要显式设置,否则输出静音。
第三步是I2S的引脚映射。STM32F407的I2S与SPI复用引脚,需要开启SPI时钟,并复用为I2S功能。很多人把I2S初始化写好了,但忘记开启GPIO时钟和AFIO复用时钟,结果数据根本没送出去。这块建议直接参考粤嵌的例程或STM32CubeMX生成的初始化代码,先跑通厂家demo,再改自己的逻辑。
5.3 从入门板到高端板:Radxa、泰山派、瑞芯微与Zynq的调试套路
热词里出现了Radxa Rock 5B+、泰山派、瑞芯微RK3506、Zynq7100、axu15egp这些板子。它们的级别不同,但调试思路一脉相承。
Radxa Rock 5B+用的是RK3588,8核ARM,性能接近PC。它的上手测试比较标准:烧录官方固件到eMMC模块或用SD卡启动,开机后用htop查看CPU频率、用glmark2之类工具测试GPU性能。这类板子最大的特点是“像PC”,SSH进去之后你几乎忘了自己用的是开发板,但需要注意散热——RK3588满载能到很烫手的程度,被动散热片不够的话,跑编译任务会降频。
泰山派(T113相关的国产板卡)资料和课程比较齐全,学习路径适合初学者,跟着官方课程走就行。这类板卡的坑主要在工具链版本和驱动编译上,用官方提供的SDK一键编译环境能省掉大量配置时间。
瑞芯微RK3506的板卡,比如合众恒跃的,多见于工业场景。调试时重点看它的工业接口(CAN、RS485、GPIO扩展)在Linux下的设备树支持情况。设备树里一个status = “okay”写着disabled,外设就不工作,排查时需要学会搜dmesg和/sys/class下的节点。
Zynq7100和axu15egp这类ARM+FPGA的板卡,调试套路完全不同。除了Linux侧,你需要配置PL(可编程逻辑)侧的FPGA逻辑,再用AXI总线把PL外设映射到PS(ARM)侧。第一次跑这类板子,建议先烧官方硬件例程,用Vivado生成bitstream,再用PetaLinux生成内核和根文件系统,确认PS和PL能通信之后,再开始定制逻辑。很多人直接把别人的FPGA工程下载下去,发现设备树里找不到IP核,多半是PL侧的地址映射和设备树描述不一致。
6. 资料管理与问题排查实录,让开发板用得更顺
最后的章节,我把自己实操里沉淀下来的资料管理习惯和排查套路分享出来。开发板使用流程的终点不是“跑通”,而是“形成一套可持续复用的工作流”,这样你换哪块板子都不慌。
6.1 建立板卡档案,别把所有资料堆桌面
我见过太多人的桌面堆满了“正点原子imx6ull资料”“ESP32S3原理图”“泰山派课件”,要用的时候找半天。建立板卡档案是一个非常值得养成的好习惯。每块开发板单独建一个目录,目录下至少维护这几项:官方资料索引(原理图、数据手册、SDK下载链接和版本)、环境配置记录(交叉编译工具链路径、串口参数、烧录命令)、踩坑日志(日期+问题+解决方法)、常用命令备忘(烧录、挂载NFS、启停服务)。
这份档案的威力在几个月后换新板子时最能体现。比如你调过imx6ull的NFS挂载,换到T113时只需要对比两份环境配置记录的差异,几分钟就能搞定,而不是重新搜一遍教程。
6.2 通用排查流程:从“现象到根因”的五步法
开发板出问题时,最忌讳的是“乱试”。我总结出一套五步排查法,每一步都有明确目的。
第一步是确认硬件基础状态:板子供电电压是否正常、核心芯片是否发烫、关键指示灯状态、串口是否输出启动日志。如果串口没有日志,问题大概率在引导阶段,优先排查启动介质和波特率。
第二步是确认软件是否在跑:Linux系统使用top或htop看进程,MCU使用打印日志看程序是否进入main函数前的初始化卡死。开发板的常见陷阱是“启动日志正常但应用没起来”,因为systemd服务或init脚本失败,要在系统日志里找原因。
第三步是确认网络连接:如果SSH连不上、NFS挂载失败,先ping一下,再检查网段、网关、防火墙。开发板直连电脑时最容易出问题的是电脑开了WiFi导致有线网卡没有自动获取到同网段IP。
第四步是确认配置一致性:设备树里的外设是否打开、内核驱动是否编译进镜像、工具链版本与内核版本是否匹配。这几个环节不匹配的表现非常隐蔽,比如“GPIO操作没反应”“I2C设备找不到”,但dmesg里通常会有明确的报错线索。
第五步是回退验证:把你改过的配置或者代码回退到上一个已知正常的版本,看看问题是否消失。这一步能快速判断问题是不是自己改动的,特别是在设备树和内核配置调试中非常有效。
6.3 经验小结:别迷信教程,别忽略异常信号
开发板的学习曲线并不可怕,真正消耗时间的往往是“教程假设你的环境和它一致,但你的环境总有差异”。所以不要盲目复制粘贴,要理解每条命令的作用、每个配置项的含义,再用上面的排查流程去适配自己的环境。
还有一点比较重要:异常信号不要忽略。比如上电时某个LED比教程里暗一点、某次启动日志比平时慢了2秒、风扇转速异常——这些早期异常如果能被注意到,往往能避免后面的“重大故障”。我在调Radxa Rock 5B+时就遇到过类似情况,电源指示灯比正常暗,结果过两天出现随机死机,最后排查发现是电源适配器功率不够。
我做每一块开发板项目,最后都会把“踩坑日志”更新到板卡档案里。几个月后回头看,你会发现自己犯的错误高度重复,而这个日志就是你避开重复犯错的最有力的工具。