ESP32-S3-LCD开发板实战:AIoT项目从硬件解析到AI模型部署

ESP32-S3-LCD开发板实战:AIoT项目从硬件解析到AI模型部署

1. 项目概述:一块能跑AI的“小屏幕”开发板

最近在捣鼓一些需要本地显示和智能交互的小玩意儿,比如智能家居中控、便携式数据监测仪,甚至是带点视觉识别功能的桌面摆件。这类项目对核心板的要求很明确:性能要足够跑一些轻量级模型,接口要丰富能接各种传感器,最关键的是,最好自带一块屏幕,省去外接的麻烦和布线困扰。市面上常见的ESP32开发板性能有限,而性能更强的树莓派Pico系列在显示和无线连接上又需要额外模块。就在这个当口,我注意到了这块ESP32-S3-LCD-1.47B开发板。

简单来说,这是一块基于乐鑫ESP32-S3芯片,并原生集成了一块1.47英寸LCD显示屏的开发板。光看这个组合,就知道它瞄准的是那些需要“显示+联网+算力”三位一体的嵌入式场景。ESP32-S3这颗双核Xtensa LX7处理器,主频高达240MHz,比经典的ESP32性能强了不少,更重要的是它支持向量指令扩展,这意味着在运行一些AI推理任务时,比如人脸检测、关键词唤醒,能有更好的效率。而板上那块1.47英寸的IPS屏幕,分辨率是172x320,显示效果细腻,直接通过SPI接口与主控通信,开发者无需再为屏幕的驱动和接线头疼。

我拿到这块板子后,第一感觉就是“集成度真高”。除了核心的MCU和屏幕,板载的元器件布局紧凑,包含了USB Type-C接口用于供电和编程、用户按键、RGB LED,甚至还预留了摄像头接口(DVP格式)。这几乎就是一个完整的微型智能终端原型。无论是想做一个能显示天气和通知的桌面时钟,还是一个通过摄像头识别物体并显示结果的小设备,这块板子都能提供一个非常不错的起点。接下来,我就结合自己的实际使用和调试经验,从开箱到跑通第一个AI例程,详细拆解一下这块板子的玩法和那些容易踩的坑。

2. 硬件深度解析:不只是“ESP32-S3加屏幕”

很多朋友第一眼看到这块板子,可能会觉得它就是个ESP32-S3核心板焊了块屏。但实际用下来,你会发现它的硬件设计有不少讲究,直接影响了开发体验和项目上限。

2.1 核心芯片ESP32-S3:性能与AI能力的基石

ESP32-S3是乐鑫在2021年推出的芯片,可以看作是ESP32系列的“性能增强版”。它采用双核Xtensa® LX7 CPU,主频最高240MHz,内置512KB SRAM,并支持外接PSRAM。对我而言,最吸引人的是以下三点:

第一,无线连接能力。它支持2.4GHz Wi-Fi 4和蓝牙5.0(包括LE Audio)。在做一个智能温湿度监测器时,我需要它同时作为Wi-Fi Station连接路由器上传数据,又作为蓝牙Beacon广播设备信息。ESP32-S3可以很好地处理这种并发无线任务,稳定性比旧款ESP32要好。

第二,AI加速指令集。芯片支持VEXT(向量扩展)指令。这是什么概念呢?比如我在板子上跑一个TensorFlow Lite Micro的轻量级人脸检测模型,在调用一些矩阵乘加运算时,使用VEXT指令的代码,其执行速度会比普通指令快上不少。虽然不能和专用的NPU相比,但对于在微控制器上进行简单的图像分类、语音识别,这个加速是实实在在能感受到的。

第三,丰富的IO与接口。ESP32-S3提供了多达45个可编程GPIO,支持SPI、I2C、I2S、UART、USB OTG、LCD接口、摄像头接口等。这块开发板充分利用了这些资源。例如,板载屏幕是通过SPI总线驱动的,而预留的摄像头接口则是8位DVP并行接口,可以方便地连接OV系列摄像头模组。

2.2 集成屏幕:1.47英寸IPS的细节与驱动

板载的这块1.47英寸LCD屏幕,型号通常是ST7789V或类似的驱动IC。它是IPS材质,视角广,色彩表现也比早期的TN屏好很多。分辨率172x320是个比较特别的长宽比,非常适合显示纵向列表信息,比如聊天记录、传感器读数列表等。

