系列文章目录

持续更新…



前言

Wi-Fi(Wireless Fidelity)是一种基于 IEEE 802.11 标准的无线局域网技术,常用于在电子设备之间建立网络连接。在 ESP32-S3 中,Wi-Fi 模块集成了 2.4 GHz 射频收发器,支持 802.11b/g/n 协议(最高可达150 Mbps的物理层速率),允许设备连接互联网或本地局域网。相比传统单片机外接 Wi-Fi 模块,ESP32-S3 的 Wi-Fi 内置于芯片,不仅提供 STA(Station)模式用于连接路由器,支持 SoftAP(软件接入点)模式建立自身热点,也能同时以 STA+AP 模式工作。本文将详细介绍 ESP32-S3 的 Wi-Fi 功能,包括主要特性、工作原理、常用的数据类型和 API,并通过示例代码展示如何进行网络连接。


一、Wi-Fi概述

1. 主要特性

ESP32-S3 内置的 Wi-Fi 系统具备以下主要特性:
1.模式支持: 提供 Station 模式(STA,作为客户端连接现有无线网络)、SoftAP 模式(作为热点建立新的无线网络)以及 STA+AP 共存模式(同时作为客户端和热点)。这种多样的模式支持使 ESP32-S3 能够灵活应用于各种物联网场景,例如既连接家庭路由器又创建本地配置热点。
2.网络协议: 支持 802.11 b/g/n 协议,其中 802.11b 最大11 Mbps、802.11g 最大54 Mbps,而 802.11n 可通过更高效的调制在2.4 GHz下实现更高吞吐。相比更先进的 802.11ac(5 GHz, 最高1.3 Gbps)标准,ESP32-S3 不支持 5 GHz Wi-Fi,但其 2.4 GHz Wi-Fi 已能满足大多数物联网数据传输需求。
3.安全机制: 支持多种 Wi-Fi加密认证模式,包括开放网络、WEP、WPA/WPA2-PSK、WPA2/WPA3-PSK混合模式,以及新一代的 WPA3-SAE 安全协议。在 Station 模式下,可根据需要设置最低接受的安全协议(例如只连接不低于 WPA2 的网络),SoftAP 模式下也可配置热点的加密方式(如 WPA2-PSK 或 WPA/WPA2 混合模式)。这些安全特性保证了网络连接的机密性和完整性。
4.多连接与并发: SoftAP 模式下,ESP32-S3 最多可接受 10 个站点设备同时接入。同时,在 STA+AP 双模共存时,设备能一边通过 STA 接入上级路由器互联网,一边通过 AP 供其他设备连接,相当于一个简易中继或网关。ESP32-S3 内部妥善处理双模下的资源分配和射频共存,确保并发通信的稳定。
5.其他功能: 支持 扫描 周围 Wi-Fi 接入点(包括主动扫描和被动监听),开发者可获取附近网络的 SSID、信号强度、信道等信息;支持 Wi-Fi直连(P2P)和 ESP-NOW 等简化协议用于设备间直连通信;以及 混杂模式 捕获空中无线帧,方便实现包分析和信号监测。此外,ESP32-S3 的 Wi-Fi 模块还能与 Bluetooth LE 无线共存。

2. Wi-Fi架构及工作原理

ESP32-S3 的 Wi-Fi 软件架构采用 事件驱动模型,由 Wi-Fi驱动(Wi-Fi Driver)、TCP/IP协议栈、事件任务和用户应用任务共同构成。Wi-Fi 驱动作为底层模块,处理 IEEE 802.11 协议的收发、加解密和连接管理,上层通过调用提供的 API 与之交互。整个运行过程中:Wi-Fi驱动将重要状态变化以事件(event)的形式上报,ESP32 的系统 事件任务 捕获这些事件并调用默认处理,然后将事件转发给用户注册的应用回调函数,从而触发相应的应用逻辑。这种架构保证了 Wi-Fi 通信的实时性和可靠性,也简化了应用程序对复杂 Wi-Fi 状态的管理。
Wi-Fi 驱动与事件任务、应用任务的交互示意图
在这里插入图片描述
STA 模式中,ESP32-S3 作为客户端,会先执行扫描(若指定了特定信道或 BSSID 则可跳过部分扫描)来寻找目标 AP,然后发起 认证(Authentication) 和 关联(Association) 请求。认证通过后建立加密密钥,Association 完成后 STA 就正式加入无线网络。随后,ESP32-S3 (STA)通过 AP 的 DHCP 服务获取 IP地址,进入联网就绪状态。当启用了 ESP-IDF 的 esp_netif 组件时,这一过程中的 DHCP 客户端会由系统自动启动并配置网络接口。整个连接过程中若发生错误(如密码错误、超时等),Wi-Fi 驱动会发送相应事件(如 WIFI_EVENT_STA_DISCONNECTED),应用可在事件回调中尝试重连或采取其他措施。

