关于esp8266模块与stm32f103模块的连接,问题分析

news2024/11/20 2:45:28

文章目录

      • 模块和芯片
      • 实验目的
      • 连接方式
      • main.h
      • esp8266.c
      • esp8266.h
      • tcp.c
      • tcp.h
      • 实验中出现的问题
      • 源代码

模块和芯片

stm32f103c8t6 单片机
esp8266 wift 模块

在这里插入图片描述
在这里插入图片描述

实验目的

实现esp8266 模块的通讯(客户端)
在这里插入图片描述

连接方式

在这里插入图片描述
这个是我所使用的模块ESP-01S 类型的,连线图要参考使用手册。本实验采用的是上图的连线方式。
下面是其他模块的原理图。
在这里插入图片描述
本实验的连线方式:

端口esp8266引脚
VCC3.3V
GNDGND
PA2MCU_TXD
PA3MCU_RXD

main.h

#include "delay.h"
#include "sys.h"
#include "string.h"
#include "tcp.h"
#include "esp8266.h"
volatile uint8_t UartRxData;
uint8_t UartTxbuf[512]={1,2,3,4,5,6,7,8,9,10};
uint8_t UartRxbuf[512],UartIntRxbuf[512];
uint16_t UartRxIndex=0,UartRxFlag,UartRxLen=0,UartRxTimer,UartRxOKFlag,UartIntRxLen;

//串口清除
uint8_t UartRecv_Clear(void)
{
	UartRxOKFlag=0;
	UartRxLen=0;
	UartIntRxLen=0;
	UartRxIndex=0;
	return 1;
}

//接收标志函数,返回0说明没收据接收,返回1说明有数据收到
uint8_t Uart_RecvFlag(void)
{
		if(UartRxOKFlag==0x55)
		{
			UartRxOKFlag=0;
			UartRxLen=UartIntRxLen;
			memcpy(UartRxbuf,UartIntRxbuf,UartIntRxLen);//把缓冲区的数据,放入需要解析的数组
			UartIntRxLen=0;
			TcpClosedFlag = strstr ((const char *)UartRxbuf, "CLOSED\r\n" ) ? 1 : 0;
			return 1;
		}
		return 0;
}
//串口2在1字节接收完成回调函数,USART2_IRQHandler中断服务程序中调用
void HAL_UART_RxCpltCallback(void)
{
	

		UartRxFlag=0x55;//接收标志置位
		UartIntRxbuf[UartRxIndex]= USART_ReceiveData(USART2);//数据写入缓冲区
		UartRxIndex++;//记载数目加1
		if(UartRxIndex>=512)//缓冲区是512字节,如果存满,归零
		{
			UartRxIndex=0;
		}
		  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//接收中断打开


}

//1ms调用一次,用来判断是否收完一帧
void UART_RecvDealwith(void)
{
	if(UartRxFlag==0x55)
	{
		if(UartIntRxLen<UartRxIndex)//UartIntRxLen小于UartRxIndex,说明有收到新的数据,把接收长度增加
		{
		UartIntRxLen=UartRxIndex;
		}else
		{
			UartRxTimer++;
			if(UartRxTimer>=50)//50ms,等待,没收到新数据,说明已经收完一帧
			{
				UartRxTimer=0;
				UartRxFlag=0;
				UartRxOKFlag=0x55;
				UartRxIndex=0;
			}
		}
	}
}

//USART2管脚初始化
void GPIO_Config_Init(void)
{
 
	GPIO_InitTypeDef GPIO_InitStructure;
  /* Configure USART2 Rx as input floating */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  /* Configure USART2 Tx as alternate function push-pull */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
 
}

void RCC_Configuration(void)
{
  /* Enable GPIO clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
  /* Enable USART2 Clock */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);  
}

void USART_Config_Init(void)
{
	USART_InitTypeDef USART_InitStructure;
	
  USART_InitStructure.USART_BaudRate = 115200;
  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(USART2, &USART_InitStructure);
  /* Enable USARTy Receive  interrupts */
  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
  /* Enable the USART2 */
  USART_Cmd(USART2, ENABLE);
}

