资讯详情

STM32 ESP8266 无线模块使用

文章目录

    • 简介
    • ESP8266介绍
    • 模块参数
      • 无线网络模式
    • AT指令
    • STM32连接模块和配置
      • GPIO配置
      • USART配置
      • 中断函数
    • ESP8266使用流程

简介

文章介绍了ESP8266的特点及连网模式(AP,station),使用串口(USART)接入STM实现连网功能。

ESP8266介绍

esp8266 内置超低功耗 Tensilica L106 32 位 RISC 处理器,CPU 最高时钟速度可达 160 MHz,支持实时操作系统 (RTOS) 和 Wi-Fi 协议栈 balun、低功耗放大器、低噪声放大器、过滤器和电源管理模块。

模块参数

无线参数
无线标准 802.11 b/g/n
频率范围 2.4G-2.5G(2400M-2483.5M)
发射功率 802.11 b: 20 dBm;802.11 g: 17 dBm;802.11 n: 14 dBm
接收灵敏度 802.11 b: (11Mbps) -91db;802.11 g: (54Mbps) -75db;802.11 n: (MCS7) -72db
硬件参数
数据接口 UART、PWM、 GPIO
工作电压 3.3V
工作电流 平均电流 80mA
工作温度 -40° ~125°
软件参数
无线网络模式 station/softAP/SoftAP station
安全机制 WPA/WPA2
加密类型 WEP/TKIP/AES

ESP8266 判断 UART 如果传输的数据时间间隔大于 20ms, 一帧结束;否则, 一直接收数据到上限值 2KB, 一帧结束。 ESP8266 模块判断UART 数据一帧结束后, 通过 WIFI 接口转发数据。 帧时间间隔为 20ms, 帧的上限值为 2KB。

无线网络模式

ESP8266 支持 softAP 模式, station 模式, softAP station 三种共存模式。

: 即无线接入点, 类似于无线路由器的无线网络中心节点。 用户设备、 其他 ESP8266 station 均可作为接口等 station 连入ESP8266, 形成局域网。 在这里插入图片描述

:即无线终端, 是无线网络的终端。 连接路由器(AP) 连入 internet ,可上传到云服务器, 下载数据。移动终端(手机, 笔记本等) ,通过云端连接ESP8266。

网络相关模块,如4G、lora等模块都有AT指令,使用AT指示模块配置,ESP8266的AT指令如下

AT指令

分类 指令格式 指令功能
测试命令 AT =? 该命令用于查询设置命令或内部程序设置
查询命令 AT ? 该命令用于返回参数当前值
设置命令 AT =<…> 该命令用于设置用户定制的参数值
执行命令 AT 该命令用于执行模块内部程序控制的变参

命令 说明
AT 测试 AT 启动
AT RST 重启模块
AT GMR 查看版本信息

命令 说明
AT CWMODE 选择 WIFI 应用模式
AT CWJAP 加入 AP
AT CWLAP 列出当前可用性 AP
AT CWQAP 退出与 AP 的连接
AT CWSAP 设置 AP 参数在模式下
AT CWLIF 检查已接入的设备 IP

命令 说明
AT CIPSTATUS 连接状态
AT CIPSTART 建立 TCP 连接或注册 UDP 端口号
AT CIPSEND 发送数据
AT CIPCLOSE 关闭 TCP 或 UDP
AT CIFSR 获取本地 IP 地址
AT CIPMUX 启动多连接
AT+CIPSERVER 配置为服务器
AT+CIPMODE 设置模块传输模式
AT+CIPSTO 设置服务器超时时间

STM32连接模块与配置

RST复位引脚,与CH_PD片选引脚,在模式初始化阶段使用。RST拉高,CH_PD先复位 再置位,模块正常工作。采用串口方式与STM32进行通信,使用串口中断,有数据时,去读取数据。

GPIO配置

// CH_PD引脚
// Enables or disables the High Speed APB (APB2) peripheral clock
#define macESP8266_CH_PD_APBxClock_FUN RCC_APB2PeriphClockCmd
//RCC_APB2Periph: specifies the APB2 peripheral to gates its clock
#define macESP8266_CH_PD_CLK RCC_APB2Periph_GPIOB 
//PORT
#define macESP8266_CH_PD_PORT GPIOB
//PIN
#define macESP8266_CH_PD_PIN GPIO_Pin_8