SoftAP 模式下,ESP32-S3 扮演无线接入点角色,周期性广播 Beacon帧 宣告自身SSID存在,周围设备(STA)可扫描到。当一个 STA 设备请求加入时,会经历类似的认证和关联流程(由 ESP32-S3 验证STA提供的密码),认证通过后完成关联,STA获取到由 ESP32-S3 分配的 IP 地址(ESP32-S3 SoftAP 默认作为 DHCP服务器)。ESP32-S3 可通过事件 WIFI_EVENT_AP_STACONNECTED / WIFI_EVENT_AP_STADISCONNECTED 获知有设备加入或离开热点,从而统计当前连接数或触发其他管理操作。值得一提的是,SoftAP 下可以通过设置 wifi_config_t.ap.ssid_hidden 来控制是否隐藏SSID,通过 beacon_interval 来调整 Beacon发送频率,以平衡连接延迟和功耗。

3. STA 模式连接过程

在 Station 模式 下,ESP32-S3 连接 Wi-Fi 的完整过程包括以下步骤:
🌟初始化阶段: 应用程序首先初始化 TCP/IP 协议栈(调用 esp_netif_init())并创建默认事件循环,然后配置 Wi-Fi 初始化参数并调用 esp_wifi_init() 初始化 Wi-Fi 驱动。接着设置 Wi-Fi 工作模式为 STA (esp_wifi_set_mode(WIFI_MODE_STA)),以及要连接的路由器的 SSID/密码等参数(通过 esp_wifi_set_config())。这些配置通常在应用启动时完成。

🌟启动阶段: 调用 esp_wifi_start() 启动 Wi-Fi 模块。此时 Wi-Fi 驱动开始工作,并通过事件 WIFI_EVENT_STA_START 通知应用 Wi-Fi已就绪。典型地,应用在捕获到该事件后调用 esp_wifi_connect(),触发后续的连接流程。

🌟扫描与连接阶段: Wi-Fi 驱动接收到连接指令后,开始按配置进行扫描和连接。首先若指定了 BSSID或信道则进行定向扫描,否则进行全信道扫描以查找目标AP。找到匹配的AP后,驱动发送认证请求并进行四次握手(WPA/WPA2情况下)建立安全连接,然后发送关联请求加入网络。如果上述过程成功,Wi-Fi 驱动会上报事件 WIFI_EVENT_STA_CONNECTED。系统事件任务将在处理该事件时自动启动 DHCP 客户端以获取 IP。如果连接过程中失败(例如AP未找到或认证失败),则会上报 WIFI_EVENT_STA_DISCONNECTED 事件,指明失败原因。应用可在回调中选择重试连接或者其它处理。

🌟获取IP阶段: 如果 DHCP 请求成功,ESP32-S3 将获得分配的 IP 地址。此时将产生 IP_EVENT_STA_GOT_IP 事件,表示 STA 已成功接入网络。应用程序通常在收到此事件后开始进行后续的网络通信任务(切勿在 IP 未就绪时就创建 socket 发送数据,否则将失败)。
在这里插入图片描述

至此,ESP32-S3 已作为 STA 正常连接到 Wi-Fi 网络,可以收发数据包,与外部互联网或局域网设备通信。连接建立后,ESP32-S3 STA 会持续监测与 AP 间的连接质量。当信号变差或 AP 关闭时,可能触发 WIFI_EVENT_STA_DISCONNECTED 事件,通知连接中断。默认策略下 Wi-Fi 驱动会自动尝试重连,应用也应在此事件中关闭或重置已有的网络通信。若重连成功并再次获取IP,将重新收到 GOT_IP 事件。整个 STA 模式下的连接维护由 Wi-Fi驱动和 esp_netif 自动管理,开发者更多关注事件处理即可。

4. SoftAP 模式工作过程

ESP32-S3 配置为 SoftAP 模式 时,会创建一个Wi-Fi热点,使其它设备能够连接进来。SoftAP 的运行流程如下:
🔥启动热点: 应用需先初始化 Wi-Fi 驱动(过程与 STA 模式相同),然后调用 esp_wifi_set_mode(WIFI_MODE_AP) 切换为 AP 模式,并通过 esp_wifi_set_config() 设置 AP 参数,包括 SSID、密码、信道、最大连接数等。接着调用 esp_wifi_start() 启动 SoftAP。启动后,ESP32-S3 将持续发送 Beacon 帧公告热点信息。启动成功时会产生事件 WIFI_EVENT_AP_START,表明热点已就绪。

🔥设备接入: 当有站点设备请求连接时,首先ESP32-S3会根据配置进行验证:如果设置了密码则进行 WPA/WPA2 身份验证,没有密码则直接开放。验证通过后,设备发起关联请求,ESP32-S3 允许其加入并为其分配一个 AID(关联 ID)和 IP 地址。每当有新的站点成功连接,Wi-Fi 驱动会产生事件 WIFI_EVENT_AP_STACONNECTED。通过该事件的数据,应用可以获取连接设备的 MAC 地址及分配的 AID。应用可在事件回调中记录或显示连接设备的信息。

🔥数据通信: 站点加入后即可通过 ESP32-S3 这个 AP 进行数据通信。ESP32-S3 会充当这些站点的网关,将数据转发到自身 STA 接入的网络(如果处于AP+STA模式),或在本地实现站点间通信。SoftAP 模式下默认IP为 192.168.4.1,子网掩码255.255.255.0,开发者也可以通过 tcpip_adapter 或 esp_netif 接口调整 DHCP 地址范围。ESP32-S3 内部处理所有 Wi-Fi 收发和ARP路由逻辑,上层应用若需与连接的站点通信,可使用标准的套接字编程进行网络收发。

