当前位置: 首页 > news >正文

STM32f103ZET6之ESP8266模块

一、ESP8265概述

        官方网址:ESP8266 Wi-Fi MCU I 乐鑫科技 (espressif.com.cn)

        ESP8266模块---wifi模块
        产品特点:

ESP8266 是什么?

        ESP8266 是由乐鑫科技(Espressif Systems)开发的一款低成本、高性能的 Wi-Fi 微控制器芯片 / 模块,集成了 32 位 Tensilica L106 处理器、Wi-Fi 射频(802.11 b/g/n)、TCP/IP 协议栈,以及丰富的 GPIO 引脚和外设接口(I2C、SPI、UART 等)。

        

        它的核心优势是 **“低成本实现 Wi-Fi 联网”**—— 相比传统的 “MCU + 独立 Wi-Fi 模块” 方案,ESP8266 直接将处理器和 Wi-Fi 功能集成,成本可低至几美元,且体积小巧(常见模块如 ESP-12F 尺寸仅 24mm×16mm),因此成为物联网(IoT)领域的 “明星产品”。

ESP8266 能干什么?

ESP8266 的核心功能是 **“让设备接入 Wi-Fi 网络”**,因此被广泛用于需要联网的场景,典型应用包括:

  • 物联网(IoT)设备:如智能传感器(温湿度、光照、烟雾传感器)的数据上传(发送到云端服务器或手机);
  • 智能家居:控制灯光、窗帘、空调等设备(通过 Wi-Fi 接收手机 APP 指令);
  • 远程监控:连接摄像头或传感器,实时向手机推送数据;
  • Wi-Fi 网关:将其他协议(如蓝牙、ZigBee)的设备数据转换为 Wi-Fi 信号转发;
  • 简易服务器:作为小型 Web 服务器,通过浏览器直接控制设备(例如网页按钮控制灯光开关)。

1. ESP8266中的wifi:

         ESP8266EX支持TCP/IP协议,完全遵循802.11 b/g/n WLAN MAC协议,支持分布式控制功能(DCF)下的基本服务集(BSS)STA和SoftAP操作。支持通过最小化主机交互来优化有效工作时长,以实现功耗管理。

         我们主要使用esp8266的wifi功能:

2.AT指令集的概念:

        AT指令是应用于终端设备与PC应用之间的连接与通信的指令。AT Attention。每个AT命令行中只能 包含一条AT指令;对于AT指令的发送,除AT两个字符外,最多可以接收1056个字符的长度(包括最后的空字符)。
        格式: AT + CMD

3. ESP8266引脚:

 需要配置的引脚:

1. 复位:

2. 使能管脚:

3.  电源部分:

4.  串口

以下为单片机与ESP8266的连接方式:

启动模式:

         程序正常运行,我们需要保证使能位和RST,必须拉高

二、ESP8266的联网步骤

步骤AT 指令(串口发送)期望返回作用说明
1AT+CWMODE=1OK设为 STA 模式
2AT+RST重启日志 + ready + OK重启生效模式
3AT+CWJAP="MyWiFi","1234"WIFI CONNECTED
WIFI GOT IP
OK
连 Wi-Fi 成功
4AT+CIPMUX=0OK设为单连接模式
5AT+CIPSTART="TCP","192.168.1.100",8888CONNECT OK连 TCP 服务器成功
6AT+CIPMODE=1OK开透传模式
7AT+CIPSEND>进入透传,可直接发数据
8Hello Server!(无返回,直接传给服务器)透传数据
9+++(发之前停 1 秒)OK退出透传,切回 AT 指令模式

1. AT+CWMODE=1:设置工作模式(STA 模式)

  • 作用:让 ESP8266 作为「Station(站点)」,即像手机、电脑一样,去连接外部 Wi-Fi 热点。
  • 模式说明
    • Station:用作客户端,是需要连接路由器或者热点
      SoftAP:用作服务器端,本身可以作为热点使用
      SoftAP+Station:混合模式。
  • 实操
    串口发送 AT+CWMODE=1,收到 OK 则设置成功。