void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

  /* Configure the NVIC Preemption Priority Bits */  
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  
  /* Enable the USART2 Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

}


//主函数,采用外部8M晶振,72M系统主频,可以在void SetSysClock(void)函数中选择主频率设置
int main(void)
 {	
	
		delay_init();	    	//延时函数初始化,通过Systick中断实现1ms延时功能  
		RCC_Configuration();//串口2时钟初始化
		NVIC_Configuration();//串口2中断配置
		GPIO_Config_Init();	//USART2管脚PA2,PA3初始化
		USART_Config_Init();//串口2配置,115200波特率,无校验,1位停止,8位数据
		ESP8266_Init();//ESP8266复位初始化
	while(1)
	{
		ESP8266_STA_TCPClient_Test();//测试TCP通讯

	}
 }


esp8266.c

#include "esp8266.h"
#include "stm32f10x.h"
#include <stdarg.h>
#include "string.h"

extern uint8_t UartRxbuf[512];
extern uint16_t UartRxLen;
extern uint8_t UartRecv_Clear(void);


struct STRUCT_USART_Fram ESP8266_Fram_Record_Struct = { 0 };  //定义了一个数据帧结构体
void ESP8266_Init(void)
{ 
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = ESP8266_RST_Pin;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(ESP8266_RST_Pin_Port, &GPIO_InitStructure);//复位配置成输出
	ESP8266_RST_Pin_Periph_Clock();
	ESP8266_Rst();
}
//对ESP8266模块发送AT指令
// cmd 待发送的指令
// ack1,ack2;期待的响应,为NULL表不需响应,两者为或逻辑关系
// time 等待响应时间
//返回1发送成功, 0失败
bool ESP8266_Send_AT_Cmd(char *cmd,char *ack1,char *ack2,u32 time)
{ 
    UartRecv_Clear(); //重新接收新的数据包
    ESP8266_USART("%s\r\n", cmd);
    if(ack1==0&&ack2==0)     //不需要接收数据
    {
    return true;
    }
    delay_ms(time);   //延时
		delay_ms(1000);
		if(Uart_RecvFlag()==1)
		{
		UartRxbuf[UartRxLen]='\0';
		}
   // printf("%s",UartRxbuf);
    if(ack1!=0&&ack2!=0)
    {
        return ( ( bool ) strstr ( (const char*)UartRxbuf, ack1 ) || 
                         ( bool ) strstr ( (const char*)UartRxbuf, ack2 ) );
    }
    else if( ack1 != 0 )  //strstr(s1,s2);检测s2是否为s1的一部分,是返回该位置,否则返回false,它强制转换为bool类型了
        return ( ( bool ) strstr ( (const char*)UartRxbuf, ack1 ) );

    else
        return ( ( bool ) strstr ( (const char*)UartRxbuf, ack2 ) );

}


//复位重启
void ESP8266_Rst(void)
{
    ESP8266_RST_Pin_SetL;
    delay_ms(500); 
    ESP8266_RST_Pin_SetH;
}


//发送恢复出厂默认设置指令将模块恢复成出厂设置
void ESP8266_AT_Test(void)
{
    char count=0;
    delay_ms(1000); 
    while(count < 10)
    {
        if(ESP8266_Send_AT_Cmd("AT+RESTORE","OK",NULL,500)) 
        {
           // printf("OK\r\n");
            return;
        }
        ++ count;
    }
}


//选择ESP8266的工作模式
// enumMode 模式类型
//成功返回true,失败返回false
bool ESP8266_Net_Mode_Choose(ENUM_Net_ModeTypeDef enumMode)
{
    switch ( enumMode )
    {
        case STA:
            return ESP8266_Send_AT_Cmd ( "AT+CWMODE=1", "OK", "no change", 2500 ); 

        case AP:
            return ESP8266_Send_AT_Cmd ( "AT+CWMODE=2", "OK", "no change", 2500 ); 

        case STA_AP:
            return ESP8266_Send_AT_Cmd ( "AT+CWMODE=3", "OK", "no change", 2500 ); 

        default:
          return false;
    }       
}


//ESP8266连接外部的WIFI
//pSSID WiFi帐号
//pPassWord WiFi密码
//设置成功返回true 反之false
bool ESP8266_JoinAP( char * pSSID, char * pPassWord)
{
    char cCmd [120];
	
    sprintf ( cCmd, "AT+CWJAP=\"%s\",\"%s\"", pSSID, pPassWord );
    return ESP8266_Send_AT_Cmd( cCmd, "OK", NULL, 5000 );
}

//ESP8266 透传使能
//enumEnUnvarnishTx  是否多连接,bool类型
//设置成功返回true,反之false
bool ESP8266_Enable_MultipleId (FunctionalState enumEnUnvarnishTx )
{
    char cStr [20];

    sprintf ( cStr, "AT+CIPMUX=%d", ( enumEnUnvarnishTx ? 1 : 0 ) );

    return ESP8266_Send_AT_Cmd ( cStr, "OK", 0, 500 );

}


//ESP8266 连接服务器
//enumE  网络类型
//ip ,服务器IP
//ComNum  服务器端口
//id,连接号,确保通信不受外界干扰
//设置成功返回true,反之fasle
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_Send_AT_Cmd ( cCmd, "OK", "ALREAY CONNECT", 4000 );

}


//透传使能
//设置成功返回true, 反之false
bool ESP8266_UnvarnishSend ( void )
{
    if (!ESP8266_Send_AT_Cmd ( "AT+CIPMODE=1", "OK", 0, 500 ))
        return false;

    return 
        ESP8266_Send_AT_Cmd( "AT+CIPSEND", "OK", ">", 500 );

}


//ESP8266发送字符串
//enumEnUnvarnishTx是否使能透传模式
//pStr字符串
//ulStrLength字符串长度
//ucId 连接号
//设置成功返回true, 反之false
bool ESP8266_SendString(FunctionalState enumEnUnvarnishTx, char * pStr, u32 ulStrLength, ENUM_ID_NO_TypeDef ucId )
{
    char cStr [20];
    bool bRet = false;


    if ( enumEnUnvarnishTx )
    {
        ESP8266_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_Send_AT_Cmd ( cStr, "> ", 0, 1000 );

        bRet = ESP8266_Send_AT_Cmd ( pStr, "SEND OK", 0, 1000 );
  }

    return bRet;

}


//ESP8266退出透传模式
void ESP8266_ExitUnvarnishSend ( void )
{
    delay_ms(1000);
    ESP8266_USART( "+++" );
    delay_ms( 500 );    
}


//ESP8266 检测连接状态
//返回0:获取状态失败
//返回2:获得ip
//返回3:建立连接 
//返回4:失去连接 
u8 ESP8266_Get_LinkStatus ( void )
{
    if (ESP8266_Send_AT_Cmd( "AT+CIPSTATUS", "OK", 0, 500 ) )
    {
        if ( strstr ( ESP8266_Fram_Record_Struct .Data_RX_BUF, "STATUS:2\r\n" ) )
            return 2;

        else if ( strstr ( ESP8266_Fram_Record_Struct .Data_RX_BUF, "STATUS:3\r\n" ) )
            return 3;

        else if ( strstr ( ESP8266_Fram_Record_Struct .Data_RX_BUF, "STATUS:4\r\n" ) )
            return 4;       

    }

    return 0;
}

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 */