🔥设备离开: 如果某站点主动断开或因为信号原因掉线,ESP32-S3 会释放其连接并产生事件 WIFI_EVENT_AP_STADISCONNECTED。该事件包含离线设备的 MAC 和先前的 AID,可用于应用层更新当前连接设备列表。SoftAP 将继续运行等待新的设备加入,除非调用 esp_wifi_stop() 停止热点或达到最大连接数上限。SoftAP 默认信道为1,可根据需要修改 wifi_config_t.ap.channel 来避免与环境中其他 Wi-Fi 干扰,但连接后的站点必须工作在 SoftAP 设置的信道上。
在这里插入图片描述
SoftAP 模式常用于局域场景或作为配网手段ESP32-S3 的 SoftAP 可以通过调整 max_connection 限制接入终端数量,通过 authmode 设置安全等级(如开放或WPA2),通过 ssid_hidden 决定是否隐藏网络。当 SoftAP 不再需要时,调用 esp_wifi_stop() 可关闭热点并释放资源。

5. STA+AP 并发模式

ESP32-S3 允许 STA 与 SoftAP 同时工作,即开启 STA+AP 双模式(又称 APSTA 模式)。在这种模式下,ESP32-S3 一边连接上级路由器获取互联网连接,一边作为热点供其他设备连接,相当于一个网络桥接器或中继。其工作特点如下:
🍀配置方法: 应用层需将 Wi-Fi 模式设为 WIFI_MODE_APSTA,并分别配置 STA 部分和 AP 部分参数(即调用两次 esp_wifi_set_config(),接口选择 WIFI_IF_STA 和 WIFI_IF_AP)。启动 Wi-Fi 后,ESP32-S3 将并行地尝试连接上级路由器并启动自身热点。两个接口运行在同一无线频段,SoftAP 的信道会和 STA 所连接的 AP 信道保持一致(ESP32 Wi-Fi 驱动会自动协调信道)。

🍀资源共享: STA 与 AP 共存时,共用同一收发无线电和内部 Wi-Fi缓冲。ESP32-S3 Wi-Fi 驱动通过高效的中断处理和队列机制确保双接口的数据帧都能及时收发。当 STA 正在高流量传输时,SoftAP 仍能发送 Beacon 及处理管理帧,只是整体带宽由两部分共享。一般情况下,STA+AP 模式对每个接口的最大吞吐略有影响,但足以满足大多数中等流量应用。

🍀常见应用场景: STA+AP 模式可以用于Wi-Fi信号中继(比如 ESP32-S3 连入家庭Wi-Fi的同时开设一个本地热点扩展覆盖范围)或 设备配置(设备上线时通过 SoftAP 提供配置页面,手机连接配置后设备再通过 STA 接入正式网络)。
在这里插入图片描述

总的来说,STA+AP 模式赋予了 ESP32-S3 更强大的网络角色灵活性。但开发者也需留意其内存占用和无线频谱利用率较单一模式有所增加。在实际应用中,根据需求选择合适的模式,充分发挥 ESP32-S3 Wi-Fi 的能力。

二、Wi-Fi网络连接数据类型及相关API

Wi-Fi 网络连接相关数据类型定义

/**
 * @brief Wi-Fi工作模式枚举
 */
typedef enum {
    WIFI_MODE_NULL = 0,    /*!< 空模式(关闭Wi-Fi) */
    WIFI_MODE_STA,         /*!< Station 模式 (STA,无线客户端) */
    WIFI_MODE_AP,          /*!< SoftAP 模式 (AP,无线接入点) */
    WIFI_MODE_APSTA,       /*!< STA+AP 混合模式 */
    // WIFI_MODE_NAN       /*!< NAN 模式 (Wi-Fi Aware) - 视芯片支持而定 */
} wifi_mode_t;

/**
 * @brief Wi-Fi接口枚举
 */
typedef enum {
    WIFI_IF_STA = 0,  /*!< Station 接口 (STA 模式下使用) */
    WIFI_IF_AP        /*!< SoftAP 接口 (AP 模式下使用) */
} wifi_interface_t;

/**
 * @brief Wi-Fi安全认证模式枚举
 */
typedef enum {
    WIFI_AUTH_OPEN = 0,         /*!< 无加密 (开放网络) */
    WIFI_AUTH_WEP,              /*!< WEP 加密 (不推荐) */
    WIFI_AUTH_WPA_PSK,          /*!< WPA-PSK 加密 */
    WIFI_AUTH_WPA2_PSK,         /*!< WPA2-PSK 加密 */
    WIFI_AUTH_WPA_WPA2_PSK,     /*!< WPA/WPA2 混合加密 */
    WIFI_AUTH_WPA3_PSK,         /*!< WPA3-SAE 加密 */
    WIFI_AUTH_WPA2_WPA3_PSK,    /*!< WPA2/WPA3 混合模式 */
    WIFI_AUTH_MAX
} wifi_auth_mode_t;

/**
 * @brief Wi-Fi快速扫描阈值配置
 * @note Station模式下可设置连接的最低要求,如信号强度和加密等级
 */