RST引脚
#define macESP8266_RST_APBxClock_FUN RCC_APB2PeriphClockCmd
#define macESP8266_RST_CLK RCC_APB2Periph_GPIOB
#define macESP8266_RST_PORT GPIOB
#define macESP8266_RST_PIN GPIO_Pin_9
//

static void ESP8266_GPIO_Config ( void )
{ 
        
	GPIO_InitTypeDef GPIO_InitStructure;
	macESP8266_CH_PD_APBxClock_FUN ( macESP8266_CH_PD_CLK, ENABLE ); 
	//CH_PD引脚 
	GPIO_InitStructure.GPIO_Pin = macESP8266_CH_PD_PIN;	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
	GPIO_Init ( macESP8266_CH_PD_PORT, & GPIO_InitStructure );	 
	//RST引脚
	macESP8266_RST_APBxClock_FUN ( macESP8266_RST_CLK, ENABLE ); 					   
	GPIO_InitStructure.GPIO_Pin = macESP8266_RST_PIN;	
	GPIO_Init ( macESP8266_RST_PORT, & GPIO_InitStructure );	 
}

USART配置

#define macESP8266_USART_BAUD_RATE 115200

#define macESP8266_USARTx USART3
#define macESP8266_USART_APBxClock_FUN RCC_APB1PeriphClockCmd
#define macESP8266_USART_CLK RCC_APB1Periph_USART3

#define macESP8266_USART_GPIO_APBxClock_FUN RCC_APB2PeriphClockCmd
#define macESP8266_USART_GPIO_CLK RCC_APB2Periph_GPIOB 
//发送TX
#define macESP8266_USART_TX_PORT GPIOB 
#define macESP8266_USART_TX_PIN GPIO_Pin_10
//接受RX
#define macESP8266_USART_RX_PORT GPIOB
#define macESP8266_USART_RX_PIN GPIO_Pin_11
//中断
#define macESP8266_USART_IRQ USART3_IRQn
#define macESP8266_USART_INT_FUN USART3_IRQHandler

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;

struct  STRUCT_USARTx_Fram strEsp8266_Fram_Record = { 
         0 };

//USART 的 NVIC中断
static void ESP8266_USART_NVIC_Configuration ( void )
{ 
        
	NVIC_InitTypeDef NVIC_InitStructure; 
	
	/* Configure the NVIC Preemption Priority Bits */  
	NVIC_PriorityGroupConfig ( macNVIC_PriorityGroup_x );

	/* Enable the USART3 Interrupt */
	NVIC_InitStructure.NVIC_IRQChannel = macESP8266_USART_IRQ;	 
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

}
static void ESP8266_USART_Config ( void )
{ 
        
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	
	
	/* config USART clock */
	macESP8266_USART_APBxClock_FUN ( macESP8266_USART_CLK, ENABLE );
	macESP8266_USART_GPIO_APBxClock_FUN ( macESP8266_USART_GPIO_CLK, ENABLE );
	
	/* USART GPIO config */
	/* Configure USART Tx as alternate function push-pull */
	GPIO_InitStructure.GPIO_Pin =  macESP8266_USART_TX_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(macESP8266_USART_TX_PORT, &GPIO_InitStructure);  
  
	/* Configure USART Rx as input floating */
	GPIO_InitStructure.GPIO_Pin = macESP8266_USART_RX_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(macESP8266_USART_RX_PORT, &GPIO_InitStructure);
	
	/* USART1 mode config */
	USART_InitStructure.USART_BaudRate = macESP8266_USART_BAUD_RATE;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No ;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_Init(macESP8266_USARTx, &USART_InitStructure);
	
	
	/* 中断配置 */
	USART_ITConfig ( macESP8266_USARTx, USART_IT_RXNE, ENABLE ); //使能串口接收中断
	USART_ITConfig ( macESP8266_USARTx, USART_IT_IDLE, ENABLE ); //使能串口空闲中断

	ESP8266_USART_NVIC_Configuration ();
	USART_Cmd(macESP8266_USARTx, ENABLE);
}

中断函数

