1. 选板与硬件认知:先搞清楚你手里的ESP32-S3是什么
玩ESP32-S3,第一件事不是急着装软件,而是搞清楚你手里的板子到底是哪一款。很多新手踩的第一个坑,就是在淘宝上看到“ESP32-S3开发板”就下单,结果拿到手发现引脚定义、Flash大小、RAM大小和网上的教程对不上,折腾半天连例程都编译不过去。
ESP32-S3是乐鑫推出的一款双核Xtal处理器,主频最高240MHz,最大的亮点是原生支持AI加速指令集,这在处理语音识别、图像识别这类边缘计算场景时非常有用。和上一代ESP32相比,S3把蓝牙升级到了BLE 5.0,Wi-Fi也做了优化,最重要的是增加了大量GPIO,尤其是那个“N16R8”的版本——这里的N指Flash容量,16就是16MB;R指PSRAM(外部伪静态随机存储器),8就是8MB。所以N16R8代表这款板子有16MB的Flash和8MB的PSRAM,这个配置跑复杂应用、做LVGL界面、跑语音模型都够用了。
我手上的这块板子是微雪(WaveShare)出的ESP32-S3 N16R8,板载了一个LCD接口、一个摄像头接口、一个TF卡槽、一个WS2812 RGB灯,还预留了麦克风焊盘。这些外设集成度高,非常适合做物联网终端原型验证。选板的时候建议看清楚几件事:一是Flash和PSRAM的容量,这决定了你能不能跑马子哥(MicroPython)之外的复杂应用;二是板载外设,比如有没有RGB灯、有没有屏幕接口,这些直接影响你的学习曲线;三是USB转串口芯片的型号,微雪这块用的是CP2102,驱动在Win11下免驱,但有些板子用CH340,就得手动装驱动。
说句实在话,ESP32-S3在入门阶段最值得玩的三个方向是:BLE配网、麦克风音频采集、以及驱动屏幕显示。这三个方向基本覆盖了物联网设备的核心交互链路——“连上网、听得到、看得到”。后面的内容我会围绕这三个方向展开,先解决环境问题,再跑通几个核心例程。
2. 环境搭建的核心方案选型:VSCode + ESP-IDF插件才是最优解
2.1 为什么放弃Arduino走ESP-IDF
国内大量教程一上来就用Arduino IDE写ESP32,因为简单,装个板卡包就能跑。但我个人强烈建议,如果你打算长期玩ESP32-S3,直接上ESP-IDF(Espressif IoT Development Framework),也就是乐鑫官方提供的物联网开发框架。原因有两个:
第一,ESP32-S3的很多高级特性在Arduino库里支持滞后甚至缺失。比如S3的AI扩展指令集、I2S麦克风通道的精细配置、BLE Mesh、以及更精细的低功耗管理,这些在ESP-IDF里都是原生支持的一等公民,在Arduino里却要靠第三方库打补丁。
第二,ESP-IDF的工程结构是CMake组织起来的,这和你之后接触Linux开发、嵌入式Linux、RT-Thread、Zephyr的开发方式一脉相承。把ESP-IDF的工程结构搞明白,你后面迁移到其他MCU平台会非常丝滑。Arduino那种把一切都封装好、代码拷进去就能跑的模式,短期爽,长期吃亏。
当然,取舍也很明显:ESP-IDF的编译速度比Arduino慢不少,第一次编译一个工程可能要三到五分钟,配置环境也比Arduino繁琐。但这个问题有解法,就是下面要说的——用VSCode插件而不是纯命令行。
2.2 VSCode + ESP-IDF插件的安装全流程
在Win11上搭建ESP-IDF环境,推荐走VSCode的Espressif IDF插件这个路线。相比在命令行里手动安装esp-idf-tools-setup,插件的优势在于它把环境变量、工具链路径、Python虚拟环境全部集成到了VSCode内部,出问题也容易排查。
具体操作步骤是这样的:
- 装好VSCode,在扩展市场里搜“espressif-idf-extension”,作者就是乐鑫官方,不要装错了,第三方同名的不少。
- 打开插件后按F1,输入“ESP-IDF: Install ESP-IDF Setup”,这时会有两个选项:一个是下载预编译好的工具链,另一个是用现成的ESP-IDF。这里推荐选“Express”模式,它会自动下载最新稳定版的ESP-IDF和所有工具链,虽然下载体积大概在500MB左右,但省心。
- 安装过程中会要求选择Python虚拟环境的路径,建议单独创建一个专用的venv目录,不要用系统自带的Python解释器。这里有个坑:如果你电脑上装了Anaconda或者Miniconda,插件默认可能会去调用conda环境里的Python,而conda的Python和ESP-IDF的某个依赖包可能存在兼容性问题。我在一台装了Miniconda的机器上踩过这个坑,现象是安装到“pip install requirement”那一步总是报错,换成纯净的Python虚拟环境后一次通过。
- 安装完成后,VSCode左下角会出现一个“ESP-IDF”状态栏图标,点击可以切换目标芯片型号、查看串口等。在这之前,先把开发板的USB线插上电脑,用Type-C数据线,注意一定要用支持数据传输的线——很多线只能充电,无法识别串口。
关于串口驱动的补充:如果你的板子用的是CH340芯片,Win11偶尔会不自动安装驱动,表现出来的现象是设备管理器里显示一个黄色的感叹号。解决办法很简单,去WCH官网下载CH340驱动手动安装。如果是CP2102就不需要管。
2.3 首次编译前的准备:选择正确的目标芯片与串口
打开VSCode后,需要先告诉ESP-IDF插件你要编译哪个芯片的工程。按F1,输入“ESP-IDF: Set Espressif Device Target”,选择esp32s3。这个步骤很容易被跳过,但很重要——如果你不设置,插件默认按esp32来编译,编译也能通过,但烧录时会发现无法连接——因为两者的Flash加密、下载协议都存在差异。
连接开发板后,在VSCode右下角状态栏里可以看到识别到的串口号,例如COM3、COM5等。在烧录之前,进入设备的“端口(COM和LPT)”属性,确认该串口的波特率设置是否为默认值。实测下来,ESP-IDF默认的烧录波特率是921600,如果你用的USB线质量差或接触不良,这个波特率下会频繁烧录失败。解决方法是插件的配置里把烧录波特率降到460800,速度慢一点但稳定得多。
到这里,环境搭建的初体验就完成了。接下来,走一个真正的Hello World级项目,把流程完整跑通。
3. 从零跑通第一个工程:点亮板载WS2812并实现LED渐变
3.1 创建工程模板:从例程而非空白工程开始
对新手来说,强烈建议不要从空白工程开始写代码,而是直接拷贝官方例程进行修改。官方例程位于安装的ESP-IDF目录下的examples文件夹里,路径通常是:
{你的安装路径}/esp-idf/examples/peripherals/rmt/led_strip为什么选这个例程?因为WS2812的驱动在ESP32上最有代表性的实现方式就是RMT(Remote Control)外设,乐鑫官方把这个例程写得很干净,它展示了如何用RMT产生精确的时序波形来控制WS2812灯珠。理解了这个例程,你也就理解了ESP32驱动大多数单总线协议器件(比如DHT11温湿度传感器)的原理。
操作上,在VSCode里按F1,输入“ESP-IDF: Show Example Projects”,选择“ESP-IDF Examples”列表里的“peripherals -> rmt -> led_strip”,点击创建。插件会要求你选一个目录存放工程,建议单独建一个“esp32_projects”文件夹统一管理。
3.2 修改代码:让WS2812亮起来并在多种颜色间渐变
创建好的工程里,核心代码在main目录下的led_strip_example_main.c里。我来逐个讲解关键修改点。
先看头文件的引入和静态变量的定义:
#include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "led_strip.h" #include "esp_log.h" #include "driver/gpio.h" static const char *TAG = "led_strip_example"; static led_strip_handle_t led_strip;第4行引入led_strip驱动库的头文件,乐鑫官方已经把这个外设抽象成了组件,不需要自己写RMT底层时序。第7行定义了一个led_strip_handle_t类型的句柄,这是所有后续操作的核心。
接下来是初始化函数。在官方例程里,GPIO引脚定义在menuconfig里,默认是GPIO48。不同厂家的板子WS2812接的引脚不一样,微雪这个板子我试过,WS2812在GPIO48上,但也有板子接在GPIO38甚至GPIO40上。改法很简单,直接在代码里硬编码:
#define BLINK_GPIO 48然后是配置RMT外设并创建led_strip句柄:
led_strip_config_t strip_config = { .strip_gpio_num = BLINK_GPIO, .max_leds = 1, .led_model = LED_MODEL_WS2812, .color_component_format = LED_STRIP_COLOR_COMPONENT_FMT_GRB, .flags = { .invert_out = false, }, }; led_strip_rmt_config_t rmt_config = { .clk_src = RMT_CLK_SRC_DEFAULT, .resolution_hz = 10 * 1000 * 1000, .mem_block_symbols = 64, }; ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip));这里注意color_component_format字段,WS2812用的是GRB格式,不是RGB,如果配错了颜色顺序,出来的颜色会非常诡异——红色会变成蓝色,绿色会变成红色,我第一次调试时就因为这里写错而困惑了很久。
初始化完成后,在app_main里先清空所有LED,然后循环设置颜色:
void app_main(void) { led_strip_clear(led_strip); while (1) { // 红色渐变 for (int i = 0; i < 255; i++) { led_strip_set_pixel(led_strip, 0, i, 0, 0); led_strip_refresh(led_strip); vTaskDelay(pdMS_TO_TICKS(20)); } // 绿色 for (int i = 255; i > 0; i--) { led_strip_set_pixel(led_strip, 0, 0, i, 0); led_strip_refresh(led_strip); vTaskDelay(pdMS_TO_TICKS(20)); } } }led_strip_set_pixel函数的参数是(句柄,灯珠编号,R值,G值,B值)。渐变效果的实现其实就是一个简单的PWM思维——通过循环改变亮度值,每20毫秒刷新一次,人眼就看到平滑过渡了。如果你想让所有灯珠一起呼吸,只需要把set_pixel的调用写成一个for循环,遍历所有灯珠即可。
3.3 编译与烧录:常见错误一网打尽
写完代码后,点击VSCode底部蓝色状态栏的“闪电”图标(编译),或者按快捷键Ctrl+E然后B,插件会开始编译。第一次编译可能需要三到五分钟,因为要编译整个FreeRTOS内核和所有依赖的组件,后续增量编译就会快很多,通常十几秒就完成。
编译完成后,同样的方法按“火焰”图标(烧录)。这里我遇到了几个高频问题,直接列出来:
| 问题 | 现象 | 解法 |
|---|---|---|
| 串口无法识别 | 设备管理器无设备 | 检查USB线是否支持数据传输,换线测试;确认驱动安装 |
| 烧录失败 | 连接超时,找不到芯片 | 按住开发板上的BOOT键,再插USB;或者把烧录波特率降到460800 |
| 编译报错 | 找不到esp_system.h等头文件 | 确认你设置了目标芯片为esp32s3(F1 -> Set Espressif Device Target) |
| 烧录成功但灯不亮 | GPIO没反应 | 确认引脚号是否正确,用万用表测WS2812的VCC引脚是否有5V供电 |
关于烧录失败最有效的手动操作方法:先把USB线从电脑上拔掉,按住开发板上的BOOT键不放,再把USB线插回电脑,这时设备管理器会出现一个新的串口,然后再点烧录。ESP32-S3有原生的USB CDC功能,但这个功能需要在应用代码里配置USB外设,引导阶段还是靠串口下载器。
4. 进阶实践一:接入板载麦克风,实现声音强度检测与输出
4.1 麦克风硬件配置与I2S初始化
ESP32-S3有专门的I2S外设,可以连接数字麦克风,例如板载的MSM261S4030H0。这是一个MEMS数字麦克风,输出的数据格式是PDM(脉冲密度调制),需要I2S接口以PDM模式接收。
微雪这块板子把麦克风接到了GPIO12(时钟)和GPIO13(数据),具体定义可以在原理图里查到。PDM麦克风在读取时需要配置I2S为Philips模式,并且把slot_mask设置为只使用右声道——因为很多PDM麦克风默认只在右声道输出数据。
下面这段代码展示了如何配置I2S读取麦克风数据,并提取声音的RMS值作为音量输出:
#include "driver/i2s_std.h" #include "driver/i2s_pdm.h" #define MIC_CLK_GPIO 12 #define MIC_DATA_GPIO 13 void mic_i2s_init(void) { i2s_chan_handle_t rx_chan; i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); i2s_new_channel(&chan_cfg, &rx_chan, NULL); i2s_pdm_rx_config_t pdm_cfg = { .clk_cfg = { .sample_rate_hz = 16000, .clk_src = I2S_CLK_SRC_DEFAULT, }, .slot_cfg = { .slot_mode = I2S_SLOT_MODE_MONO, .data_bit_width = I2S_DATA_BIT_WIDTH_16BIT, .slot_bit_width = I2S_SLOT_BIT_WIDTH_16BIT, .slot_mask = I2S_PDM_SLOT_RIGHT, }, .gpio_cfg = { .clk = MIC_CLK_GPIO, .din = MIC_DATA_GPIO, .invert_flags = { .clk_inv = false, }, }, }; i2s_channel_init_pdm_rx_mode(rx_chan, &pdm_cfg); i2s_channel_enable(rx_chan); }这里有几个细节:sample_rate_hz设置成16000就够语音识别用了,设置太高会导致数据量暴增而且PDM麦克风的有效频响范围一般最多到20kHz左右;slot_mask用I2S_PDM_SLOT_RIGHT,因为我们的麦克风数据在右声道。
4.2 实时读取并计算音量,点亮WS2812
有了I2S通道之后,就可以在循环里读取数据了。PDM麦克风读出来的原始数据是一堆带符号的16位整型数,需要经过一个简单的HPF(高通滤波)去掉直流偏置,再计算RMS值就能得到相对音量。
#define SAMPLE_RATE 16000 #define READ_BUF_SIZE 512 void audio_task(void *arg) { int16_t *buf = malloc(READ_BUF_SIZE * sizeof(int16_t)); while (1) { size_t bytes_read = 0; i2s_channel_read(rx_chan, buf, READ_BUF_SIZE * sizeof(int16_t), &bytes_read, portMAX_DELAY); int samples = bytes_read / sizeof(int16_t); double sum_sq = 0; for (int i = 0; i < samples; i++) { // 去直流,简单一阶高通滤波器 static int16_t prev = 0; int16_t filtered = buf[i] - prev; prev = buf[i]; sum_sq += (double)filtered * filtered; } double rms = sqrt(sum_sq / samples); uint8_t brightness = (uint8_t)(rms * 2); led_strip_set_pixel(led_strip, 0, brightness, 0, 255 - brightness); led_strip_refresh(led_strip); vTaskDelay(pdMS_TO_TICKS(50)); } }这段代码没有做FFT,只是做了最基础的RMS检测。如果你后续想识别语音内容或者做一个简单的唤醒词检测,可以把I2S的音频流直接接入乐鑫的ESP-SR(Espressif Speech Recognition)组件,官方提供了“你好小智”这样的唤醒词模型,需要额外在menuconfig里勾选esp-sr组件并分配至少1.5MB的RAM。
实测下来,在N16R8上跑ESP-SR的唤醒词检测,RAM占用大概在2MB以内,Flash占用3MB左右,绰绰有余。
5. 进阶实践二:BLE配网 + 屏幕显示,做出一个能用的物联网节点
5.1 BLE配网思路:通过手机App写入Wi-Fi凭据
ESP32-S3的BLE配网是目前物联网设备最常见的连接方案。核心思路是:设备上电后先开启一个BLE GATT服务,手机App连接该服务后,把Wi-Fi的SSID和密码写入设备,设备拿到这些信息后断开BLE,切换为Wi-Fi Station模式连接路由器。
用ESP-IDF实现BLE配网,最省力的方式是使用官方提供的wifi_provisioning组件。这个组件已经封装好了完整的安全校验、BLE GATT服务和数据解析协议,配合乐鑫官方手机App(ESP SoftAP Prov)就能直接使用,不必自己写手机端,也不用自己定义数据协议格式。
5.2 实际配置步骤与代码示例
在menuconfig里使能wifi_provisioning组件后,主代码只需要几个函数调用就能完成整个配网流程:
#include "wifi_provisioning/manager.h" #include "wifi_provisioning/scheme_ble.h" static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { if (event_base == WIFI_PROV_EVENT) { switch (event_id) { case WIFI_PROV_START: ESP_LOGI(TAG, "Provisioning started"); break; case WIFI_PROV_CRED_RECV: ESP_LOGI(TAG, "Received Wi-Fi credentials"); break; case WIFI_PROV_CRED_FAIL: ESP_LOGI(TAG, "Provisioning failed, retrying..."); esp_wifi_set_storage(WIFI_STORAGE_RAM); esp_wifi_disconnect(); break; case WIFI_PROV_END: ESP_LOGI(TAG, "Provisioning finished, starting Wi-Fi"); break; default: break; } } } void start_ble_provisioning(void) { wifi_prov_mgr_config_t config = { .scheme = wifi_prov_scheme_ble, .scheme_event_handler = WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM, }; ESP_ERROR_CHECK(wifi_prov_mgr_init(config)); const char *service_name = "MY_ESP32_S3_DEVICE"; const char *service_key = "my_proof_of_possession"; ESP_ERROR_CHECK(wifi_prov_mgr_start_provisioning(WIFI_PROV_SECURITY_1, service_name, service_key)); }这里WIFI_PROV_SECURITY_1是安全模式,要求手机端输入一个proof-of-possession密钥才能配对,有效防止别人随意配网窃取你家的Wi-Fi密码。service_name就是你在手机App里看到的设备名,我建议加上设备的标识号,避免多个设备同时配网时认不清。
配网完成后,Wi-Fi会自动连接路由器,设备MAC地址和IP信息可以通过日志窗口打印出来。到这里,这个ESP32-S3节点就有了网络基础能力。
5.3 用GC9A01圆形屏幕实时显示网络状态
有了Wi-Fi连接,下一步就是把网络状态可视化。GC9A01是一款圆形的TFT屏幕,分辨率240x240,行情价十几块钱,几乎是为ESP32-S3开发板量身定做的显示外设。
驱动GC9A01需要SPI接口。接线方式从微雪板子上直接引出的SPI引脚通常对应:SCLK、MOSI、CS、DC、RST、BL。用ESP-IDF官方提供的spi_master驱动:
#include "esp_lcd_panel_io.h" #include "esp_lcd_panel_vendor.h" #include "esp_lcd_panel_ops.h" // 创建SPI总线 spi_bus_config_t bus_cfg = { .sclk_io_num = 12, .mosi_io_num = 11, .miso_io_num = -1, // GC9A01不需要MISO .quadwp_io_num = -1, .quadhd_io_num = -1, .max_transfer_sz = 240 * 240 * 2, }; spi_bus_initialize(SPI2_HOST, &bus_cfg, SPI_DMA_CH_AUTO); // 创建LCD面板 esp_lcd_panel_io_handle_t io_handle; esp_lcd_panel_io_spi_config_t io_config = { .dc_gpio_num = 13, .cs_gpio_num = 10, .pclk_hz = 40 * 1000 * 1000, .lcd_cmd_bits = 8, .lcd_param_bits = 8, .spi_mode = 0, .trans_queue_depth = 10, }; esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)SPI2_HOST, &io_config, &io_handle); // 初始化GC9A01 esp_lcd_panel_handle_t panel = NULL; esp_lcd_panel_dev_config_t panel_config = { .reset_gpio_num = 14, .color_space = ESP_LCD_COLOR_SPACE_RGB, .bits_per_pixel = 16, }; esp_lcd_new_panel_gc9a01(io_handle, &panel_config, &panel); esp_lcd_panel_reset(panel); esp_lcd_panel_init(panel);屏幕初始化之后,配合LVGL图形库,可以在屏幕上绘制一个圆形表盘,显示配网状态和当前IP地址。LVGL在N16R8上跑240x240的屏幕非常流畅,帧率能到30fps以上——前提是配置了DMA传输和双缓冲。
有个值得注意的点:GC9A01的SPI时钟频率不是越高越好,实测在40MHz以下工作正常,调太高可能出现花屏,某些批次的屏幕甚至需要降到20MHz。如果显示出现雪花噪点,优先降pclk_hz,其次检查低压差线性稳压器供电是否稳定,给屏幕的3.3V供电不建议直接从板载的LDO引,最好用单独的稳压模块给屏幕供电。
6. 常见问题与排查技巧实录
6.1 编译烧录类问题速查
| 现象 | 可能原因 | 快速解法 |
|---|---|---|
| 烧录时报“A fatal error occurred: Failed to connect to ESP32-S3” | 芯片没有进入下载模式 | 按住BOOT再上电,或检查USB线的数据通道 |
| 烧录时报“Timed out waiting for packet header” | 串口波特率太高或芯片供电不稳 | 降低烧录波特率到460800,检查USB口是否直连主机(不要经过USB Hub) |
| 编译后烧录成功但上电没反应 | 程序panic或Flash原因 | 打开插件里的Monitor查看日志,在menuconfig里开启Core Dump方便定位 |
| 日志输出乱码 | 串口监视器波特率不对 | ESP-IDF默认日志波特率也是115200,但如果你改过menuconfig,要同步改插件串口设置 |
| 编译速度慢到怀疑人生 | 没有设置增量编译缓存 | 首次编译后不要随便clean;把ESP-IDF放到固态硬盘路径里 |
6.2 外设调试类问题速查
| 现象 | 可能原因 | 快速解法 |
|---|---|---|
| WS2812颜色错乱 | GRB和RGB顺序配错 | 确认led_model为LED_MODEL_WS2812,或者手动设置color_component_format为GRB |
| I2S麦克风读到的全是0或噪声 | PDM引脚配置错误 | 确认CLK和DATA引脚是否正确,slot_mask对不对,GPIO需要设置成输入模式 |
| Wi-Fi扫不到热点 | 天线射频匹配问题 | 检查板载天线或外接天线座,部分开发板需要手动焊接天线跳线电阻 |
| 屏幕白屏 | SPI初始化失败或屏幕供电不足 | 先用逻辑分析仪抓SPI时序,再量屏幕VCC是否为3.3V |
| BLE配网卡在验证阶段 | 安全密钥不匹配 | 确认service_key和手机App输入的POP一致,大小写敏感 |
6.3 隐藏最深的两个坑
第一个坑:不要用劣质Type-C线,不要用USB Hub。ESP32-S3在烧录时对USB信号质量有一定要求,劣质线材和HUB会增加电压降和信号抖动,导致烧录时好时坏。实测下来,很多“连不上芯片”“烧录到一半失败”的问题,换一根短线、直接插电脑主板USB口之后,奇迹般就解决了。
第二个坑:Flash加密和Secure Boot不要一上来就开。在menuconfig里如果你勾选了Flash Encryption或Secure Boot,第一次烧录后芯片会被写入加密密钥,后续如果不小心把Flash擦除了,芯片就成板砖了,需要用烧录器连串口和特定的保险丝恢复流程才能救回来。新手阶段,这不是你需要关心的功能,千万别碰。
7. 最后的经验:学习ESP32-S3的正确路径,避免三分钟热度
环境搭建这关过了之后,很多人反而不知道怎么继续学了——因为例程太多,选择困难。根据我个人的经验,比较合理的路径是:
先把板载的硬件全部点亮一遍,LED、按键、麦克风、屏幕、摄像头,每个外设都跑一个最小例程,这个过程让你对硬件资源建立直觉;然后用BLE或Wi-Fi把这块板子和手机、电脑连接起来,体会“设备联网”的完整链路,这个节点你会真正理解什么是物联网;最后再回过来,把之前跑过的LED渐变和麦克风检测结合起来,做成一个“声音控制灯光颜色”的小项目——虽然简单,但你已经完成了环境搭建、外设驱动、传感器数据处理、执行器控制、无线通信这五个核心环节的串联。
我在实际调试过程中感触最深的是:ESP32-S3的坑,大多数不是芯片本身的问题,而是环境问题、接线问题、供电问题和抄代码时引脚定义没改的问题。遇到卡壳时,先看一眼日志,再看一眼接线,最后再怀疑芯片——这个排查顺序能帮你省下大量时间。
如果后续想深入,可以试着把ESP-SR的离线语音识别跑起来,或者把摄像头采集的视频通过Wi-Fi推流到手机,这两件事都能在N16R8这个配置上流畅运行。到那时候,你会发现在这块几十块钱的板子上,你能做的事情远远超过预期。