屏幕通过SPI与ESP32-S3通信。这里有一个硬件设计上的细节需要注意:为了节省GPIO并提高刷新速度,这块板子很可能使用了“8位并行SPI(又称“8线SPI”)”模式,而非标准的3线或4线SPI。在标准SPI中,我们只有一根数据线(MOSI)发送数据。而在8位并行模式下,会使用8根GPIO同时发送一个字节的8个位,理论上刷新速度可以提升8倍。这对于动态更新UI、播放简单动画至关重要。

在软件驱动层面,我们一般不需要直接操作底层SPI时序。乐鑫的ESP-IDF框架和Arduino核心库都提供了成熟的LCD驱动库,比如lvgl(Light and Versatile Graphics Library)就得到了非常好的支持。你只需要在工程配置中指定屏幕的型号、分辨率、引脚定义,库就会帮你处理好底层的通信。我的经验是,在ESP-IDF环境下,使用lvgl配合乐鑫官方的esp_lcd组件,是最稳定、功能最全的方案。

2.3 外围电路与扩展接口:为项目而生

除了核心和屏幕,板子上的其他部分也体现了“开箱即用”的设计思路:

  • USB Type-C接口:这不仅是供电口(5V),更是编程和串口调试口。芯片内置了USB Serial/JTAG控制器,意味着你只需要一根USB-C数据线,就能完成供电、程序烧录、串口打印调试信息所有功能,无需额外的USB转串口芯片或调试器,极大简化了开发。
  • 用户按键与RGB LED:通常至少会有一个复位键(RST)和一个用户可编程按键(BOOT/GPIO0)。RGB LED则可以用来做状态指示,比如用不同颜色表示Wi-Fi连接状态、设备工作模式等,让交互更直观。
  • 摄像头接口:这个预留的接口非常关键。它通常是标准的24PIN或18PIN DVP接口,可以直接插接OV2640、OV7670等常见摄像头模组。结合ESP32-S3的AI能力,这就构成了一个最简单的“边缘视觉”节点。我尝试过接入OV2640,在ESP-IDF中使用esp32-camera组件,可以轻松获取图像数据,然后送入TensorFlow Lite Micro模型进行识别。
  • 扩展排针:板子四周的排针将ESP32-S3未使用的GPIO引了出来。你可以通过这些排针连接温湿度传感器(如DHT11、SHT30)、运动传感器(MPU6050)、SD卡模块等,进一步扩展功能。

注意:在连接外部传感器时,务必先查看开发板的原理图(如果厂家提供),确认你准备使用的GPIO引脚没有被屏幕、摄像头接口或内部Flash等占用,避免冲突导致功能异常。

3. 开发环境搭建与“第一行代码”

拿到硬件后,第一步就是搭建开发环境并点亮点亮屏幕。这里主要有两条路径:Arduino IDEESP-IDF。我会对比两者的优劣,并给出具体的操作步骤。

3.1 路径选择:Arduino的便捷与ESP-IDF的强大

Arduino IDE路径:对于初学者或者希望快速验证想法、使用大量现成传感器库的开发者,Arduino是首选。它的优点是上手极快,库管理方便,社区资源丰富。

  • 安装步骤:
    1. 下载并安装Arduino IDE。
    2. 在“文件”->“首选项”的“附加开发板管理器网址”中,添加乐鑫的板卡支持地址:https://espressif.github.io/arduino-esp32/package_esp32_index.json
    3. 打开“工具”->“开发板”->“开发板管理器”,搜索“esp32”,安装“Espressif Systems”提供的ESP32开发板支持包(版本建议选最新的稳定版)。
    4. 安装完成后,在“工具”->“开发板”列表中,选择“ESP32S3 Dev Module”。然后,你需要根据ESP32-S3-LCD-1.47B的具体配置,在“工具”菜单下设置正确的Flash Size(通常是8MB或16MB)、PSRAM(Enabled, 8MB)、Partition Scheme(Huge APP)等。最重要的是,要找到并安装适用于这块屏幕的驱动库,比如TFT_eSPI库,并在库的配置文件中正确设置引脚。
  • 优点:半小时内就能写出一个显示“Hello World”的程序。
  • 缺点:对ESP32-S3特有功能(如USB JTAG、8位并行SPI优化、AI指令集)的支持可能不够深入或需要额外配置;项目结构简单,不适合大型复杂应用。