typedef struct {
    int8_t rssi;                /*!< 信号强度阈值(最小接受的RSSI,单位dBm) */
    wifi_auth_mode_t authmode;  /*!< 最低接受的安全模式,例如 WIFI_AUTH_WPA2_PSK */
} wifi_scan_threshold_t;

/**
 * @brief Station模式配置结构体
 * @note 用于配置ESP32作为STA连接外部AP的参数
 */
typedef struct {
    uint8_t ssid[32];                   /*!< 目标AP的SSID */
    uint8_t password[64];               /*!< 目标AP的密码 */
    bool bssid_set;                     /*!< 是否指定AP的BSSID(MAC地址);false为不指定 */
    uint8_t bssid[6];                   /*!< 目标AP的BSSID(如果 bssid_set=true,则需填写) */
    uint8_t channel;                    /*!< 目标AP的信道(不确定填0,将自动扫描) */
    wifi_scan_threshold_t threshold;    /*!< 快速扫描阈值,仅连接符合条件的AP */
    // 其他字段如 listen_interval, pmf_cfg 等在一般应用中使用默认值
} wifi_sta_config_t;

/**
 * @brief SoftAP模式配置结构体
 * @note 用于配置ESP32作为热点的参数
 */
typedef struct {
    uint8_t ssid[32];               /*!< SoftAP的SSID名称 */
    uint8_t password[64];           /*!< SoftAP的密码 */
    uint8_t ssid_len;               /*!< SSID长度(0表示自动按字符串长度计算) */
    uint8_t channel;                /*!< SoftAP信道(1~13,需与区域法规一致) */
    wifi_auth_mode_t authmode;      /*!< 加密模式 (WIFI_AUTH_OPEN/WPA2_PSK/WPA_WPA2_PSK 等) */
    uint8_t ssid_hidden;            /*!< 是否隐藏SSID(1隐藏,0广播) */
    uint8_t max_connection;         /*!< 最大连接站点数 (1~10) */
    uint16_t beacon_interval;       /*!< Beacon帧发送间隔(单位:ms) */
} wifi_ap_config_t;

/**
 * @brief 通用Wi-Fi配置结构体
 */
typedef union {
    wifi_sta_config_t sta;          /*!< Station配置 */
    wifi_ap_config_t ap;            /*!< SoftAP配置 */
} wifi_config_t;

Wi-Fi 网络连接相关 API

/**
 * @brief 初始化Wi-Fi驱动
 * 
 * 分配Wi-Fi驱动所需资源(控制结构体、缓存等)并创建Wi-Fi任务。此API需在调用任何其他Wi-Fi API之前调用。
 * 
 * @param[in] cfg  指向 Wi-Fi 初始化配置结构体的指针,一般使用 WIFI_INIT_CONFIG_DEFAULT() 宏填充默认值后再调整
 * @return 
 *      - ESP_OK: 初始化成功 
 *      - ESP_ERR_NO_MEM: 内存不足,无法完成初始化 
 *      - ESP_ERR_WIFI_NOT_INIT: 底层Wi-Fi子系统未就绪(如Wi-Fi未启用) 
 */
esp_err_t esp_wifi_init(const wifi_init_config_t *cfg);

/**
 * @brief 关闭Wi-Fi驱动
 * 
 * 释放 esp_wifi_init 分配的所有资源,并停止Wi-Fi任务。
 * 
 * @return 
 *      - ESP_OK: 操作成功 
 *      - ESP_ERR_WIFI_NOT_INIT: Wi-Fi驱动尚未初始化 
 */
esp_err_t esp_wifi_deinit(void);

/**
 * @brief 设置Wi-Fi工作模式
 * 
 * 设置 ESP32 Wi-Fi 的运行模式,可选 STA模式、AP模式或 STA+AP 混合模式。默认上电模式为 STA。
 * 
 * @param[in] mode  要切换的 Wi-Fi模式 (参见 wifi_mode_t 枚举) 
 * @return 
 *      - ESP_OK: 设置成功 
 *      - ESP_ERR_WIFI_NOT_INIT: Wi-Fi驱动未初始化 
 *      - ESP_ERR_INVALID_ARG: 参数错误(mode不在有效范围) 
 */
esp_err_t esp_wifi_set_mode(wifi_mode_t mode);

/**
 * @brief 启动 Wi-Fi
 * 
 * 根据当前配置启动 Wi-Fi 驱动。若模式为 STA,则启动 station 控制块并开始连接流程;若模式为 AP,则启动 SoftAP 控制块开始广播;若模式为 APSTA,则同时启动 STA和AP。
 * 
 * @return 
 *      - ESP_OK: 成功启动 
 *      - ESP_ERR_WIFI_NOT_INIT: Wi-Fi驱动未初始化 
 *      - ESP_ERR_WIFI_CONN: 内部状态错误,启动失败 
 *      - ESP_ERR_NO_MEM: 内存不足,启动失败 
 */
esp_err_t esp_wifi_start(void);

/**
 * @brief 停止 Wi-Fi
 * 
 * 停止 Wi-Fi 活动。若当前模式为 STA,则断开 station 并释放资源;若为 AP,则关闭 SoftAP 并释放资源;APSTA模式将同时停止两种接口。
 * 
 * @return 
 *      - ESP_OK: 停止成功 
 *      - ESP_ERR_WIFI_NOT_INIT: Wi-Fi驱动未初始化 
 */
