ESP32 — Hello World
难度: ⭐(零基础入门)
开发框架: ESP-IDF
源文件: project_test/main/hello_world_main.c
这个实验是干嘛的?
这是 ESP32 的"Hello World"——上电后打印芯片信息,然后倒计时重启。
通过这个实验你将学会:
- ESP-IDF 项目的基本结构
- ESP32 的
app_main() 入口函数(不是 main()!)
- 如何读取芯片信息(型号、核心数、Flash 大小)
- FreeRTOS 任务的基本用法
硬件准备
- ESP32 开发板(任意型号)
- USB 数据线(Micro USB 或 Type-C,看板子)
- 电脑端串口助手(115200 波特率)
ESP32 与传统 MCU 的区别
| 特性 |
传统 MCU(STM32/GD32) |
ESP32 |
| 入口函数 |
main() |
app_main() |
| 操作系统 |
无(裸机)或 FreeRTOS |
内置 FreeRTOS |
| 延时函数 |
delay_ms() |
vTaskDelay() |
| 编译系统 |
Keil/IAR |
CMake + ESP-IDF |
| WiFi/蓝牙 |
需外接模块 |
内置 |
| 内存管理 |
无 |
动态内存(heap) |
关键区别:ESP32 基于 FreeRTOS,你的代码运行在一个 RTOS 任务里,不是裸机。
完整代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
/*
* SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-License-Identifier: CC0-1.0
*/
#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h" // SDK 配置(menuconfig 生成)
#include "freertos/FreeRTOS.h" // FreeRTOS 头文件
#include "freertos/task.h" // 任务管理
#include "esp_chip_info.h" // 芯片信息 API
#include "esp_flash.h" // Flash 信息 API
#include "esp_system.h" // 系统 API
/* ESP32 的入口函数(不是 main,是 app_main!) */
void app_main(void)
{
printf("Hello world!\n");
/* 第一步:读取芯片信息 */
esp_chip_info_t chip_info;
uint32_t flash_size;
esp_chip_info(&chip_info);
printf("This is %s chip with %d CPU core(s), %s%s%s%s, ",
CONFIG_IDF_TARGET, // 芯片型号(编译时确定)
chip_info.cores, // CPU 核心数
(chip_info.features & CHIP_FEATURE_WIFI_BGN) ? "WiFi/" : "",
(chip_info.features & CHIP_FEATURE_BT) ? "BT" : "",
(chip_info.features & CHIP_FEATURE_BLE) ? "BLE" : "",
(chip_info.features & CHIP_FEATURE_IEEE802154) ? ", 802.15.4 (Zigbee/Thread)" : "");
/* 第二步:打印芯片版本 */
unsigned major_rev = chip_info.revision / 100;
unsigned minor_rev = chip_info.revision % 100;
printf("silicon revision v%d.%d, ", major_rev, minor_rev);
/* 第三步:读取 Flash 大小 */
if (esp_flash_get_size(NULL, &flash_size) != ESP_OK) {
printf("Get flash size failed");
return;
}
printf("%" PRIu32 "MB %s flash\n", flash_size / (uint32_t)(1024 * 1024),
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");
/* 第四步:打印最小剩余堆内存 */
printf("Minimum free heap size: %" PRIu32 " bytes\n",
esp_get_minimum_free_heap_size());
/* 第五步:倒计时 10 秒后重启 */
for (int i = 10; i >= 0; i--) {
printf("Restarting in %d seconds...\n", i);
vTaskDelay(1000 / portTICK_PERIOD_MS); // 延时 1 秒
}
printf("Restarting now.\n");
fflush(stdout);
esp_restart(); // 软件重启
}
|
代码分段讲解
1. 入口函数
ESP32 的入口是 app_main(),不是 main()!
main() 在 ESP-IDF 内部被 FreeRTOS 使用了,你的代码写在 app_main() 里。ESP-IDF 启动时会自动创建一个 FreeRTOS 任务来运行 app_main()。
2. 芯片信息
1
2
|
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
|
esp_chip_info() 返回一个结构体,包含:
chip_info.cores — CPU 核心数(ESP32 是 2 核)
chip_info.features — 芯片能力标志位(WiFi、蓝牙、BLE 等)
chip_info.revision — 芯片版本号
3. FreeRTOS 延时
1
|
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
不要用 delay_ms()! ESP32 基于 FreeRTOS,必须用 RTOS 的延时函数:
vTaskDelay(1000) — 延时 1000 个 tick
portTICK_PERIOD_MS — 每个 tick 多少毫秒(通常 1ms)
1000 / portTICK_PERIOD_MS = 延时 1000ms = 1 秒
vTaskDelay 是非阻塞的,延时期间 CPU 可以运行其他任务。
4. 系统重启
软件重启,相当于按复位键。重启后程序从头开始运行。
实验现象
串口助手(115200 波特率)输出:
1
2
3
4
5
6
7
8
9
|
Hello world!
This is esp32 chip with 2 CPU core(s), WiFi/BT/BLE, silicon revision v3.0,
4MB external flash
Minimum free heap size: 287432 bytes
Restarting in 10 seconds...
Restarting in 9 seconds...
...
Restarting in 0 seconds...
Restarting now.
|
然后芯片自动重启,重复输出。
常见问题
Q: 串口没有输出?
- 检查 USB 线是否支持数据传输(有些只能充电)
- 检查串口驱动(CP2102 或 CH340)
- 波特率设 115200
- ESP32 上电后会先输出 bootloader 日志,然后才是你的程序
Q: 编译报错找不到 ESP-IDF?
- 确认已安装 ESP-IDF 并设置了环境变量
- 运行
source export.sh(Linux)或 export.bat(Windows)
Q: 想用 Arduino 方式写?
- Arduino IDE 里入口是
setup() 和 loop()
setup() 对应 app_main() 的初始化部分
loop() 对应 while(1) 主循环
小结
| 概念 |
说明 |
app_main() |
ESP32 的入口函数(不是 main()) |
esp_chip_info() |
读取芯片型号、核心数、能力 |
vTaskDelay() |
FreeRTOS 非阻塞延时 |
esp_restart() |
软件重启 |
| FreeRTOS |
ESP32 内置的实时操作系统 |
拓展应用
学了 ESP32 能做什么?最大的优势是自带 WiFi 和蓝牙:
| 项目 |
原理 |
难度 |
| 智能家居开关 |
WiFi + MQTT + 继电器 |
⭐⭐⭐ |
| 物联网温度计 |
WiFi 上传数据到云平台 |
⭐⭐ |
| 蓝牙遥控小车 |
BLE 连接手机控制电机 |
⭐⭐⭐ |
| WiFi 遥控器 |
ESP32 建 Web 服务器,手机浏览器控制 |
⭐⭐⭐ |
| 网络摄像头 |
ESP32-CAM + WiFi 视频流 |
⭐⭐⭐⭐ |
| 天气显示屏 |
WiFi 获取天气 API,E-ink 显示 |
⭐⭐⭐ |
| OTA 远程升级 |
WiFi 下载新固件,自动更新 |
⭐⭐⭐⭐ |
| 蓝牙音箱 |
A2DP 蓝牙音频流 |
⭐⭐⭐⭐ |
核心思路:ESP32 的核心价值是联网能力。传统 MCU 需要外接 WiFi/蓝牙模块才能联网,ESP32 自带。任何需要"联网"的项目,ESP32 都是首选。