15-WiFi通信与ESP32-C3.md 11 KB


tags: [source-summary] type: source source: "尚硅谷嵌入式技术之STM32单片机(高级篇)V2.0.1 — WiFi章节 + 配套代码10~11" author: "尚硅谷研究院" date: 2026-07-15

created: 2026-07-15

WiFi通信与ESP32-C3

用生活理解:ESP32-C3 就像一个随身 WiFi 翻译官——你的单片机不会说 WiFi,但 ESP32-C3 会。你用串口告诉它:"连这个路由器"、"发这串数据到这个 IP",它帮你搞定所有 WiFi 通信。AT 指令就是你和翻译官之间的暗号手册。


ESP32-C3 简介

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 不兼容(不同内核、不同指令集)

AT 指令工作模式

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 指令 预期响应 说明
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 设置当前串口参数(波特率/数据位/停止位/校验/流控)

WiFi 操作指令

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"

TCP/UDP 通信指令

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)            → 退出透传

实验:ESP32-C3 TCP 通信

项目路径stm32/10_wifi_test_halstm32/11_wifi_tcp_server_hal

软件设计(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=1AT+CIPSEND > 3s
退出透传 +++(无换行,20ms 间隔) OK
关闭连接 AT+CIPCLOSE CLOSED 5s

常见问题与避坑

  1. AT 指令无响应 → 检查波特率(确保一致)、TX↔RX 交叉连接、模块电源(峰值 500mA 需足够供电)
  2. WiFi 连不上 → 仅支持 2.4GHz(不支持 5GHz)、检查 SSID 密码、AP 是否隐藏
  3. TCP 连接失败 → 检查目标 IP 可达性、端口是否开放、防火墙规则
  4. 透传模式数据回显ATE0 关闭回显;否则发送的数据会同时从 ESP 返回
  5. +++ 退不出透传 → 要求前后 20ms 无数据,保证足够间隔
  6. 数据长度错 → 非透传下,AT+CIPSEND=len 的 len 必须与后续发送的数据字节数严格一致