esp_err_t esp_wifi_stop(void);

/**
 * @brief 设置 Wi-Fi 配置参数
 * 
 * 将 Wi-Fi 参数配置应用到指定接口(STA 或 AP)。需在初始化后、启动之前调用。对于 STA 接口,此API通常用于设置要连接的 SSID、密码等;对于 AP 接口则设置热点信息。
 * 
 * @param[in] interface  接口枚举 (WIFI_IF_STA 或 WIFI_IF_AP)
 * @param[in] conf       指向 Wi-Fi 配置结构体的指针 (wifi_config_t),根据 interface 不同其 sta 或 ap 字段有效
 * @return 
 *      - ESP_OK: 配置成功 
 *      - ESP_ERR_WIFI_NOT_INIT: Wi-Fi驱动未初始化 
 *      - ESP_ERR_INVALID_ARG: 参数无效(如 interface 非法) 
 *      - ESP_ERR_NO_MEM: 内存不足,无法保存配置 
 */
esp_err_t esp_wifi_set_config(wifi_interface_t interface, const wifi_config_t *conf);

/**
 * @brief 发起 Wi-Fi 扫描
 * 
 * 扫描周围的 Wi-Fi 网络。可以设置扫描参数并选择是否阻塞等待结果。
 * 
 * @param[in]  config  扫描参数指针(wifi_scan_config_t),可为 NULL 表示使用默认全信道主动扫描 
 * @param[in]  block   是否同步阻塞等待扫描完成:true 则函数阻塞直到完成,false 则立即返回,扫描完成通过事件通知 
 * @return 
 *      - ESP_OK: 成功开始扫描 
 *      - ESP_ERR_WIFI_NOT_INIT: Wi-Fi驱动未初始化 
 *      - ESP_ERR_WIFI_MODE: 当前模式下不支持扫描(如Wi-Fi已停止) 
 */
esp_err_t esp_wifi_scan_start(const wifi_scan_config_t *config, bool block);

/**
 * @brief 获取扫描到的AP列表数量
 * 
 * 调用 esp_wifi_scan_start 完成后,可用此API获取扫描结果中找到的 AP 总数。
 * 
 * @param[out] number  指向存储AP数量的变量指针
 * @return 
 *      - ESP_OK: 获取成功 
 *      - ESP_ERR_WIFI_NOT_INIT: Wi-Fi驱动未初始化 
 *      - ESP_ERR_INVALID_STATE: 尚未进行过扫描或扫描结果无效 
 */
esp_err_t esp_wifi_scan_get_ap_num(uint16_t *number);

/**
 * @brief 获取扫描的AP详细信息
 * 
 * 获取上次扫描的各AP记录,包括SSID、BSSID、信道、RSSI等信息。需提供足够大小的数组缓冲。
 * 
 * @param[in,out] number      输入时为准备获取的最大AP数,调用后填充为实际获取的AP数 
 * @param[out]    ap_records  指向 wifi_ap_record_t 数组的指针,用于输出AP信息 
 * @return 
 *      - ESP_OK: 获取成功,ap_records 填充完成 
 *      - ESP_ERR_WIFI_NOT_INIT: Wi-Fi驱动未初始化 
 *      - ESP_ERR_INVALID_ARG: 参数无效(如 number 或 ap_records 为空) 
 */
esp_err_t esp_wifi_scan_get_ap_records(uint16_t *number, wifi_ap_record_t *ap_records);

/**
 * @brief Station模式连接 Wi-Fi
 * 
 * 开始按照上次配置的 STA 参数连接到指定AP。成功调用后将触发异步的连接流程(产生 WIFI_EVENT_STA_CONNECTED 或 WIFI_EVENT_STA_DISCONNECTED 等事件)。
 * 
 * @return 
 *      - ESP_OK: 开始连接 
 *      - ESP_ERR_WIFI_NOT_INIT: Wi-Fi驱动未初始化 
 *      - ESP_ERR_WIFI_MODE: 当前非 STA模式,无法执行 
 */
esp_err_t esp_wifi_connect(void);

/**
 * @brief 断开 Station模式下的 Wi-Fi 连接
 * 
 * 主动断开当前 STA 正在连接或已连接的 Wi-Fi。断开后将产生 WIFI_EVENT_STA_DISCONNECTED 事件。
 * 
 * @return 
 *      - ESP_OK: 已开始断开 
 *      - ESP_ERR_WIFI_NOT_INIT: Wi-Fi驱动未初始化 
 *      - ESP_ERR_WIFI_MODE: 当前非 STA模式 
 */
esp_err_t esp_wifi_disconnect(void);

/**
 * @brief 设置 Wi-Fi 配置存储类型
 * 
 * 指定 Wi-Fi 参数(如 esp_wifi_set_config 设置的内容)保存的位置。
 * 
 * @param[in] storage  存储类型:WIFI_STORAGE_FLASH(保存到NVS Flash),WIFI_STORAGE_RAM(仅运行时内存)
 * @return 
 *      - ESP_OK: 设置成功 
 *      - ESP_ERR_WIFI_NOT_INIT: Wi-Fi驱动未初始化 
 */
esp_err_t esp_wifi_set_storage(wifi_storage_t storage);

三、Wi-Fi网络连接示例程序

