tags: [source-summary] type: source source: "尚硅谷嵌入式技术之STM32单片机(高级篇)V2.0.1 — WiFi章节 + 配套代码10~11" author: "尚硅谷研究院" date: 2026-07-15
用生活理解:ESP32-C3 就像一个随身 WiFi 翻译官——你的单片机不会说 WiFi,但 ESP32-C3 会。你用串口告诉它:"连这个路由器"、"发这串数据到这个 IP",它帮你搞定所有 WiFi 通信。AT 指令就是你和翻译官之间的暗号手册。
ESP32-C3 是乐鑫科技(Espressif)推出的RISC-V 32 位WiFi + BLE 5.0 芯片。
| 特性 | 值 |
|---|---|
| 内核 | RISC-V 32 位单核,最高 160MHz |
| WiFi | 802.11 b/g/n, 2.4GHz(仅 2.4GHz,不支持 5GHz) |
| BLE | Bluetooth 5.0 (LE) |
| RAM | 400KB SRAM |
| Flash | 4MB |
| 接口 | UART、SPI、I2C、I2S、PWM、ADC |
| 工作模式 | Station(连接路由器)/ SoftAP(自建热点)/ Station+AP |
参考:乐鑫 ESP32-C3 数据手册、ESP32-C3 AT 指令集用户手册 注意:ESP32-C3 与 ESP8266 不兼容(不同内核、不同指令集)
ESP32-C3 默认出厂固件为AT 指令模式——芯片从 Flash 启动后,通过串口接收 AT 指令并返回响应。
通信方式:
STM32(USART) ── TX ──→ RX(ESP32-C3)
── RX ←── TX(ESP32-C3)
── GND ── GND
响应格式:每条指令执行后返回 \r\nOK\r\n 或 \r\nERROR\r\n
| AT 指令 | 预期响应 | 说明 |
|---|---|---|
AT\r\n |
OK |
测试连接是否正常 |
AT+RST\r\n |
ready |
软复位模块 |
AT+GMR\r\n |
版本信息 | 查看 AT 固件版本 |
ATE0\r\n |
OK |
关闭回显(默认开启,ATE1=开) |
AT+UART_CUR=115200,8,1,0,0\r\n |
OK |
设置当前串口参数(波特率/数据位/停止位/校验/流控) |
| AT 指令 | 说明 | 响应 |
|---|---|---|
AT+CWMODE=1\r\n |
Station 模式(连路由器) | OK |
AT+CWMODE=2\r\n |
SoftAP 模式(自建热点) | OK |
AT+CWMODE=3\r\n |
Station + AP 模式 | OK |
AT+CWJAP="SSID","password"\r\n |
连接指定 WiFi | WIFI CONNECTED/WIFI DISCONNECT |
AT+CWQAP\r\n |
断开当前 WiFi | OK |
AT+CWLAP\r\n |
扫描附近 WiFi 列表 | +CWLAP:enc,auth,ssid,rssi,mac |
AT+CIFSR\r\n |
查询本地 IP 地址 | +CIFSR:STAIP,"192.168.x.x" |
| AT 指令 | 说明 | 响应 |
|---|---|---|
AT+CIPSTART="TCP","ip",port\r\n |
建立 TCP 连接 | CONNECT |
AT+CIPSTART="UDP","ip",port\r\n |
建立 UDP 连接 | CONNECT |
AT+CIPMODE=1\r\n |
开启透传模式 | OK |
AT+CIPSEND\r\n |
透传模式下开始发送(出现 > 提示符) |
> |
AT+CIPSEND=len\r\n |
发送指定长度的数据(非透传) | > 后发数据 |
AT+CIPSTATUS\r\n |
查询连接状态 | STATUS:3(已连接)/STATUS:4(已断开) |
AT+CIPCLOSE\r\n |
关闭当前连接 | CLOSED |
AT+CIPMUX=0\r\n |
单连接模式 | OK |
AT+CIPMUX=1\r\n |
多连接模式(最多 5 个) | OK |
透传模式(Transparent Transmission)下,进入 AT+CIPSEND 后出现的 > 提示符,此后所有串口输入数据自动转发到 TCP 连接,收到的 TCP 数据也自动从串口输出。
退出透传模式:在 20ms 内没有数据的时间间隔后,发送 +++(不需要换行回车),可退出透传返回 AT 指令模式。
非透传模式(CIPMODE=0):
AT+CIPSEND=5\r\n → 发送指令
> → 提示符
Hello → 发送 5 字节
SEND OK → 完成
透传模式(CIPMODE=1):
AT+CIPMODE=1\r\n
OK
AT+CIPSEND\r\n
> → 进入透传
Hello World... → 所有串口数据直接变为 TCP 数据发送
+++(间隔20ms) → 退出透传
项目路径:stm32/10_wifi_test_hal、stm32/11_wifi_tcp_server_hal
基础 AT 通信测试 — 文件:stm32/10_wifi_test_hal/Core/Src/main.c
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "esp32.h"
/* USER CODE END Includes */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
// MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
printf("尚硅谷Wi-Fi通信实验:AT指令...\n");
// 初始化ESP32
ESP32_Init();
printf("ESP32 初始化完成!\n");
// 1. 发送AT测试
uint8_t *cmd = "AT\r\n";
ESP32_SendCmd(cmd, strlen((char *)cmd));
// 2. 查看固件版本信息
cmd = "AT+GMR\r\n";
ESP32_SendCmd(cmd, strlen((char *)cmd));
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
TCP 服务器 — 文件:stm32/11_wifi_tcp_server_hal/Core/Src/main.c
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "wifi.h"
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
// 全局变量定义,数据缓冲区及其长度、连接id、对端IP和端口号
uint8_t rxBuff[1024];
uint16_t rxLen;
uint8_t id;
uint8_t ip[16];
uint16_t port;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
// MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
printf("尚硅谷Wi-Fi通信实验:TCP服务器...\n");
// 1. WiFi初始化
WIFI_Init(AP);
// 2. 启动TCP服务器
WIFI_TCP_ServerStart();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
// 3. 从套接字读取
WIFI_TCP_ReadData(rxBuff, &rxLen, &id, ip, &port);
// 4. 如果收到数据,原样发送回去
if (rxLen > 0)
{
printf("收到数据:连接ID = %d, 对端IP:端口号 = %s:%d, 数据长度 = %d, 内容 = %.*s\n",
id, ip, port, rxLen, rxLen, rxBuff);
WIFI_TCP_SendData(id, rxBuff, rxLen);
// 清空长度0
rxLen = 0;
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
| 操作 | AT 指令 | 等待响应 | 超时 |
|---|---|---|---|
| 测试连接 | AT |
OK |
2s |
| 设置 Station | AT+CWMODE=1 |
OK |
1s |
| 扫描 WiFi | AT+CWLAP |
OK |
10s |
| 连接 WiFi | AT+CWJAP="SSID","pwd" |
WIFI GOT IP |
15s |
| 查询 IP | AT+CIFSR |
OK |
2s |
| TCP 连接 | AT+CIPSTART="TCP",ip,port |
CONNECT |
10s |
| 发送数据 | AT+CIPSEND=len → 数据 |
SEND OK |
5s |
| 进入透传 | AT+CIPMODE=1 → AT+CIPSEND |
> |
3s |
| 退出透传 | +++(无换行,20ms 间隔) |
OK |
— |
| 关闭连接 | AT+CIPCLOSE |
CLOSED |
5s |
ATE0 关闭回显;否则发送的数据会同时从 ESP 返回