void USART_printf ( USART_TypeDef* USARTx, char * Data, ... )
{
    const char *s;
    int d;   
    char buf[16];
	unsigned char TempData;


    va_list ap;
    va_start(ap, Data);

    while ( * Data != 0 )     // 判断数据是否到达结束符
    {                                         
        if ( * Data == 0x5c )  //'\'
        {                                     
            switch ( *++Data )
            {
                case 'r':                                     //回车符
								TempData=0x0d;
								USART_SendData(USARTx, TempData);
								while (RESET == USART_GetFlagStatus(USARTx, USART_FLAG_TC));//发送完成判断
                Data ++;
                break;

                case 'n':                                     //换行符
								TempData=0x0a;
								USART_SendData(USARTx, TempData);
								while (RESET == USART_GetFlagStatus(USARTx, USART_FLAG_TC));//发送完成判断						
                Data ++;
                break;

                default:
                Data ++;
                break;
            }            
        }

        else if ( * Data == '%')
        {                                     
            switch ( *++Data )
            {               
                case 's':                                         //字符串
                s = va_arg(ap, const char *);
                for ( ; *s; s++) 
                {
										TempData=*s;
										USART_SendData(USARTx, TempData);
									  while (RESET == USART_GetFlagStatus(USARTx, USART_FLAG_TC));//发送完成判断
                }
                Data++;
                break;

                case 'd':           
                    //十进制
                d = va_arg(ap, int);
                itoa(d, buf, 10);
                for (s = buf; *s; s++) 
                {
                   	TempData=*s;
									  USART_SendData(USARTx, TempData);
									  while (RESET == USART_GetFlagStatus(USARTx, USART_FLAG_TC));//发送完成判断
                }
                     Data++;
                     break;
                default:
                     Data++;
                     break;
            }        
        }
        else 
				{
										TempData=*Data++;
								    USART_SendData(USARTx, TempData);
										while (RESET == USART_GetFlagStatus(USARTx, USART_FLAG_TC));//发送完成判断					
				}

    }
}

