首页 / 学习路径 / 第 01 章 · 开发环境搭建与第一个程序
01
入门 · 必做

开发环境搭建与第一个程序

这一章要把「工具链」这件事彻底解决:装好 Arduino IDE、装好 ESP32 开发板核心、认识你的第一块开发板、看懂每一个引脚的作用,然后让板载 LED 闪起来。这一步看起来简单,却是后面所有章节的地基——工具链不通,后面全是空谈。

阅读时长 约 35 分钟硬件 2 件实战案例 1 个前置要求 无
1

本章要点

Arduino IDE 本身只认识 AVR / ATmega 芯片。ESP32 的能力全部来自第三方「开发板核心」——在开发板管理器里添加网址 https://espressif.github.io/arduino-esp32/package_esp32_index.json 之后,才能在菜单里看到 ESP32 Dev Module 并选择它。理解这一点,你就不会再疑惑「为什么我装了 IDE 却找不到 ESP32 板子」。

ESP32 DevKit V1 的板载 LED 接在 GPIO2 上,且是低电平点亮——这一点与 Arduino UNO 恰好相反。写 digitalWrite(LED_PIN, HIGH) 反而会让它熄灭。这个细节能帮你省掉大量「LED 不亮」的排查时间。

上传失败的三大原因,几乎占了新手全部的卡壳时间:① 没装 USB 转串口驱动(CH340 或 CP2102)② 用了只有电源线芯的充电线 ③ 板子需要手动按住 BOOT 键进入下载模式。

2

硬件清单与原理

名称数量作用与原理
ESP32 DevKit V11 块核心控制器。双核 32 位 Xtensa,240MHz,520KB SRAM,内置 WiFi + 蓝牙 + 霍尔传感器。板载 USB 转串口芯片用于下载程序与串口通信。
微型 USB 数据线1 根既供电又传输数据。必须是数据线——纯充电线没有数据线芯,电脑识别不到 COM 口。
板载 LED1 个接在 GPIO2 上,低电平点亮。若你的板子没有板载 LED,可外接 GPIO2 → 220Ω → LED 阳极,阴极接 GND。
3

接线说明

ESP32 ESP32 DevKit V1 GPIO2 板载 LED GPIO2 GND 信号 220Ω 限流 LED GND 共地 接线示意 · 外接 LED 版(板载 LED 已免接线)
本章无需外接元件,直接使用板载 LED。

板载 LED 已在出厂时接好:GPIO2 连接 LED,LED 另一端连接 GND

若你的板子没有板载 LED,可按以下方式外接:

① GPIO2 → [220Ω 电阻] → LED 阳极(长脚)

② LED 阴极(短脚) → GND

提示:LED 长脚为阳极、短脚为阴极,接反不会亮,也不会烧。

4

实战案例 01-1 · 让板载 LED 闪起来

功能用途

验证开发环境是否配置成功、芯片是否正常工作、代码能否正确烧录。

预期现象

LED 以 1 秒为周期闪烁;串口监视器(115200)每半秒打印一行状态日志。

ch01_blink.ino编译通过
/*
 * ============================================================================
 * 第 1 章 · 实战案例 01-1:让板载 LED 闪起来
 * ----------------------------------------------------------------------------
 * 硬件清单:
 *   - ESP32 DevKit V1 开发板 × 1
 *   - 微型 USB 数据线 × 1(注意必须是数据线,不能用只充电的线)
 *   - 板载 LED(GPIO2)—— 部分开发板没有板载 LED,可外接:GPIO2 → 220Ω 电阻 → LED 阳极,
 *     LED 阴极 → GND
 *
 * 功能用途:
 *   验证「开发环境是否配置成功、芯片是否正常工作、代码能否正确烧录」这三件事。
 *   这是所有 ESP32 学习的第一个里程碑,必须先看到灯闪,后面才有意义。
 *
 * 预期现象:
 *   1. 板载 LED 以 1 秒为周期闪烁(亮 500ms / 灭 500ms)
 *   2. Arduino IDE 串口监视器(波特率 115200)每半秒打印一行状态日志
 * ============================================================================
 */

#include <Arduino.h>   // 引入 Arduino 核心头文件,提供 pinMode / digitalWrite / millis 等基础 API

/* ==========================================================================
 * 一、引脚定义
 * ESP32 DevKit V1 的板载 LED 正极接 3V3、负极接 GPIO2,
 * 因此 GPIO2 输出低电平(LOW)时 LED 才点亮——这一点和 Arduino UNO 相反。
 * ======================================================================== */
#define LED_PIN 2        // 板载 LED 所连接的 GPIO 编号

/* ==========================================================================
 * 二、可调参数(初学者最爱改的地方,改完直接重新烧录即可看效果)
 * ======================================================================== */
const class="kw">unsigned long ON_TIME_MS  = 500;   // LED 点亮持续时间,单位毫秒
const class="kw">unsigned long OFF_TIME_MS = 500;   // LED 熄灭持续时间,单位毫秒