2. AT+RST:模块重启(让工作模式生效)
  • 作用:ESP8266 是 “单片机思维”,改完模式后需重启才能真正切换。
  • 细节
    发送 AT+RST 后,模块会重启,串口会打印一堆启动日志(如 ready 等),最后回到可接收 AT 指令状态。

3. AT+CWJAP="SSID","PASSWORD":连接 Wi-Fi 热点

  • 作用:让 ESP8266 接入你指定的 Wi-Fi 网络。
  • 参数说明
    • SSID:你要连的 Wi-Fi 名称(字符串,必须用英文双引号包裹)
    • PASSWORD:Wi-Fi 密码(同理,英文双引号包裹,无密码则填 "" )
  • 实操
    比如连名为 MyWiFi、密码 12345678 的 Wi-Fi,发送:
    AT+CWJAP="MyWiFi","12345678"
    
    等待几秒,收到 WIFI CONNECTED(连成功) + WIFI GOT IP(分配到 IP) + OK,则联网完成。

4. AT+CIPMUX=0:设置单路连接模式

  • 作用:告诉模块,接下来要建立 1 对 1 的 TCP/UDP 连接(单连接模式)。
  • 模式说明
    • CIPMUX=0:单连接(同一时间只能连 1 个服务器)
    • CIPMUX=1:多连接(可同时连多个服务器,需配合 AT+CIPSERVER 等指令)
  • 何时用
    如果你只是想连一个服务器(比如传数据到自己的云平台),选 0 更简单。

5. AT+CIPSTART="TCP","IP地址",端口号:建立 TCP 连接

  • 作用:让 ESP8266 主动连到你指定的 TCP 服务器(比如自己电脑开的 TCP 服务、云平台)。
  • 参数说明
    • TCP:协议类型(也支持 UDP,按需换)
    • IP地址:服务器的公网 / 局域网 IP(比如本地调试填 192.168.1.100,云平台填 47.xxx.xxx.xxx )
    • 端口号:服务器监听的端口(如 8080 3333,需和服务器程序对应)
  • 实操
    比如连本地电脑(IP 192.168.1.100,端口 8888)的 TCP 服务,发送:
    AT+CIPSTART="TCP","192.168.1.100",8888
    
    收到 CONNECT OK 则连接成功,失败会返回 CONNECT FAIL(检查 IP、端口、服务器是否开启)。

6. AT+CIPMODE=1:开启透传模式

  • 作用:进入「透传」状态 —— 你从串口发的所有数据,会直接透传给 TCP/UDP 服务器,无需额外加指令头(反之,服务器发的数据也会直接返回串口)。
  • 对比普通模式
    • 普通模式(CIPMODE=0)发数据,需先 AT+CIPSEND=长度,再发内容(麻烦);
    • 透传模式(CIPMODE=1)发数据,直接敲内容就行(简单,适合持续传数据)。

7. AT+CIPSEND:进入透传数据发送

  • 作用:在透传模式下,执行这条指令后,模块进入 “数据直通” 状态。
  • 实操
    发送 AT+CIPSEND 后,串口会返回 >,此时你输入的任何内容(比如 Hello Server! ),都会直接通过 TCP 发给服务器,无需额外处理。

8. +++:退出透传模式
  • 作用:从透传状态切回 “AT 指令模式”,方便你发其他 AT 指令(比如断网、改配置)。
  • 关键细节
    发 +++ 时,必须保证串口没有其他数据同时发送(即发 +++ 前后,要等 1 秒左右无数据,否则模块可能识别成普通数据)。
    成功退出后,串口会返回 OK,此时可继续发 AT+CWQAP(断开 Wi-Fi)等指令。

 

三、具体代码案例

1.esp8266.c:

#include "esp8266.h"
#include "delay.h"
#include "stdio.h"
#include "string.h"
#include "esp_data.h"
//配置串口+ESP8266使能和复位
void usart3_Init(u32 brr)
{GPIO_InitTypeDef GPIOInitTypeDef;USART_InitTypeDef USARTInitTypeDef;//打开时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);//配置PB10--TX PB11--RX//PB10--复用推挽输出GPIOInitTypeDef.GPIO_Pin=GPIO_Pin_10;GPIOInitTypeDef.GPIO_Mode=GPIO_Mode_AF_PP;GPIOInitTypeDef.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIOInitTypeDef);//PB11--浮空GPIOInitTypeDef.GPIO_Pin=GPIO_Pin_11;GPIOInitTypeDef.GPIO_Mode=GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOB,&GPIOInitTypeDef);//usart3的配置USARTInitTypeDef.USART_BaudRate=brr;USARTInitTypeDef.USART_HardwareFlowControl=USART_HardwareFlowControl_None;USARTInitTypeDef.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;USARTInitTypeDef.USART_Parity=USART_Parity_No;USARTInitTypeDef.USART_StopBits=USART_StopBits_1;USARTInitTypeDef.USART_WordLength=USART_WordLength_8b;USART_Init(USART3,&USARTInitTypeDef);usart3_It_Config();USART_Cmd(USART3,ENABLE);
}
//配置中断 接收和空闲
void usart3_It_Config(void)
{//设置空闲中断和接收中断USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);USART_ITConfig(USART3,USART_IT_IDLE,ENABLE);//NVIC_SetPriority(USART3_IRQn,0);//占先优先级:1 次级优先级:1 NVIC_EnableIRQ(USART3_IRQn);
}void ESP8266_IO_Config(void)
{GPIO_InitTypeDef gpio_initsources;//打开时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,ENABLE);gpio_initsources.GPIO_Pin=GPIO_Pin_13|GPIO_Pin_14;gpio_initsources.GPIO_Mode=GPIO_Mode_Out_PP;gpio_initsources.GPIO_Speed=GPIO_Speed_2MHz;//配置PB5//void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);GPIO_Init(GPIOG,&gpio_initsources);
}
//联网流程
u8 Esp8266_AT_test(void)
{//"AT\r\n"char count=0;GPIO_SetBits ( GPIOG, GPIO_Pin_13 );GPIO_SetBits ( GPIOG, GPIO_Pin_14 );printf("\r\nAT测试.....\r\n");delay_ms ( 2000 );while ( count < 10 ){printf("\r\nAT测试次数 %d......\r\n", count);if( ESP8266_Cmd ( "AT", "OK",NULL,500) ){printf("\r\nAT测试启动成功 %d......\r\n", count);return 1;}//复位以下GPIO_ResetBits ( GPIOG, GPIO_Pin_14 );delay_ms ( 500 ); GPIO_SetBits ( GPIOG, GPIO_Pin_14 );++ count;}return 0;
}
//AT+CWMODE=1
bool ESP8266_SetMode(u8 mode)
{char esp_cmd[100];
//	switch(mode)
//	{
//		case 1:sprintf(esp_cmd,"AT+CWMODE=%d",mode);break;
//		case 2:sprintf(esp_cmd,"AT+CWMODE=%d",mode);break;
//		case 3:sprintf(esp_cmd,"AT+CWMODE=%d",mode);break
//	}
//	sprintf(esp_cmd,"AT+CWMODE=%d",mode);return (ESP8266_Cmd(esp_cmd,"OK",NULL,500));}
//设置联网热点
//AT+CWJAP="111","11111111"  
bool ESP8266_SET_HotPort(void)
{char esp_cmd[100];sprintf(esp_cmd,"AT+CWJAP=\"%s\",\"%s\"",WIFI_ID,WIFI_PW);return (ESP8266_Cmd(esp_cmd,"OK",NULL,500));}
//AT+CIPMUX=0--单链接
bool ESP8266_Set_CIPmux(u8 cipmux)
{char esp_cmd[100];sprintf(esp_cmd,"AT+CIPMUX=%d",cipmux);return (ESP8266_Cmd(esp_cmd,"OK",NULL,500));}bool ESP8266_Set_CIPSTART(u8 link_id)
{char esp_cmd[100];//整理需要发送的指令格式if(link_id<5){//多链接}else {//单链接//AT+CIPSTART="TCP","iot.espressif.cn",8000sprintf(esp_cmd,"AT+CIPSTART=\"%s\",\"%s\",%d","TCP",SER_IP,SER_PORT);}return (ESP8266_Cmd(esp_cmd,"OK","ALREADY	CONNECT",500));}u8 ESP8266_Send_Data(void)
{//设置透传模式if ( ! ESP8266_Cmd ( "AT+CIPMODE=1", "OK", 0, 500 ) )return false;//开始数据传输return   //必须接收到  “>”,然后才可以进入透传模式ESP8266_Cmd ( "AT+CIPSEND", "OK", ">", 500 );
}void ESP8266_NET_Config(void)
{GPIO_SetBits ( GPIOG, GPIO_Pin_13 );//使能ESP8266printf("配置ESP8266联网流程\r\n");//联网流程
//	Esp8266_AT_test();while(!Esp8266_AT_test());//printf("正在配置ESP8266模式\r\n");while(!ESP8266_SetMode(1));printf("正在配置WIFI热点信息\r\n");while(!ESP8266_SET_HotPort());printf("正在配置单链接\r\n");while(!ESP8266_Set_CIPmux(0));//printf("正在配置服务器端信息\r\n");while(!ESP8266_Set_CIPSTART(5));//透传模式配置printf("进入透传模式\r\n");while(!ESP8266_Send_Data());printf("进入透传模式成功\r\n");printf("开始传输数据\r\n");}

对应的.h文件:

#ifndef _ESP8266_H_
#define _ESP8266_H_
#include "stm32f10x.h"
#include <stdbool.h>//enum{
//	Station=1,
//	SoftAP,
//	SoftSta
//}Cmode;
#define WIFI_ID "iPhone010"   //热点ID
#define WIFI_PW "66666666"   //热点密码#define SER_IP  ""  //连接的服务器的ip,建议为云服务器,因为有公网ip
#define SER_PORT  8000   //端口号void usart3_Init(u32 brr);
void usart3_It_Config(void);
void ESP8266_IO_Config(void);
u8 Esp8266_AT_test(void);
bool ESP8266_SetMode(u8 mode);
bool ESP8266_SET_HotPort(void);
bool ESP8266_Set_CIPmux(u8 cipmux);
bool ESP8266_Set_CIPSTART(u8 link_id);u8 ESP8266_Send_Data(void);
void ESP8266_NET_Config(void);#endif

2.esp_data.c:


#include "esp_data.h"
#include "stdarg.h"
#include "string.h"
#include <stdbool.h>
#include <delay.h>
#include <stdio.h>
#include "esp8266.h"struct  STRUCT_USARTx_Fram strEsp8266_Fram_Record = { 0 };
struct  STRUCT_USARTx_Fram strUSART_Fram_Record = { 0 };static char *itoa( int value, char * string, int radix );void USART_printf ( USART_TypeDef * USARTx, char * Data, ... )
{const char *s;int d;   char buf[16];va_list ap;va_start(ap, Data);while ( * Data != 0 )     // 判断是否到达字符串结束符{				                          if ( * Data == 0x5c )  //'\'{									  switch ( *++Data ){case 'r':							          //回车符USART_SendData(USARTx, 0x0d);Data ++;break;case 'n':							          //换行符USART_SendData(USARTx, 0x0a);	Data ++;break;default:Data ++;break;}			 }else if ( * Data == '%'){									  //switch ( *++Data ){				case 's':										  //字符串s = va_arg(ap, const char *);for ( ; *s; s++) {USART_SendData(USARTx,*s);while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );}Data++;break;case 'd':			//十进制d = va_arg(ap, int);itoa(d, buf, 10);for (s = buf; *s; s++) {USART_SendData(USARTx,*s);while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );}Data++;break;default:Data++;break;}		 }else USART_SendData(USARTx, *Data++);while ( USART_GetFlagStatus ( USARTx, USART_FLAG_TXE ) == RESET );}
}
/** 函数名:itoa* 描述  :将整形数据转换成字符串* 输入  :-radix =10 表示10进制,其他结果为0*         -value 要转换的整形数*         -buf 转换后的字符串*         -radix = 10* 输出  :无* 返回  :无* 调用  :被USART2_printf()调用*/
static char * itoa( int value, char *string, int radix )
{int     i, d;int     flag = 0;char    *ptr = string;/* This implementation only works for decimal numbers. */if (radix != 10){*ptr = 0;return string;}if (!value){*ptr++ = 0x30;*ptr = 0;return string;}/* if this is a negative value insert the minus sign. */if (value < 0){*ptr++ = '-';/* Make the value positive. */value *= -1;}for (i = 10000; i > 0; i /= 10){d = value / i;if (d || flag){*ptr++ = (char)(d + 0x30);value -= (d * i);flag = 1;}}/* Null terminate the string. */*ptr = 0;return string;} /* NCL_Itoa *///1---成功   0--失败
bool ESP8266_Cmd ( char * cmd, char * reply1, char * reply2, u32 waittime )
{    strEsp8266_Fram_Record .InfBit .FramLength = 0;               //从新开始接收新的数据包macESP8266_Usart ( "%s\r\n", cmd );if ( ( reply1 == 0 ) && ( reply2 == 0 ) )                      //不需要接收数据return true;delay_ms ( waittime );                 //延时strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ]  = '\0';printf("000\r\n");macPC_Usart ( "00%s", strEsp8266_Fram_Record .Data_RX_BUF );strEsp8266_Fram_Record .InfBit .FramLength = 0;                             //清除接收标志strEsp8266_Fram_Record.InfBit.FramFinishFlag = 0;                             if ( ( reply1 != 0 ) && ( reply2 != 0 ) )return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply1 ) || ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply2 ) ); else if ( reply1 != 0 )return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply1 ) );elsereturn ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply2 ) );}u8 ucTcpClosedFlag=0;
void USART1_IRQHandler(void)
{uint8_t ucCh;if ( USART_GetITStatus ( USART1, USART_IT_RXNE ) != RESET ){ucCh  = USART_ReceiveData( USART1 );if ( strUSART_Fram_Record .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) )                       //预留1个字节写结束符strUSART_Fram_Record .Data_RX_BUF [ strUSART_Fram_Record .InfBit .FramLength ++ ]  = ucCh;}if ( USART_GetITStatus( USART1, USART_IT_IDLE ) == SET )                                         //数据帧接收完毕{strUSART_Fram_Record .InfBit .FramFinishFlag = 1;		ucCh = USART_ReceiveData( USART1 );                                                              //由软件序列清除中断标志位(先读USART_SR,然后读USART_DR)	}	
}/*** @brief  This function handles macESP8266_USARTx Handler.* @param  None* @retval None*/
void USART3_IRQHandler ( void )
{	uint8_t ucCh;if ( USART_GetITStatus ( USART3, USART_IT_RXNE ) != RESET ){ucCh  = USART_ReceiveData( USART3 );if ( strEsp8266_Fram_Record .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) )                       //预留1个字节写结束符strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ++ ]  = ucCh;}if ( USART_GetITStatus( USART3, USART_IT_IDLE ) == SET )                                         //数据帧接收完毕{strEsp8266_Fram_Record .InfBit .FramFinishFlag = 1;ucCh = USART_ReceiveData( USART3 );                                                              //由软件序列清除中断标志位(先读USART_SR,然后读USART_DR)ucTcpClosedFlag = strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "CLOSED\r\n" ) ? 1 : 0;                   //获取连接状态}	}void ESP8266_ExitUnvarnishSend ( void )
{delay_ms ( 1000 );macESP8266_Usart ( "+++" );delay_ms ( 500 ); }
uint8_t ESP8266_Get_LinkStatus ( void )
{if ( ESP8266_Cmd ( "AT+CIPSTATUS", "OK", 0, 500 ) ){if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:2\r\n" ) )return 2;else if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:3\r\n" ) )return 3;else if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:4\r\n" ) )return 4;		}return 0;}void ESP8266_CheckRecvDataTest(void)
{uint8_t ucStatus;uint16_t i;/* 如果接收到了串口调试助手的数据 */if(strUSART_Fram_Record.InfBit.FramFinishFlag == 1){for(i = 0;i < strUSART_Fram_Record.InfBit.FramLength; i++){USART_SendData( USART3 ,strUSART_Fram_Record.Data_RX_BUF[i]); //转发给ESP82636while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET){}      //等待发送完成}strUSART_Fram_Record .InfBit .FramLength = 0;                                //接收数据长度置零strUSART_Fram_Record .InfBit .FramFinishFlag = 0;                            //接收标志置零}/* 如果接收到了ESP8266的数据 */if(strEsp8266_Fram_Record.InfBit.FramFinishFlag){                                                      for(i = 0;i < strEsp8266_Fram_Record .InfBit .FramLength; i++)               {USART_SendData( USART1 ,strEsp8266_Fram_Record .Data_RX_BUF[i]);    //转发给ESP8266while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET){}}strEsp8266_Fram_Record .InfBit .FramLength = 0;                             //接收数据长度置零strEsp8266_Fram_Record.InfBit.FramFinishFlag = 0;                           //接收标志置零}if ( ucTcpClosedFlag )                                             //检测是否失去连接{ESP8266_ExitUnvarnishSend ();                                    //退出透传模式do ucStatus = ESP8266_Get_LinkStatus ();                         //获取连接状态while ( ! ucStatus );if ( ucStatus == 4 )                                             //确认失去连接后重连{printf ( "\r\n正在重连热点和服务器 ......\r\n" );while ( !ESP8266_SET_HotPort() );//0--TCPwhile ( !	ESP8266_Set_CIPSTART(5) );printf ( "\r\n重连热点和服务器成功\r\n" );}while ( ! ESP8266_Send_Data () );		}
}

对应的.h文件:

#ifndef _ESP_DATA_H_
#define _ESP_DATA_H_
#include "stm32f10x.h"
#include <stdio.h>
#include <stdbool.h>
#pragma anon_unions#define     macESP8266_Usart( fmt, ... )           USART_printf ( USART3, fmt, ##__VA_ARGS__ )#define     macPC_Usart( fmt, ... )                printf ( fmt, ##__VA_ARGS__ )
#define RX_BUF_MAX_LEN     1024                                     //最大接收缓存字节数
extern struct  STRUCT_USARTx_Fram                                  //串口数据帧的处理结构体
{char  Data_RX_BUF [ RX_BUF_MAX_LEN ];union {__IO u16 InfAll;struct {__IO u16 FramLength       :15;                               // 14:0 __IO u16 FramFinishFlag   :1;                                // 15 } InfBit;}; } strEsp8266_Fram_Record;extern struct STRUCT_USARTx_Fram strUSART_Fram_Record;
void USART_printf ( USART_TypeDef * USARTx, char * Data, ... );
bool ESP8266_Cmd ( char * cmd, char * reply1, char * reply2, u32 waittime );
void ESP8266_CheckRecvDataTest(void);#endif

3. 监听的服务器程序server.py:(可以运行在pc端监听单片机wifi模块发来的数据)

import socketserver_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 监听所有可用接口,云服务器需用 0.0.0.0
server_socket.bind(('0.0.0.0', 8000))  
server_socket.listen(5)print('服务器已启动,等待客户端连接...')while True:client_socket, client_address = server_socket.accept()print(f'客户端 {client_address} 已连接')while True:data = client_socket.recv(1024)if not data:breakprint(f'收到数据: {data.decode("utf-8")}')client_socket.send(f"服务器已收到: {data.decode('utf-8')}".encode('utf-8'))client_socket.close()print(f'客户端 {client_address} 已断开')

        云服务器上运行:python3 server.py 

4. main.c:

#include "stm32f10x.h"
#include "esp8266.h"
#include "delay.h"int main(void)
{// 1. 系统时钟配置(如果使用CubeMX生成则自动完成)SystemInit();// 2. 初始化延时函数(需要实现delay.c/h)delay_init();// 3. 配置USART1(用于调试信息输出到PC)// 假设USART1已经在其他地方初始化,波特率115200// 如果没有,需要添加USART1_Init(115200)之类的函数调用// 4. 配置USART3(用于与ESP8266通信)usart3_Init(115200);// 5. 配置ESP8266的控制引脚(EN和RST)ESP8266_IO_Config();// 6. 启动ESP8266并完成联网配置printf("\r\n==== ESP8266联网测试 ====\r\n");ESP8266_NET_Config();// 7. 主循环:持续检查并转发数据while(1){// 检查并处理ESP8266与PC之间的数据转发ESP8266_CheckRecvDataTest();// 可以添加其他业务逻辑(如读取传感器数据等)// 适当延时,避免CPU占用过高delay_ms(10);}
}

5.步骤与现象:

1. 串口助手观察初始化过程

打开串口助手(波特率 115200),复位 STM32 后,应看到以下输出:

 
==== ESP8266联网测试 ====
配置ESP8266联网流程
AT测试.....
AT测试次数 0......
AT测试启动成功 0......
正在配置ESP8266模式
正在配置WIFI热点信息
正在配置单链接
正在配置服务器端信息
进入透传模式
进入透传模式成功
开始传输数据
2. 云服务器日志验证连接

Python 服务器应显示类似日志:

 
服务器已启动,等待客户端连接...
客户端 ('你的ESP8266 IP', 随机端口) 已连接
3. 数据透传测试
  • PC→云服务器
    在串口助手发送任意消息(如 Hello, server!),云服务器日志会显示:

    收到数据: Hello, server!
    
  • 云服务器→PC
    服务器会自动回复消息,串口助手会显示:

    服务器已收到: Hello, server!
    
4. 断开重连测试

手动停止云服务器上的 Python 程序,模拟断开连接。ESP8266 会自动检测到连接丢失,并在串口显示:

正在重连热点和服务器 ......

重新启动云服务器上的 Python 程序,ESP8266 会自动重连,串口显示:

重连热点和服务器成功

https://github.com/0voice  

http://www.dtcms.com/a/285275.html

相关文章:

  • AlpineLinux的内核优化
  • AI搜索+GEO时代的营销策略更迭学习笔记
  • 计算机的网络体系及协议模型介绍
  • 【Java】文件编辑器
  • ROS1/Linux——Launch文件使用
  • 【深度学习新浪潮】AI在finTech领域有哪些值得关注的进展?
  • STM32 IAR 生成工程后配置
  • CSP-S模拟赛三(仍然是难度远超CSP-S)
  • 【Java源码阅读系列55】深度解读Java Method 类源码
  • 78、【OS】【Nuttx】【启动】caller-saved 和 callee-saved 示例:栈指针和帧指针(下)
  • 股票行情接口api,板块、概念接口,股票主力资金流接口,板块概念资金流接口
  • 暑期自学嵌入式——Day05(C语言阶段)
  • 1-创建Vue3项目
  • Linux系统编程——进程间通信
  • 融智兴科技: RFID超高频洗涤标签解析
  • LeetCode--48.旋转图像
  • 快速了解网络爬虫
  • 设备驱动的私有数据设计
  • yocto开发(1)----bitbake的全流程分析
  • 指针数组和数组指针的应用案例
  • js对象简介、内置对象
  • 聊聊数据和功能测试面临的挑战有哪些?
  • #systemverilog# 关键字之 变量声明周期与静态方法关系探讨
  • 美团外卖霸王餐接口对接具体操作步骤
  • NW972NW974美光固态闪存NW977NW981
  • 【读论文】AgentOrchestra 解读:LLM 智能体学会「团队协作」去解决复杂任务
  • 海思3516CV610 卷绕 研究
  • JxBrowser 8.9.2 版本发布啦!
  • Python22 —— 标准库(random库)
  • 简单手写一个Spring boot starter