void macESP8266_USART_INT_FUN ( void )
{ 
        	
	uint8_t ucCh;
	//获取RX中断状态
	if ( USART_GetITStatus ( macESP8266_USARTx, USART_IT_RXNE ) != RESET )
	{ 
        
		ucCh  = USART_ReceiveData( macESP8266_USARTx );//接收数据
		
		if ( strEsp8266_Fram_Record .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) )   //长度判断 
			//向BUF缓冲区中写入数据ucCh,FramLength 在不断增加
			strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ++ ]  = ucCh;
	}
	//获取IDEL中断状态 ,数据帧接收完毕
	if ( USART_GetITStatus( macESP8266_USARTx, USART_IT_IDLE ) == SET ) 
	{ 
        
        strEsp8266_Fram_Record .InfBit .FramFinishFlag = 1;//条件置位
		ucCh = USART_ReceiveData( macESP8266_USARTx );                                                            
		ucTcpClosedFlag = strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "CLOSED\r\n" ) ? 1 : 0;
    }	
}

ESP8266使用流程

ESP8266的一般使用顺序,ESP8266连接当前环境的热点,与服务器建立TCP连接,传输数据。

AT+CWMODE=1:设置工作模式(STA模式) AT+RST:模块重启(生效工作模式) AT+CWJAP=“111”,“11111111”:连接当前环境的WIFI热点(热点名,密码) AT+CIPMUX=0:设置单路连接模式 AT+CIPSTART=“TCP”,“xxx.xxx.xxx.xxx”,xxxx:建立TCP连接 AT+CIPMODE=1:开启透传模式 AT+CIPSEND:透传模式下,传输数据 +++:退出透传模式

程序的主处理流程

void ESP8266_StaTcpClient_UnvarnishTest ( void )
{ 
        
	uint8_t ucStatus;
	char cStr [ 100 ] = { 
         0 };
	//使能PD_CH
	macESP8266_CH_ENABLE();
	//AT测试
	ESP8266_AT_Test ();
	//选择网络模式
	ESP8266_Net_Mode_Choose ( STA );
    //连接AP
    while ( ! ESP8266_JoinAP ( macUser_ESP8266_ApSsid, macUser_ESP8266_ApPwd ) );	
	//启动多连接关闭
	ESP8266_Enable_MultipleId ( DISABLE );
	//连接服务器IP 端口号
	while ( !	ESP8266_Link_Server ( enumTCP, macUser_ESP8266_TcpServer_IP, macUser_ESP8266_TcpServer_Port, Single_ID_0 ) );
	//设置模式进入透传模式
	while ( ! ESP8266_UnvarnishSend () );

    while ( 1 )//进入循环
	{ 
        		
		//此处可以修改数据源,此处为一串字符串,也可以是从开发版上获取传感器数据,比如温湿度传感器
		sprintf ( cStr,"ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" );
		ESP8266_SendString ( ENABLE, cStr, 0, Single_ID_0 );  //发送数据
		
		Delay_ms ( 100 );
		
		if ( ucTcpClosedFlag )  //检测是否丢失链接
		{ 
        
			ESP8266_ExitUnvarnishSend ();        //如果丢失,退出透传模式
			
			do ucStatus = ESP8266_Get_LinkStatus ();      //获取链接状态
			while ( ! ucStatus );
			
			if ( ucStatus == 4 )                                             //失去链接后重连
			{ 
        
				while ( ! ESP8266_JoinAP ( macUser_ESP8266_ApSsid, macUser_ESP8266_ApPwd ) );
				while ( !ESP8266_Link_Server ( enumTCP, macUser_ESP8266_TcpServer_IP, macUser_ESP8266_TcpServer_Port, Single_ID_0 ) );			
			}
			while ( ! ESP8266_UnvarnishSend () );		
		}
	}

发送AT指令函数

/* cmd:待发送的命令, reply1,reply2期待的回复 waittime 等待时间 */
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';
	macPC_Usart ( "%s", strEsp8266_Fram_Record .Data_RX_BUF );
	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 ) );
	else
		return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply2 ) );
}

选择NET模式

bool ESP8266_Net_Mode_Choose ( ENUM_Net_ModeTypeDef enumMode )
{ 
        
	switch ( enumMode )
	{ 
        
		case STA:
			return ESP8266_Cmd ( "AT+CWMODE=1", "OK", "no change", 2500 ); 
	    case AP:
		    return ESP8266_Cmd ( "AT+CWMODE=2", "OK", "no change", 2500 ); 
	    case STA_AP:
		    return ESP8266_Cmd ( "AT+CWMODE=3", "OK", "no change", 2500 ); 
	    default:
		    return false;
  }
}