/* ==========================================================================
 * 三、状态变量
 * ======================================================================== */
class="kw">unsigned long lastToggleTime = 0;        // 记录「上一次切换亮灭状态」的时刻(开机以来的毫秒数)
bool          ledIsOn       = false;     // 记录 LED 当前是「亮」还是「灭」

/* ==========================================================================
 * 四、初始化函数 setup()
 * 特点:主板复位后只执行一次,用来完成所有「一次性」的准备工作。
 * ======================================================================== */
void setup() {
  // 启动串口通信,波特率设为 115200(必须与串口监视器右下角的设置一致,否则会看到乱码)
  Serial.begin(115200);

  // 等待 200 毫秒,给 USB 转串口芯片(CH340/CP2102)留出枚举时间。
  // 如果不等待,setup 里立刻打印的中文有可能变成乱码,这是新手最常见的「玄学问题」之一。
  delay(200);

  // 把 LED 引脚配置为「输出」模式。ESP32 的引脚默认是「输入」,
  // 不写这一句的话 digitalWrite 不会有任何效果。
  pinMode(LED_PIN, OUTPUT);

  // 设置 LED 初始状态为熄灭。注意这里是 LOW 而不是 HIGH,原因是板载 LED 低电平点亮。
  digitalWrite(LED_PIN, LOW);

  Serial.println();                                     // 打印一个空行,让监视器排版更清爽
  Serial.println(class="st">"[LED] 初始化完成,2 秒后开始闪烁");  // 打印中文日志(UTF-8 编码,正常显示)
  Serial.println(class="st">"[LED] 引脚 GPIO2 | 亮 500ms / 灭 500ms");

  delay(2000);  // 等待 2 秒,给初学者一点时间看到这行日志再开始闪
}

/* ==========================================================================
 * 五、主循环函数 loop()
 * 特点:setup() 结束后会无限重复执行,是程序真正「干活」的地方。
 * ======================================================================== */
void loop() {
  // millis() 返回「开机到此刻经过的毫秒数」,类型为 unsigned long。
  // 用它做计时,可以避免 delay() 阻塞整个程序。
  class="kw">unsigned long now = millis();

  // 判断:距离上次切换是否已经过了足够时间?
  // 用 now - lastToggleTime 而不是直接比较,是因为 millis() 运行约 49 天后会溢出回 0,
  // 做减法能让溢出被自动处理,这是 Arduino 社区的通行写法。
  class="kw">unsigned long currentDuration = ledIsOn ? ON_TIME_MS : OFF_TIME_MS;

  if (now - lastToggleTime >= currentDuration) {
    // 取反当前状态:亮 → 灭,灭 → 亮
    ledIsOn = !ledIsOn;

    // 真正驱动硬件。由于板载 LED 是「低电平点亮」,所以:
    //   ledIsOn 为 true(要亮)→ 输出 LOW
    //   ledIsOn 为 false(要灭)→ 输出 HIGH
    digitalWrite(LED_PIN, ledIsOn ? LOW : HIGH);

    // 更新基准时刻,否则下一轮判断会立刻再次成立,造成疯狂闪烁
    lastToggleTime = now;

    // 打印状态日志,方便和肉眼看到的灯做对照
    Serial.print(class="st">"[LED] 当前状态:");
    Serial.println(ledIsOn ? class="st">"ON(点亮)" : class="st">"OFF(熄灭)");
  }
}
完整源码 98 行 · ch01_blink/ch01_blink.inoarduino-cli 编译通过
5

本章小结

① Arduino IDE 本身只识别 AVR 芯片,ESP32 的能力来自第三方开发板核心,必须在开发板管理器里添加网址后才能看到 ESP32 板型。

② 上传失败的三大原因:USB 驱动未装、用了充电线、没按 BOOT 键进下载模式。

③ setup() 只执行一次,loop() 无限重复,这是 Arduino 程序的固定骨架。

④ 板载 LED 在 GPIO2 上是低电平点亮,与 Arduino UNO 相反,写 HIGH 会熄灭。

⑤ 用 millis() 做计时优于 delay(),前者不会阻塞整个程序。

6

本章练习

练习 1

把 ON_MS 改成 100、OFF_MS 改成 900,观察闪烁节奏变化。

练习 2

把 LED_PIN 改成 4,外接一个 LED 到 GPIO4,验证新引脚是否生效。

练习 3

在 setup() 末尾加一句 Serial.println,观察它打印几次——验证 setup() 只执行一次。

练习 4

故意删掉 pinMode(LED_PIN, OUTPUT) 再烧录,记录现象并解释原因。

7

下一章

02
NEXT · 第 02 章

C/C++ 语言基础

用 8 路跑马灯把变量、循环、数组、函数全部跑一遍——这一章决定你能不能读懂后面所有代码。

开始学习