ESP-IDF路径:这是乐鑫官方的物联网开发框架,功能最全、性能最优、对芯片特性支持最完善。如果你想充分发挥ESP32-S3的AI能力、使用LVGL构建复杂UI、或进行产品级开发,ESP-IDF是必经之路。

  • 安装步骤(推荐使用VSCode扩展):
    1. 安装Visual Studio Code。
    2. 在VSCode扩展商店中搜索并安装“Espressif IDF”扩展。
    3. 安装扩展后,按F1打开命令面板,输入“ESP-IDF: Configure ESP-IDF extension”,选择“Express”安装方式。扩展会自动下载所需的工具链和ESP-IDF框架。
    4. 安装完成后,就可以通过“ESP-IDF: Show Examples Projects”来打开官方示例,其中就有针对LCD和摄像头的例程。
  • 优点:官方原生支持,能使用所有底层特性;组件化管理,方便集成LVGL、TensorFlow Lite Micro等复杂组件;调试工具强大(如JTAG调试、性能分析)。
  • 缺点:学习曲线较陡,需要了解CMake构建系统,对新手不友好。

我的建议:如果你是嵌入式新手,想先感受一下硬件,可以从Arduino开始,点亮屏幕跑个简单程序。但如果你目标明确,就是要做带AI或复杂UI的项目,请直接上手ESP-IDF,早期的学习成本会在后期开发效率上加倍回报你。

3.2 点亮屏幕:在ESP-IDF中驱动LCD

假设我们选择了ESP-IDF路径。点亮屏幕的第一步是创建一个基于esp_lcdlvgl组件的新工程。乐鑫官方提供了非常完善的示例。

  1. 创建项目:在VSCode中,使用“ESP-IDF: New Project”命令,创建一个空项目。
  2. 添加组件依赖:在项目的CMakeLists.txt中,添加对esp_lcdlvgldriver等组件的依赖。更简单的方法是,直接从ESP-IDF示例目录(examples/peripherals/lcd/lvgl)中复制一份代码到你的项目目录,以此为基础进行修改。这是最快最不容易出错的方式。
  3. 配置引脚与参数:打开示例中的main.cKconfig.projbuild(或sdkconfig.defaults)文件。这里需要根据ESP32-S3-LCD-1.47B的原理图,修改屏幕的引脚定义。关键参数包括:
    • SPI_CLK_GPIO,SPI_MOSI_GPIO等SPI引脚。
    • LCD_DC_GPIO(数据/命令选择引脚)。
    • LCD_RST_GPIO(复位引脚,如果硬件连接了的话)。
    • LCD_PIXEL_CLOCK_HZ(SPI时钟频率,可尝试从20MHz开始调高)。
    • 屏幕的宽度(LCD_H_RES= 172)和高度(LCD_V_RES= 320)。
  4. 编译与烧录:连接USB线,在VSCode底部状态栏选择正确的串口和芯片目标(ESP32-S3)。点击编译按钮,然后点击烧录按钮。如果一切配置正确,编译烧录完成后,屏幕应该会被初始化,并显示LVGL的示例UI(如一个仪表盘和几个按钮)。

常见踩坑点:

  • 屏幕白屏或花屏:这是最常见的问题。99%的原因是指令引脚(DC、RST)或SPI引脚配置错误。请务必对照开发板原理图或卖家提供的资料再三检查。也可以用逻辑分析仪或示波器抓一下SPI波形,看是否有数据发出。
  • 刷新速度慢:如果感觉UI拖动有卡顿,首先检查LCD_PIXEL_CLOCK_HZ是否已设置到较高值(如40MHz或80MHz,需在屏幕驱动IC允许范围内)。其次,确认是否启用了8位并行SPI模式(在esp_lcd的配置结构中设置flags.octal_mode = true),这需要硬件连接支持。
  • 内存不足:LVGL和帧缓冲区会消耗不少内存。确保在menuconfig中正确配置了PSRAM(Component config -> ESP32S3-Specific -> Support for external, SPI-connected RAM),并为LVGL分配足够的内存(在lvgl组件的配置菜单中设置)。

4. 核心功能实战:从联网到运行AI模型

当屏幕成功点亮,开发环境也熟悉后,就可以开始实现核心功能了。我们围绕两个最典型的应用展开:联网获取数据并显示,以及运行轻量级AI模型。