示例 1:STA 模式连接指定 AP

/*
 * ESP32-S3 WiFi STA(Station)模式连接示例
 * 本程序演示如何让ESP32作为WiFi客户端连接到路由器
 */

#include <string.h>            // 字符串处理函数
#include "freertos/FreeRTOS.h" // FreeRTOS实时操作系统
#include "freertos/task.h"     // 任务管理
#include "esp_wifi.h"          // WiFi驱动
#include "esp_event.h"         // 事件处理
#include "esp_log.h"           // 日志输出
#include "esp_netif.h"         // 网络接口
#include "nvs_flash.h"         // 非易失性存储

// ======================== 用户配置区域 ========================
// 请修改以下两行为您要连接的WiFi信息
#define WIFI_SSID "ssid"           // 替换为您的WiFi名称
#define WIFI_PASSWORD "password" // 替换为您的WiFi密码

// 定义日志标签,用于在串口监视器中识别输出信息
static const char *TAG_STA = "wifi_sta";

/*
 * WiFi事件处理函数 - 这是程序的核心部分
 *
 * 参数说明:
 * - arg: 用户数据(本例中未使用)
 * - event_base: 事件类型(WIFI_EVENT 或 IP_EVENT)
 * - event_id: 具体的事件ID
 * - event_data: 事件携带的数据
 *
 * 这个函数会在WiFi状态发生变化时自动被调用
 */
static void wifi_event_handler(void *arg,
                               esp_event_base_t event_base,
                               int32_t event_id,
                               void *event_data)
{
    // 处理WiFi相关事件
    if (event_base == WIFI_EVENT)
    {
        switch (event_id)
        {
        case WIFI_EVENT_STA_START:
            // WiFi启动完成,开始尝试连接到指定的路由器
            esp_wifi_connect();
            ESP_LOGI(TAG_STA, "WiFi已启动,正在尝试连接到路由器...");
            break;

        case WIFI_EVENT_STA_CONNECTED:
            // 成功连接到路由器(但还没有获取到IP地址)
            ESP_LOGI(TAG_STA, "成功连接到路由器,等待获取IP地址...");
            break;

        case WIFI_EVENT_STA_DISCONNECTED:
            // WiFi连接断开,自动重新连接
            ESP_LOGW(TAG_STA, "WiFi连接断开,正在尝试重新连接...");
            // 连接失败后自动重连
            esp_wifi_connect();
            break;

        default:
            break;
        }
    }
    // 处理IP相关事件
    else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
    {
        // 成功获取到IP地址,WiFi连接完全建立
        ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
        char ip[16]; // 用于存储IP地址字符串

        // 将IP地址从数字格式转换为字符串格式
        esp_ip4addr_ntoa(&event->ip_info.ip, ip, sizeof(ip));
        ESP_LOGI(TAG_STA, "WiFi连接成功!获取到IP地址: %s", ip);
    }
}

/*
 * WiFi STA模式初始化函数
 *
 * 这个函数完成以下工作:
 * 1. 初始化NVS存储(WiFi驱动需要用到)
 * 2. 初始化网络栈
 * 3. 创建事件循环
 * 4. 初始化WiFi驱动
 * 5. 注册事件处理函数
 * 6. 配置WiFi参数
 * 7. 启动WiFi
 */
static void wifi_init_sta(void)
{
    // 第1步:初始化NVS (Non-Volatile Storage) 非易失性存储
    // WiFi驱动需要用NVS来保存校准数据和配置信息
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        // 如果NVS分区有问题,就擦除并重新初始化
        ESP_ERROR_CHECK(nvs_flash_erase());
        ESP_ERROR_CHECK(nvs_flash_init());
    }

    // 第2步:初始化TCP/IP网络栈
    ESP_ERROR_CHECK(esp_netif_init());

    // 第3步:创建默认的事件循环(用于处理WiFi事件)
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    // 第4步:创建默认的WiFi STA网络接口
    esp_netif_create_default_wifi_sta();

    // 第5步:初始化WiFi驱动
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    // 第6步:注册事件处理函数
    // 注册WiFi事件处理器(处理连接、断开等事件)
    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
                                                        ESP_EVENT_ANY_ID,
                                                        &wifi_event_handler,
                                                        NULL,
                                                        NULL));
    // 注册IP事件处理器(处理获取IP地址事件)
    ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
                                                        IP_EVENT_STA_GOT_IP,
                                                        &wifi_event_handler,
                                                        NULL,
                                                        NULL));

    // 第7步:设置WiFi工作模式为STA(Station,即客户端模式)
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));

    // 第8步:配置WiFi连接参数
    wifi_config_t wifi_config = {
        .sta = {
            .ssid = WIFI_SSID,                        // 要连接的WiFi名称
            .password = WIFI_PASSWORD,                // WiFi密码
            .threshold.authmode = WIFI_AUTH_WPA2_PSK, // 最低安全认证模式
        },
    };
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));

    // 第9步:启动WiFi
    // 启动后会自动触发WIFI_EVENT_STA_START事件,然后开始连接
    ESP_ERROR_CHECK(esp_wifi_start());

    ESP_LOGI(TAG_STA, "WiFi STA 初始化完成!配置连接到 SSID: %s", WIFI_SSID);
}