//下面为ESP8266MQTT功能指令

/*
*MQTT配置用户属性
*LinkID 连接ID,目前只支持0
*scheme 连接方式,这里选择MQTT over TCP,这里设置为1
*client_id MQTTclientID 用于标志client身份
*username 用于登录 MQTT 服务器 的 username
*password 用于登录 MQTT 服务器 的 password
*cert_key_ID 证书 ID, 目前支持一套 cert 证书, 参数为 0
*CA_ID 目前支持一套 CA 证书, 参数为 0
*path 资源路径,这里设置为""
*设置成功返回true 反之false
*/
bool ESP8266_MQTTUSERCFG( char * pClient_Id, char * pUserName,char * PassWord)
{
    char cCmd [120];
    sprintf ( cCmd, "AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"\"", pClient_Id,pUserName,PassWord );
    return ESP8266_Send_AT_Cmd( cCmd, "OK", NULL, 500 );
}


/*
*连接指定的MQTT服务器
*LinkID 连接ID,目前只支持0
*IP:MQTT服务器上对应的IP地址
*ComNum MQTT服务器上对应的端口号,一般为1883
*设置成功返回true 反之false
*/
bool ESP8266_MQTTCONN( char * Ip, int  Num)
{
    char cCmd [120];
    sprintf ( cCmd,"AT+MQTTCONN=0,\"%s\",%d,0", Ip,Num);
    return ESP8266_Send_AT_Cmd( cCmd, "OK", NULL, 500 );
}

/*
*订阅指定连接的 MQTT 主题, 可重复多次订阅不同 topic
*LinkID 连接ID,目前只支持0
*Topic 订阅的主题名字,这里设置为Topic
*Qos值:一般为0,这里设置为1
*设置成功返回true 反之false
*/
bool ESP8266_MQTTSUB(char * Topic)
{
    char cCmd [120];
    sprintf ( cCmd, "AT+MQTTSUB=0,\"%s\",1",Topic );
    return ESP8266_Send_AT_Cmd( cCmd, "OK", NULL, 500 );
}


/*
*在LinkID上通过 topic 发布数据 data, 其中 data 为字符串消息
*LinkID 连接ID,目前只支持0
*Topic 订阅的主题名字,这里设置为Topic
*data:字符串信息
*设置成功返回true 反之false
*/
bool ESP8266_MQTTPUB( char * Topic,char *temp)
{
    char cCmd [120];
    sprintf (cCmd, "AT+MQTTPUB=0,\"%s\",\"%s\",1,0", Topic ,temp);
    return ESP8266_Send_AT_Cmd( cCmd, "OK", NULL, 1000 );
}