4.1 实现网络功能与动态UI更新

一个常见的场景是制作一个网络天气站。这需要完成Wi-Fi连接、HTTP请求、JSON解析和LVGL UI更新。

步骤一:Wi-Fi连接在ESP-IDF中,使用esp_netifesp_event组件进行Wi-Fi连接非常标准。你需要提供SSID和密码。代码逻辑通常是:初始化网络接口 -> 注册Wi-Fi事件处理函数 -> 启动Wi-Fi Station模式 -> 等待连接成功事件。务必增加重连机制,在网络异常断开后能自动尝试重新连接。

步骤二:HTTP请求与数据解析使用esp_http_client组件发起HTTPS请求,从天气API(如和风天气、OpenWeatherMap)获取数据。收到数据后,使用cJSON库解析JSON格式的响应,提取出温度、湿度、天气状况等字段。

步骤三:LVGL UI设计与刷新在LVGL中创建所需的UI组件:几个标签(Label)用于显示城市名、温度、湿度,一个图片(Image)组件用于显示天气图标(晴、雨、雪等)。你可以使用LVGL的官方设计工具SquareLine Studio进行可视化拖拽设计,生成C代码,这样比纯手写代码效率高很多。 解析到天气数据后,在主循环或一个单独的任务中,调用lv_label_set_text_fmt()等函数更新UI组件的文本或图片源。LVGL本身不是线程安全的,所以从网络任务更新UI时,需要通过lv_timer或互斥锁(mutex)进行同步。

我的经验:将网络请求放在一个独立的任务(FreeRTOS Task)中,优先级设为中等。UI更新由LVGL的内部定时器驱动。两者之间通过线程安全的队列(Queue)传递数据。这样能避免网络请求阻塞UI渲染,导致界面卡死。同时,记得在UI上设计一个连接状态指示,比如用RGB LED或屏幕角落的一个小点,显示Wi-Fi是否已连接、数据是否在更新。

4.2 集成摄像头与运行TensorFlow Lite Micro

这是体现ESP32-S3-LCD-1.47B价值的高阶玩法。目标是让板子通过摄像头捕捉图像,在本地运行一个人脸检测模型,并将检测结果(画框)实时显示在屏幕上。

步骤一:连接并驱动摄像头使用排线将OV2640摄像头模组连接到板子的摄像头接口。在ESP-IDF中,启用esp32-camera组件。这个组件提供了统一的API来初始化摄像头、配置分辨率(如QVGA: 320x240)、获取图像帧。初始化完成后,你可以调用esp_camera_fb_get()来获取一帧图像数据(通常是JPEG格式或RGB格式)。

步骤二:准备TensorFlow Lite Micro模型

  1. 模型选择与训练:对于人脸检测,可以从简单的MobileNetV1 SSD或自定义的轻量级模型开始。你可以使用TensorFlow或PyTorch在PC上训练一个模型,或者直接使用网上已有的预训练模型。
  2. 模型转换:使用TensorFlow Lite转换工具(tflite_convert或在线转换器)将模型转换为.tflite格式。然后,使用xxd命令或专门的转换脚本,将.tflite文件转换为C语言字节数组(一个巨大的const unsigned char数组),以便嵌入到ESP32的固件中。
  3. 集成到工程:在ESP-IDF项目中,启用TensorFlow Lite Micro组件(通过idf.py menuconfig或直接修改CMakeLists.txt)。将上一步生成的C数组文件放入项目目录,并在代码中#include它。

步骤三:编写推理与显示代码

  1. 初始化解释器:在代码中,包含tensorflow/lite/micro/all_ops_resolver.htensorflow/lite/micro/micro_interpreter.h等头文件。使用你的模型数组初始化一个tflite::MicroInterpreter
  2. 预处理图像:esp_camera获取的图像帧可能需要经过缩放、色彩空间转换(RGB888转RGB565或灰度)、归一化等预处理,以匹配模型的输入要求。这部分代码对性能影响很大,尽量使用高效的查找表(LUT)或ESP32-S3的向量指令进行优化。
  3. 运行推理:将预处理后的图像数据拷贝到解释器的输入张量(input->data.finput->data.uint8),然后调用interpreter->Invoke()
  4. 解析结果并显示:从输出张量中读取结果。对于目标检测模型,输出通常是边界框坐标、类别和置信度。在LVGL中,你可以使用lv_draw_rect函数,根据这些坐标在屏幕的对应位置(需要做坐标映射,因为摄像头分辨率和屏幕分辨率不同)绘制矩形框,实现实时画框显示。