/*
 * 程序主入口函数
 *
 * 这是ESP32程序的起始点,类似于C语言的main函数
 * 程序会从这里开始执行
 */
void app_main(void)
{
    // 调用WiFi初始化函数,开始WiFi连接过程
    wifi_init_sta();

    // 主循环:让程序一直运行,不退出
    // 因为WiFi连接是通过事件处理的,所以主程序只需要保持运行即可
    while (true)
    {
        // 每隔1秒休眠一次,释放CPU资源给其他任务
        // 这是FreeRTOS的任务延时函数
        vTaskDelay(pdMS_TO_TICKS(1000)); // 1000毫秒 = 1秒
    }
}

示例 2:SoftAP 模式创建热点

/*
 * ESP32-S3 WiFi AP(热点)模式示例
 * 
 * 本程序演示如何让ESP32作为WiFi热点(Access Point),
 * 
 * 功能:
 * - 创建名为"esp32_ap"的WiFi热点
 * - 密码为"12345678"
 * - 最多支持4个设备同时连接
 * - 显示连接和断开的设备信息
 */

#include <string.h>               // 字符串处理函数
#include "freertos/FreeRTOS.h"    // FreeRTOS实时操作系统
#include "freertos/task.h"        // 任务管理
#include "esp_wifi.h"             // WiFi驱动
#include "esp_event.h"            // 事件处理
#include "esp_log.h"              // 日志输出
#include "esp_netif.h"            // 网络接口
#include "nvs_flash.h"            // 非易失性存储

// ======================== 用户配置区域 ========================
#define AP_WIFI_SSID "esp32_ap"      // AP热点名称,可以修改为您想要的名称
#define AP_WIFI_PASSWORD "12345678"  // AP热点密码,至少8位字符
#define AP_MAX_STA_CONN 4            // 最大同时连接设备数,范围:1-10
#define AP_CHANNEL 1                 // WiFi信道,范围:1-13

// 定义日志标签,用于在串口监视器中识别输出信息
static const char *TAG_AP = "wifi_ap";

/*
 * WiFi AP事件处理函数 - 处理热点相关事件
 * 
 * 参数说明:
 * - arg: 用户数据(本例中未使用)
 * - event_base: 事件类型(这里主要是WIFI_EVENT)
 * - event_id: 具体的事件ID
 * - event_data: 事件携带的数据
 * 
 * 这个函数会在AP状态发生变化时自动被调用
 */
static void wifi_ap_event_handler(void *arg,                    // 用户参数指针(未使用)
                                  esp_event_base_t event_base,  // 事件基础类型
                                  int32_t event_id,             // 事件ID
                                  void *event_data)             // 事件数据指针
{
    // 检查是否为WiFi事件
    if (event_base == WIFI_EVENT)
    {
        // 根据具体的事件ID进行不同处理
        switch (event_id)
        {
        case WIFI_EVENT_AP_START:
            // AP热点启动完成事件
            ESP_LOGI(TAG_AP, "SoftAP已启动,等待客户端连接...");
            break;
            
        case WIFI_EVENT_AP_STACONNECTED:
        {
            // 有设备连接到我们的热点事件
            // 获取连接事件的详细数据
            wifi_event_ap_staconnected_t *conn = (wifi_event_ap_staconnected_t *)event_data;
            // 输出连接设备的MAC地址和分配的AID
            ESP_LOGI(TAG_AP, "客户端加入: MAC=%02x:%02x:%02x:%02x:%02x:%02x,AID=%d",
                     conn->mac[0], conn->mac[1], conn->mac[2],    // MAC地址前3字节
                     conn->mac[3], conn->mac[4], conn->mac[5],    // MAC地址后3字节
                     conn->aid);                                   // 分配的关联ID
            break;
        }
        
        case WIFI_EVENT_AP_STADISCONNECTED:
        {
            // 有设备从我们的热点断开事件
            // 获取断开事件的详细数据
            wifi_event_ap_stadisconnected_t *disc = (wifi_event_ap_stadisconnected_t *)event_data;
            // 输出断开设备的MAC地址和对应的AID
            ESP_LOGI(TAG_AP, "客户端离开: MAC=%02x:%02x:%02x:%02x:%02x:%02x,AID=%d",
                     disc->mac[0], disc->mac[1], disc->mac[2],    // MAC地址前3字节
                     disc->mac[3], disc->mac[4], disc->mac[5],    // MAC地址后3字节
                     disc->aid);                                   // 对应的关联ID
            break;
        }
        
        default:
            // 其他未处理的WiFi事件
            break;
        }
    }
}

/*
 * WiFi SoftAP(软接入点)初始化函数
 * 
 * 这个函数完成以下工作:
 * 1. 初始化NVS存储(WiFi驱动需要用到)
 * 2. 初始化网络栈
 * 3. 创建事件循环
 * 4. 初始化WiFi驱动
 * 5. 注册事件处理函数
 * 6. 配置AP参数(SSID、密码、信道等)
 * 7. 启动AP热点
 * 8. 显示AP的IP地址
 */