链接wifi, AT+CWJAP

/* pSSID用户名 pPassWord 密码 */
bool ESP8266_JoinAP ( char * pSSID, char * pPassWord )
{ 
        
	char cCmd [120];
	sprintf ( cCmd, "AT+CWJAP=\"%s\",\"%s\"", pSSID, pPassWord );
	return ESP8266_Cmd ( cCmd, "OK", NULL, 5000 );
}

连接外部服务器 AT+CIPSTART

bool ESP8266_Link_Server ( ENUM_NetPro_TypeDef enumE, char * ip, char * ComNum, ENUM_ID_NO_TypeDef id)
{ 
        
	char cStr [100] = { 
         0 }, cCmd [120];
  switch (  enumE )
  { 
        
		case enumTCP:
		  sprintf ( cStr, "\"%s\",\"%s\",%s", "TCP", ip, ComNum );
		  break;
		case enumUDP:
		  sprintf ( cStr, "\"%s\",\"%s\",%s", "UDP", ip, ComNum );
		  break;
		default:
			break;
  }

  if ( id < 5 )
    sprintf ( cCmd, "AT+CIPSTART=%d,%s", id, cStr);
  else
	  sprintf ( cCmd, "AT+CIPSTART=%s", cStr );
	return ESP8266_Cmd ( cCmd, "OK", "ALREAY CONNECT", 4000 );
}

获取链接状态AT+CIPSTATUS

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;
}

发送数据"AT+CIPSEND=

/* 返回值 1,发送成功 0,发送失败 */

bool ESP8266_SendString ( FunctionalState enumEnUnvarnishTx, char * pStr, u32 ulStrLength, ENUM_ID_NO_TypeDef ucId )
{ 
        
	char cStr [20];
	bool bRet = false;
	if ( enumEnUnvarnishTx )
	{ 
        
		macESP8266_Usart ( "%s", pStr );
		bRet = true;
	}

	else
	{ 
        
		if ( ucId < 5 )
			sprintf ( cStr, "AT+CIPSEND=%d,%d", ucId, ulStrLength + 2 );
		else
			sprintf ( cStr, "AT+CIPSEND=%d", ulStrLength + 2 );
		ESP8266_Cmd ( cStr, "> ", 0, 1000 );
		bRet = ESP8266_Cmd ( pStr, "SEND OK", 0, 1000 );
  }
	return bRet;
}

主函数

void ESP8266_Init ( void )
{ 
        
	ESP8266_GPIO_Config (); 
	ESP8266_USART_Config (); 
	
	macESP8266_RST_HIGH_LEVEL();
	macESP8266_CH_DISABLE();
}

int main ( void )
{ 
        
    USARTx_Config ();//串口打印函数
	SysTick_Init ();//系统时钟初始化
	ESP8266_Init ();//esp8266初始化
    ESP8266_StaTcpClient_UnvarnishTest ();
    while ( 1 );
}

通过网络助手,收到开发版发来的数据

模块作为AP的配置

	ESP8266_AT_Test ();
	ESP8266_Net_Mode_Choose ( AP );
	//设置模块的IP
    while ( ! ESP8266_CIPAP ( macUser_ESP8266_TcpServer_IP ) );
    //创建模块热点
    while ( ! ESP8266_BuildAP ( macUser_ESP8266_BulitApSsid, macUser_ESP8266_BulitApPwd, macUser_ESP8266_BulitApEcn ) );	
	//模块启动多连接
	ESP8266_Enable_MultipleId ( ENABLE );
	//模块开启或关闭服务器
	while ( !	ESP8266_StartOrShutServer ( ENABLE, macUser_ESP8266_TcpServer_Port, macUser_ESP8266_TcpServer_OverTime ) );
    //ESP8266 获取 AP IP
	ESP8266_Inquire_ApIp ( cStr, 20 );

参考 《ESP8266_用户手册_V0.3.pdf》 《ESP8266 Non-OS SDK AT 指令集.pdf》 《野火YH-ESP8266模块用户手册.pdf》 《野火提供的esp8266源码》

标签: 超低功耗微功率无线传感器模块用gmr传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台