/*
*关闭 MQTT Client 为 LinkID 的连接, 并释放内部占用的资源
*LinkID 连接ID,目前只支持0
*Topic 订阅的主题名字,这里设置为Topic
*data:字符串信息
*设置成功返回true 反之false
*/
bool ESP8266_MQTTCLEAN(void)
{
    char cCmd [120];
    sprintf ( cCmd, "AT+MQTTCLEAN=0");
    return ESP8266_Send_AT_Cmd( cCmd, "OK", NULL, 500 );
}

//ESP8266发送字符串
//enumEnUnvarnishTx是否使能透传模式
//pStr字符串
//ulStrLength字符串长度
//ucId 连接号
//设置成功返回true, 反之false
bool MQTT_SendString(char * pTopic,char *temp2)
{
	
    bool bRet = false;
    ESP8266_MQTTPUB(pTopic,temp2);
	  delay_ms(1000);
    bRet = true;
    return bRet;

}

esp8266.h

···
#ifndef __ESP8266_H
#define __ESP8266_H
#include “stm32f10x.h”

#include <stdio.h>
#include <string.h>
#include <stdbool.h>

#if defined ( __CC_ARM )
#pragma anon_unions
#endif

//ESP8266模式选择
typedef enum
{
STA,
AP,
STA_AP
}ENUM_Net_ModeTypeDef;

//网络传输层协议,枚举类型
typedef enum{
enumTCP,
enumUDP,
} ENUM_NetPro_TypeDef;
//连接号,指定为该连接号可以防止其他计算机访问同一端口而发生错误
typedef enum{
Multiple_ID_0 = 0,
Multiple_ID_1 = 1,
Multiple_ID_2 = 2,
Multiple_ID_3 = 3,
Multiple_ID_4 = 4,
Single_ID_0 = 5,
} ENUM_ID_NO_TypeDef;

#define ESP8266_RST_Pin GPIO_Pin_3 //复位管脚
#define ESP8266_RST_Pin_Port GPIOC //复位
#define ESP8266_RST_Pin_Periph_Clock() RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //PC时钟

#define ESP8266_RST_Pin_SetH GPIO_SetBits(ESP8266_RST_Pin_Port, ESP8266_RST_Pin)
#define ESP8266_RST_Pin_SetL GPIO_ResetBits(ESP8266_RST_Pin_Port, ESP8266_RST_Pin)

#define ESP8266_USART(fmt, …) USART_printf (USART2, fmt, ##VA_ARGS)
#define PC_USART(fmt, …) printf(fmt, ##VA_ARGS) //这是串口打印函数,串口2,执行printf后会自动执行fput函数,重定向了printf。

#define RX_BUF_MAX_LEN 1024 //最大字节数
extern struct STRUCT_USART_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;
};

}ESP8266_Fram_Record_Struct;

//初始化和TCP功能函数
void ESP8266_Init(void);
void ESP8266_AT_Test(void);
bool ESP8266_Send_AT_Cmd(char *cmd,char *ack1,char ack2,u32 time);
void ESP8266_Rst(void);
bool ESP8266_Net_Mode_Choose(ENUM_Net_ModeTypeDef enumMode);
bool ESP8266_JoinAP( char * pSSID, char * pPassWord );
bool ESP8266_Enable_MultipleId ( FunctionalState enumEnUnvarnishTx );
bool ESP8266_Link_Server(ENUM_NetPro_TypeDef enumE, char * ip, char * ComNum, ENUM_ID_NO_TypeDef id);
bool ESP8266_SendString(FunctionalState enumEnUnvarnishTx, char * pStr, u32 ulStrLength, ENUM_ID_NO_TypeDef ucId );
bool ESP8266_UnvarnishSend ( void );
void ESP8266_ExitUnvarnishSend ( void );
u8 ESP8266_Get_LinkStatus ( void );
void USART_printf ( USART_TypeDef
USARTx, char * Data, … );
//MQTT功能函数
bool ESP8266_MQTTUSERCFG( char * pClient_Id, char * pUserName,char * PassWord);
bool ESP8266_MQTTCONN( char * Ip, int Num);
bool ESP8266_MQTTSUB(char * Topic);
bool ESP8266_MQTTPUB( char * Topic,char *temp);
bool ESP8266_MQTTCLEAN(void);
bool MQTT_SendString(char * pTopic,char *temp2);
extern void delay_ms(__IO uint32_t nTime);
extern uint8_t Uart_RecvFlag(void);
#endif