static void wifi_init_softap(void)
{
    // 第1步:初始化NVS (Non-Volatile Storage) 非易失性存储
    // WiFi驱动需要用NVS来保存校准数据和配置信息
    esp_err_t ret = nvs_flash_init();                            // 尝试初始化NVS
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        // 如果NVS分区有问题,就擦除并重新初始化
        ESP_ERROR_CHECK(nvs_flash_erase());                     // 擦除NVS分区
        ESP_ERROR_CHECK(nvs_flash_init());                      // 重新初始化NVS
    }

    // 第2步:初始化TCP/IP网络栈
    ESP_ERROR_CHECK(esp_netif_init());                          // 初始化网络接口层
    
    // 第3步:创建默认的事件循环(用于处理WiFi事件)
    ESP_ERROR_CHECK(esp_event_loop_create_default());           // 创建默认事件循环
    
    // 第4步:创建默认的WiFi AP网络接口
    esp_netif_create_default_wifi_ap();                         // 创建AP网络接口

    // 第5步:初始化WiFi驱动
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();        // 使用默认WiFi配置
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));                       // 初始化WiFi驱动

    // 第6步:注册事件处理函数
    // 注册WiFi事件处理器(处理AP启动、客户端连接/断开等事件)
    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,      // 事件类型:WiFi事件
                                                        ESP_EVENT_ANY_ID, // 事件ID:所有WiFi事件
                                                        &wifi_ap_event_handler, // 事件处理函数
                                                        NULL,              // 用户数据(未使用)
                                                        NULL));            // 事件处理器实例(未使用)

    // 第7步:配置AP参数
    wifi_config_t ap_config = {0};                              // 初始化配置结构体为0
    
    // 设置AP的SSID(热点名称)
    strncpy((char *)ap_config.ap.ssid, AP_WIFI_SSID, sizeof(ap_config.ap.ssid)); // 复制SSID字符串
    ap_config.ap.ssid_len = strlen(AP_WIFI_SSID);               // 设置SSID长度
    
    // 设置AP的密码
    strncpy((char *)ap_config.ap.password, AP_WIFI_PASSWORD, sizeof(ap_config.ap.password)); // 复制密码字符串
    
    // 设置WiFi信道(1-13)
    ap_config.ap.channel = AP_CHANNEL;                          // 设置工作信道
    
    // 设置最大连接设备数(1-10)
    ap_config.ap.max_connection = AP_MAX_STA_CONN;              // 设置最大连接数
    
    // 设置加密方式为WPA/WPA2-PSK
    ap_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK;             // 设置加密模式
    
    // 如果密码为空,则设置为开放模式(不推荐)
    if (strlen(AP_WIFI_PASSWORD) == 0)
    {
        ap_config.ap.authmode = WIFI_AUTH_OPEN;                 // 设置为开放模式(无密码)
    }

    // 第8步:设置WiFi工作模式为AP(接入点模式)
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));           // 设置为AP模式
    
    // 第9步:应用AP配置
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &ap_config)); // 应用AP配置

    // 第10步:启动WiFi!
    ESP_ERROR_CHECK(esp_wifi_start());                          // 启动WiFi服务

    // 输出配置信息
    ESP_LOGI(TAG_AP, "SoftAP初始化完成!SSID:%s  密码:%s  信道:%d  最大连接数:%d",
             AP_WIFI_SSID, AP_WIFI_PASSWORD, AP_CHANNEL, AP_MAX_STA_CONN);

    // 第11步:获取并显示AP的IP地址
    esp_netif_t *ap_netif = esp_netif_get_handle_from_ifkey("WIFI_AP_DEF"); // 获取AP网络接口句柄
    if (ap_netif)                                               // 如果获取成功
    {
        esp_netif_ip_info_t ip_info;                            // IP信息结构体
        if (esp_netif_get_ip_info(ap_netif, &ip_info) == ESP_OK) // 获取IP信息
        {
            char ip[16];                                         // 用于存储IP地址字符串
            esp_ip4addr_ntoa(&ip_info.ip, ip, sizeof(ip));      // 将IP地址转换为字符串
            ESP_LOGI(TAG_AP, "SoftAP IP地址: %s", ip);        // 输出IP地址
        }
    }
}

/*
 * 程序主入口函数
 * 
 * 这是ESP32程序的起始点,类似于C语言的main函数
 * 程序会从这里开始执行
 */
void app_main(void)
{
    // 调用WiFi AP初始化函数,启动热点模式
    wifi_init_softap();                                         // 初始化并启动WiFi热点
    
    // 主循环:让程序一直运行,不退出
    // 因为WiFi AP是通过事件处理的,所以主程序只需要保持运行即可
    while (true)                                                // 无限循环
    {
        // 每隔1秒休眠一次,释放CPU资源给其他任务
        // 这是FreeRTOS的任务延时函数
        vTaskDelay(pdMS_TO_TICKS(1000));                        // 延时1000毫秒 = 1秒
    }
}

总结

通过上述内容,我们全面阐述了 ESP32-S3 上 Wi-Fi 功能的原理与应用。ESP32-S3 强大的 Wi-Fi 模块使其能够在物联网项目中作为通信中枢,实现设备联网、远程数据传输和本地无线交互。开发者在使用时应充分利用事件回调机制处理连接状态变化,并合理配置安全参数确保网络可靠。相信通过本文的讲解和示例代码,读者可以更自信地掌握 ESP32-S3 Wi-Fi 的使用,在项目中实现稳定的无线连接功能。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