性能优化与踩坑实录:

  • 内存瓶颈:摄像头图像帧、TensorFlow Lite Micro的中间张量(Arena)都会消耗大量内存。务必在menuconfig中开启PSRAM支持,并将TensorFlow Lite的中间内存(tensor_arena)分配到PSRAM中。同时,选择较低的摄像头分辨率(如QQVGA 160x120)能显著减少内存压力和推理时间。
  • 推理速度:在QVGA分辨率下,即使使用MobileNet,单次推理也可能需要几百毫秒,达不到“实时”。为了加速:
    • 使用ESP32-S3的VEXT指令。确保在编译时开启了-O2-O3优化,并且TensorFlow Lite Micro的库编译时包含了ESP32-S3的特定优化。
    • 考虑使用更小的模型,或二值化神经网络(BNN)。
    • 降低摄像头帧率,比如每秒只处理5-10帧。
  • 显示延迟:在屏幕上实时绘制检测框时,如果直接在主循环中连续调用LVGL的刷新函数,可能会造成界面卡顿。更好的做法是,将推理和画框放在一个独立的中优先级任务中,并通过消息队列通知UI任务进行更新,或者使用LVGL的定时器在固定间隔内刷新检测结果图层。

5. 深入调试:解决蓝牙与功耗的隐秘问题

在开发过程中,我遇到了两个不那么直观但影响很大的问题,都与无线功能相关,值得单独拿出来讨论。

5.1 如何管理ESP32-S3中的蓝牙状态

在一些项目中,你可能同时需要Wi-Fi和蓝牙功能,或者需要蓝牙间歇性工作。ESP32-S3的蓝牙协议栈(Bluetooth Controller)在默认情况下,一旦初始化,就会持续运行并消耗可观的电流(几十毫安)。如果你不需要蓝牙,最简单的办法就是在menuconfig中完全禁用蓝牙(Component config -> Bluetooth -> Bluetooth -> Bluetooth controller -> Bluetooth controller mode (Disabled))。

但如果你需要蓝牙,只是不希望它一直活跃,就需要主动管理其状态。核心概念是:蓝牙控制器可以独立于主CPU进入“休眠”状态,但它的唤醒和停止需要遵循特定流程,不能粗暴地直接断电。

错误做法与后果:我曾尝试在不需要蓝牙时,直接调用esp_bluedroid_disable()esp_bt_controller_disable(),然后在需要时再重新启用。结果经常导致系统不稳定,甚至出现内存错误或看门狗复位。原因是蓝牙协议栈内部有一些异步任务和定时器,直接禁用可能无法干净地释放所有资源。

正确的流程:乐鑫提供了更精细的控制API。关键在于使用esp_bt_controller_get_status()来查询当前状态,并根据状态进行安全的模式切换。

// 1. 初始化蓝牙(仅在应用开始时做一次) esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); esp_bt_controller_init(&bt_cfg); esp_bt_controller_enable(ESP_BT_MODE_BTDM); // 启用双模(BR/EDR + BLE) esp_bluedroid_init(); esp_bluedroid_enable(); // ... 使用蓝牙进行广播或连接 ... // 2. 当需要让蓝牙进入低功耗状态时(例如,设备进入数据采集模式,暂时不用蓝牙) // 首先,停止所有蓝牙应用层活动,断开连接,停止广播。 esp_bluedroid_disable(); esp_bluedroid_deinit(); // 将蓝牙控制器设置为低功耗模式。注意:不是禁用(disable)。 esp_bt_controller_disable(); // 先禁用 esp_bt_controller_enable(ESP_BT_MODE_BLE); // 再以BLE模式启用?不,对于深度睡眠,需要进入特定模式。 // 更常见的做法是,如果希望彻底关闭射频以省电,且允许唤醒后较慢重启,可以: esp_bt_controller_disable(); esp_bt_controller_deinit(); // 释放资源 // 此时蓝牙硬件完全关闭,功耗最低。 // 3. 当需要重新使用蓝牙时 // 重新初始化和启用(流程同步骤1) esp_bt_controller_init(&bt_cfg); esp_bt_controller_enable(ESP_BT_MODE_BTDM); esp_bluedroid_init(); esp_bluedroid_enable(); // 重新配置并启动你的蓝牙应用(广播、服务等)。