···

tcp.c

#include "tcp.h"
#include "esp8266.h"
#include "stdio.h"
#include "string.h"
#include "stm32f10x.h"
volatile u8 TcpClosedFlag = 0;
extern uint8_t Uart_RecvFlag(void);

void ESP8266_STA_TCPClient_Test(void)
{
    u8 res;
	
    char str[100]={0};
    ESP8266_AT_Test();
    ESP8266_Net_Mode_Choose(STA);
    while(!ESP8266_JoinAP(User_ESP8266_SSID, User_ESP8266_PWD));
    ESP8266_Enable_MultipleId ( DISABLE );
    while(!ESP8266_Link_Server(enumTCP, User_ESP8266_TCPServer_IP, User_ESP8266_TCPServer_PORT, Single_ID_0));
    while(!ESP8266_UnvarnishSend());
    while ( 1 )
    {       
			  sprintf (str,"傻逼校园网\r\n" );//格式化发送字符串到TCP服务器
        ESP8266_SendString ( ENABLE, str, 0, Single_ID_0 );
        delay_ms(200);
			  Uart_RecvFlag();//接收数据
        if(TcpClosedFlag) //判断是否失去连接
        {
            ESP8266_ExitUnvarnishSend(); //退出透传模式
            do
            {
                res = ESP8266_Get_LinkStatus();     //获取连接状态
            }   
            while(!res);

            if(res == 4)                     //确认失去连接,重连
            {               
                while (!ESP8266_JoinAP(User_ESP8266_SSID, User_ESP8266_PWD ) );
                while (!ESP8266_Link_Server(enumTCP, User_ESP8266_TCPServer_IP, User_ESP8266_TCPServer_PORT, Single_ID_0 ) );        
            } 
            while(!ESP8266_UnvarnishSend());                    
        }
    }   
}

tcp.h

#ifndef __TCP_H
#define __TCP_H 			   
#include "stm32f10x.h"

/*
*以下参数需要用户自行修改才能测试用过
*/

#define User_ESP8266_SSID     "shiyan"          //wifi名
#define User_ESP8266_PWD      "12345678"      //wifi密码

#define User_ESP8266_TCPServer_IP     "192.168.137.1"     //服务器IP
#define User_ESP8266_TCPServer_PORT   "8888"      			//服务器端口号





extern volatile uint8_t TcpClosedFlag;  //连接状态标志

void ESP8266_STA_TCPClient_Test(void);
extern void delay_ms(__IO uint32_t  nTime);

#endif

该部分的参数需要自己进行修改, 可以通过反复断开和连接确认自己的设备IP。
在这里插入图片描述

实验中出现的问题

我第一次测试程序的时候,代码没有问题。但就是接受不到信息。开始觉得可能是防火墙的关系,测试之后,与防火墙没有关系。
最后发现是校园网的关系,具体的影响方式不太了解。
千万不要用校园网做测试。

源代码

如果需要源代码,评论区留邮箱!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/568898.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++中stack的用法(超详细,入门必看)

博主简介&#xff1a;Hello大家好呀&#xff0c;我是陈童学&#xff0c;一个与你一样正在慢慢前行的人。 博主主页&#xff1a;陈童学哦 所属专栏&#xff1a;CSTL 前言&#xff1a;Hello各位小伙伴们好&#xff01;欢迎来到本专栏CSTL的学习&#xff0c;本专栏旨在帮助大家了解…

s2020gc56收集数据

作答区域&#xff1a; #include<bits/stdc.h> using namespace std; int n,k,s1,s2,h1,h2,he,ans,r2,r1,l2,l11,f[1000009]; int main() {cin>>n>>k;for(int i1;i<n;i)cin>>f[i];for(int i1;;i){s1;if(s1>k)break;h1h1f[i];}for(int in;;i--){…

神经网络实验--卷积神经网络

本实验主要为了掌握深度学习的基本原理&#xff1b;能够使用TensorFlow实现卷积神经网络&#xff0c;完成图像识别任务。 文章目录 1. 实验目的 2. 实验内容 3. 实验过程 题目一&#xff1a; 题目二&#xff1a; 实验小结&讨论题 1. 实验目的 ①掌握深度学习的基本原…

spring练习1

1、练习网站案例 1、建好相应的java类 package spring;public class Player {public int getId() {return id;}public void setId(int id) {this.id id;}public String getName() {return name;}public void setName(String name) {this.name name;}public String getPosit…

自学软件测试怎么学?新增软件测试(全栈),笔试及面试全套方法

既然是自学&#xff0c;那就如下方面着手吧。 1、面试(此篇文章的重磅) 2、思路 3、心态 4、技能 真所谓&#xff0c;“面试造飞机&#xff0c;工作拧螺丝”。咱们先从第一个&#xff0c;面试着手&#xff0c;这就好比写文章先列好提纲一样&#xff0c;要知道你这个行业具体有那…

【大学物理实验】绪论

《大学物理实验》实验报告册的封面&#xff0c;以下说法不正确的是&#xff1a; A. 应正确填写完整的学号 B. 预习前应写好姓名等相关信息 C. 报告册左上角应填写本班级报告箱编号 D. 除了姓名&#xff0c;其他信息可写可不写 正确答案&#xff1a; D 某同学完成某个实验&…

javascript基础四:== 和 ===区别,分别在什么情况使用?

一、等于操作符 等于操作符用两个等于号&#xff08; &#xff09;表示&#xff0c;如果操作数相等&#xff0c;则会返回 true 前面文章&#xff0c;我们提到在JavaScript中存在隐式转换。等于操作符&#xff08;&#xff09;在比较中会先进行类型转换&#xff0c;再确定操作…

Redis集群安装之哨兵集群

1.哨兵集群介绍及原理 主从模式&#xff0c;当主节点宕机之后&#xff0c;从节点是可以作为主节点顶上来&#xff0c;继续提供服务的。但是有一个问题&#xff0c;主节点的IP已经变动了&#xff0c;此时应用服务还是拿着原主节点的地址去访问&#xff0c;此时就需要人工干预进行…

阿里巴巴 MySQL binlog 增量订阅消费组件canal实现mysql数据同步

canal实现mysql数据同步 简介&#xff1a;最近线上系统进行压测&#xff0c;评估线上系统容量&#xff0c;根据压测情况对代理层&#xff0c;代码&#xff0c;sql等都做了相应的优化&#xff0c;而系统最大的瓶颈在于数据库&#xff0c;根据实际业务情况&#xff0c;决定对数据…

迅镭激光董事长颜章健受邀参加江苏师范大学研究生毕业答辩活动

5月20日&#xff0c;迅镭激光董事长颜章健应邀赴江苏师范大学物电学院进行为期2天的考察交流&#xff0c;并作为特聘专家参加光电信息工程专业研究生毕业答辩活动。 校企携手 再谱新篇 考察期间&#xff0c;江苏师范大学物电学院举行欢迎座谈会&#xff0c;江苏师范大学学科办…

二叉搜索树(查找、插入、删除的讲解实现+图文并茂)

目录 1. 二叉搜索树&#xff08;BST&#xff09; 1.1 二叉搜索树概念 1.2 二叉搜索树操作 1.2.1 二叉搜索树的查找 1.2.2 二叉搜索树的插入 1.2.3 二叉搜索树的删除 2. 二叉搜索树的实现 2.1BST基本结构 2.2 BST操作成员函数(非递归&#xff09; 2.3 BST操作成员函数&#x…

开放式耳机是什么意思?2023年开放式耳机推荐指南

开放式耳机&#xff0c;就是开放耳朵不需要塞入耳道的一种耳机。 这种耳机包括气传导和骨传导两种类型。气传导耳机采用波束成形技术进行定向传音&#xff0c;将音频传送到耳朵&#xff0c;其所采用的空气传导原理在发声的时候不会引起振动。 而骨传导耳机则是通过震动颅骨来…

HttpRunnerManager接口自动化测试框架在win环境下搭建教程

近几日一直在研究如何把接口自动化做的顺畅&#xff0c;目前用的是轻量级jmeterantJenkins自动化测试框架&#xff0c;目前测试界的主流是python语言&#xff0c;所以一直想用搭建一个基于python的HttpRunnerManager。公司项目也比较多&#xff0c;在上班的过程中偶尔研究了一下…

【Linux高级 I/O(6)】初识文件锁—— flock()方法(附代码示例)

想象一下&#xff0c;当两个人同时编辑磁盘中同一份文件时&#xff0c;其后果将会如何呢&#xff1f;在 Linux 系统中&#xff0c;该文件的最后状态通常取决于写该文件的最后一个进程。多个进程同时操作同一文件&#xff0c;很容易导致文件中的数据发生混乱&#xff0c;因为多个…

【UE】制作追踪导弹

效果 步骤 1. 首先在虚幻商城下载所需素材 2. 打开“BP_West_Missile_M26” 勾选模拟物理 添加一个变量&#xff0c;命名为“Target” 该变量用来表示导弹追踪的目标&#xff0c;变量类型为actor的对象引用&#xff0c;勾选可编辑实例和生成时公开 在事件图表中添加如下节点 3…

Swin Transformer 论文精读

Swin Transformer 论文精读 https://www.bilibili.com/video/BV13L4y1475U Swin 几乎涵盖了 CV 的下游任务&#xff08;下游任务指骨干网后面的 head 解决的任务&#xff0c;如&#xff1a;分类、检测、语义分割&#xff09;&#xff0c;并且曾经刷新多个数据集的榜单。 题目…

记一次符合Google Coding Style的Bash脚本重构

最近我在思考这样一个问题&#xff0c;顺便看一下gpt对这个问题的解释。搜索发现&#xff1a; 团队写代码&#xff0c;为什么要遵循coding guideline&#xff1f; 一致性&#xff1a;编码准则确保整个团队的代码风格和格式是一致的&#xff0c;这使得团队成员之间更易于交流和…

人工智能(Pytorch)搭建模型6-使用Pytorch搭建卷积神经网络ResNet模型

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能(Pytorch)搭建模型6-使用Pytorch搭建卷积神经网络ResNet模型&#xff0c;在本文中&#xff0c;我们将学习如何使用PyTorch搭建卷积神经网络ResNet模型&#xff0c;并在生成的假数据上进行训练和测试。本文将…

Linux---vi/vim编辑器、查阅命令

1. vi\vim编辑器三种模式 vim 是 vi 的加强版本&#xff0c;兼容 vi 的所有指令&#xff0c;不仅能编辑文本&#xff0c;而且还具有 shell 程序编辑的功能&#xff0c; 可以不同颜色的字体来辨别语法的正确性&#xff0c;极大方便了程序的设计和编辑性。 命令模式&#xff08…

整数智能重磅推出集成SAM的智能标注工具2.0

前言 图像语义分割一直是数据标注中最繁琐、最耗时的标注任务之一&#xff0c;利用钢笔工具手动描边的标注方式所带来的时间成本和低准确率都将影响模型的生产速度和模型性能。整数智能ABAVA数据工程平台最新发布了基于SAM&#xff08;Segement Anything Model&#xff09;改进…