更优策略(动态电源管理):对于需要频繁切换的场景,频繁初始化和反初始化开销较大。ESP-IDF的电源管理组件(esp_pm)可以在系统空闲时自动降低CPU频率并使外设进入低功耗状态,但对蓝牙控制器的控制不够直接。一个实用的折中方案是:

  • 如果蓝牙只是偶尔用(比如一天几次),用上述“关闭-重启”流程。
  • 如果蓝牙需要较快速响应(比如作为Beacon间歇广播),则保持蓝牙控制器使能,但通过API(如esp_bt_sleep_enable())使其进入蓝牙模块自身的睡眠模式,并通过RF开关控制射频部分。这需要更深入的蓝牙协议栈知识。

关键点:避免在蓝牙协议栈活动期间(如有连接或广播)直接调用禁用函数。务必先通过应用层API停止所有活动,等待相关回调确认停止后,再逐层关闭协议栈和控制器。

5.2 系统级功耗优化实战

对于电池供电的项目,功耗是生命线。ESP32-S3-LCD-1.47B的功耗大头主要在:ESP32-S3芯片本身、屏幕背光、以及外接的传感器/摄像头。

1. 屏幕背光控制:这块板的屏幕背光通常由一个GPIO通过PWM或简单的电平控制。在不需要显示时(比如设备休眠时),一定要彻底关闭背光。仅仅清空屏幕帧缓冲区(让屏幕显示黑色)是不够的,背光LED本身仍在耗电。

// 假设背光控制引脚为GPIO_NUM_XX #define LCD_BL_GPIO GPIO_NUM_XX gpio_set_direction(LCD_BL_GPIO, GPIO_MODE_OUTPUT); gpio_set_level(LCD_BL_GPIO, 0); // 拉低,关闭背光 // 需要显示时再拉高

对于需要调节亮度的情况,可以将该GPIO配置为PWM输出,通过改变占空比来调节亮度。

2. ESP32-S3的睡眠模式:ESP32-S3支持多种睡眠模式,常见的有:

  • Modem-sleep:Wi-Fi/蓝牙射频关闭,CPU和内存保持运行。适用于需要CPU持续工作但不需要无线的场景。通过esp_wifi_set_ps(WIFI_PS_MIN_MODEM)设置。
  • Light-sleep:CPU暂停,内存数据保持,部分外设关闭。可被定时器或外部中断唤醒。唤醒速度快(毫秒级)。调用esp_light_sleep_start()进入。
  • Deep-sleep:仅RTC模块和极少量内存保持供电,其他全部关闭。功耗最低(约10μA)。可被定时器、GPIO引脚变化等唤醒。唤醒后程序从头开始执行(类似复位)。调用esp_deep_sleep_start()进入。

我的配置策略:对于一个环境传感器,我采用“工作-深度睡眠”循环:

  • 工作期(约5秒):开启Wi-Fi连接服务器上传数据,点亮屏幕显示最新读数。
  • 睡眠期(55秒):调用esp_deep_sleep_start(),并设置RTC定时器在55秒后唤醒。在进入深度睡眠前,务必执行:
    • esp_bluedroid_disable()esp_bt_controller_disable()(如果用了蓝牙)。
    • esp_wifi_stop()停止Wi-Fi。
    • 将屏幕背光GPIO拉低。
    • 将其他外部传感器(如I2C温湿度传感器)的电源控制引脚拉低(如果硬件支持)。
    • 保存需要保持的数据到RTC慢速内存(RTC_DATA_ATTR修饰的变量)。
  • 这样,平均电流可以从工作时的近百mA,降至深睡时的几十μA,极大地延长了电池寿命。

3. 外设电源管理:对于摄像头、SD卡模块等功耗较大的外设,最好通过一个MOSFET或电源管理IC来控制其VCC供电,在不需要时彻底断电,而不是仅仅让其进入待机模式。

调试功耗时,串口打印是耗电大户。在最终发布固件前,务必减少或禁用调试日志输出(在menuconfig中设置日志级别为Warning或Error,并关闭不必要的组件日志)。使用电流表或功耗分析仪实际测量不同状态下的电流,是优化功耗最可靠的方法。