串口初始化代码就不分享了,大家都有的,我做的是回环测试,也就是用了两个串口,一个串口给ESP8266发送指令,另一个接收他发回来的数据,如果需要代码最后会给
先分享一下代码,大概讲解一下(从简)

建立连接

//Server:服务器类型	IP:服务器地址	PORT:端口号
void ESP_CIPSTART(const char* Server,const char* IP,const char* PORT)
{
	char temp[40] = {0};
	uint8_t k = 0;
	sprintf(temp,"AT+CIPSTART=\"%s\",\"%s\",%s\r\n",Server,IP,PORT);
	while(temp[k]!='\0')
	{
		USART_SendByte(ESP_USARTx,temp[k]);
		while(USART_GetFlagStatus(ESP_USARTx,USART_FLAG_TXE) == RESET);
		k++;
	}
	while(USART_GetFlagStatus(ESP_USARTx,USART_FLAG_TC) ==RESET);
}

CIPSTART不懂,那就去先了解AT指令

检测响应

//rsp:你要检测的响应字符串,waitTimes_ms:超时退出
uint8_t ESP_Check_Respond(const char* rsp,u16 waitTimes_ms)
{
	while((strstr(ESP_Usart_RecBuf,rsp) == NULL)&&(--waitTimes_ms))
	{
		delay_ms(1);
	}
	if(waitTimes_ms) return SUCCESS;
	else return ERROR;
}

strstr是标准库string.h的,include

发送命令字符串

//Enter是否加入换行 1就加入
void ESP8266_SendATcmd(const char* AT_cmd,u8 Enter)
{
	char CMDBuf[20] = {0};
	uint8_t k = 0;
	strcat(CMDBuf,AT_cmd);
	if(Enter)
	{	
		strcat(CMDBuf,"\r\n");	//加入换行
	}
	while(*(CMDBuf+k)!='\0')
	{
		USART_SendByte(ESP_USARTx,*(CMDBuf+k));
		while(USART_GetFlagStatus(ESP_USARTx,USART_FLAG_TXE) == RESET);
		k++;
	}
	while(USART_GetFlagStatus(ESP_USARTx,USART_FLAG_TC) ==RESET);
}
void ESP_SendString(const char* str)
{
	uint8_t k = 0;
	do
	{
		USART_SendByte(ESP_USARTx,str[k]);
		while(USART_GetFlagStatus(ESP_USARTx,USART_FLAG_TXE) == RESET);
		k++;
	}while(*(str+k)!='\0');
	while(USART_GetFlagStatus(ESP_USARTx,USART_FLAG_TC) == RESET);
}

发送AT指令、发送字符串(向ESP8266)
基于上面两个函数,我定义了一些宏

#define	OPEN_PTMODE()				ESP8266_SendATcmd("AT+CIPMODE=1",1)	//打开透传模式,要记得关
#define	CLOSE_PTMODE()				ESP_SendString("+++")				//退出透传模式(重要!不然会一直接收数据)
#define	CMD_CIPCLOSE()				ESP_SendString("AT+CIPCLOSE\r\n")	//退出IP
#define CMD_AT()					ESP8266_SendATcmd(AT,CMD_ENTER)
#define	CMD_RST()					ESP8266_SendATcmd(AT_RST,CMD_ENTER)

获取时间

NETWORK_TIME myTime;
//获取网络时间
uint8_t Get_NetWork_Time(void)
{
	
	uint8_t GetFlag = 0;
	ESP_CIPSTART("TCP","www.beijing-time.org","80");
	delay_ms(50);
	if(ESP_Check_Respond("CONNECT",400) == 0)
	{
		ESP_ERROR("ERROR0");
		return 0;
	}
	//delay_ms(1000);
	OPEN_PTMODE();							//开透传
	delay_ms(50);
	if(ESP_Check_Respond("OK",400) == 0)
	{
		CLOSE_PTMODE();	
		ESP_ERROR("ERROR1");
		return 0;
	}
	ESP8266_SendATcmd("AT+CIPSEND",1);
	delay_ms(50);
	if(ESP_Check_Respond("OK",400) == 0)
	{
		CLOSE_PTMODE();	
		ESP_ERROR("ERROR1");
		return 0;
	}
	ESP_SendString("GET /time15.asp HTTP/1.1\r\nHost:www.beijing-time.org\r\n");
	ESP_SendString("GET /time15.asp HTTP/1.1\r\nHost:www.beijing-time.org\r\n");
	delay_ms(500);
	if(GetNET_Time(&myTime,ESP_Usart_RecBuf))	GetFlag = 1;
	//delay_ms(1000);
	CLOSE_PTMODE();		//关透传
	delay_ms(50);	
	CMD_CIPCLOSE();		//退出IP
	delay_ms(50);					
	return GetFlag;
}

先别急着看代码,我说一下这个函数的流程是,建立连接,开启透传(记得关).发送CIPSEND指令开始进入发送模式,然后发送两次获取时间的字符串(不知道为什么要发两次),然后通过一个函数(GetNET_Time)提取时间数据,成功提取返回1,失败为0,最后关闭透传,切记),退出连接.下面分享一下怎么提取数据。

提取时间数据

先给大家看一下格式

HTTP/1.1 400 Bad Request
Content-Type: text/html; charset=us-ascii
Server: Microsoft-HTTPAPI/2.0
Date: Thu, 30 Jul 2020 13:58:01 GMT
Connection: close
Content-Length: 339

很明显,Date后面就是数据了,这样照葫芦画瓢,定义一个结构体来存储这些数据

typedef struct
{
	char week[5];
	char date[3];
	char month[5];
	char year[6];
	char hours[4];
	char minute[4];
	char seconds[4];
} NETWORK_TIME;

上代码

uint8_t GetNET_Time(NETWORK_TIME* time,char *Timestr)
{
	char* pbuf = NULL;
	pbuf = strstr(Timestr,"Date:");
	if(pbuf)
	{
		if(sscanf(pbuf,"%*[^:]: %[^,], %[^ ] %[^ ] %[^ ] %[^:]:%[^:]:%[^ ]",
		time->week,time->date,time->month,time->year,time->hours,time->minute,time->seconds))
		{
			return 1;
		}
	}
	return 0;
}

sscanf在stdio.h, include进去,sscanf用法自己查
说一下过程,传入数组缓冲区数据,然后用strstr函数查找”Date:“这个字符所在位置(指针),最后传入sscanf按格式提取出年月日。。。等时间数据(字符串)。
可能有些人不懂数组缓冲区,我以前发了一篇IDLE中断,需要的可以看看,同样可以定义一个ESP用到的串口的接收缓冲。
下面来测试一下结果,分享我的测试代码

extern NETWORK_TIME myTime;
int thour;
int tmin;
int tsec;
int main()
{
	/*Parameter Configuration*/
	
	/*Init*/
	delay_init(168);
	USART_Config();
	LED_GPIO_Config();
	ESP8266_USART_Config();	//初始化ESP的串口
	ESP_Idle_Receive_Config();	//初始化空闲接收中断
	/*Configuration Operation*/
	ESP8266_SendATcmd("AT+RST",1);	//一定要复位一下,并且连上WIFI,CWMODE=1或者3
	if(Get_NetWork_Time())
		{
			sscanf(myTime.hours,"%d",&thour);
			sscanf(myTime.minute,"%d",&tmin);
			sscanf(myTime.seconds,"%d",&tsec);
			printf("\r\n%s %d:%d:%d",myTime.year,thour+8,tmin,tsec);
		}
	/*LOOP*/
	while(1)
	{
		LED1_TOGGLE;
		delay_ms(500);
	}
}

我把字符串转化成整型了,其实也可以直接使用字符串,%s就行了,我转成整型是因为时间有时差,那是0度线的时间,我也不知道哪里,北京时间+8就对了(东8区?)

我的结果:

esp32读取电脑信息 esp32 获取时间_esp32读取电脑信息

回环测试

#define	ESP_USE_IDLE_RECEIVE		//是否开启空闲接收中断
#define ESP_USART_REC_BUFSIZE		100
//头文件↑

static u16 ESP_Usart_Count = 0;		//接收计数,在中断函数调用
char ESP_Usart_RecBuf[ESP_USART_REC_BUFSIZE]; 
#ifdef ESP_USE_IDLE_RECEIVE
void ESP_USARTx_IRQHandle()
{
	u16 times;
	if(USART_GetITStatus(ESP_USARTx,USART_IT_RXNE) != RESET)
	{
		ESP_Usart_RecBuf[ESP_Usart_Count] = USART_ReceiveData(ESP_USARTx);
		ESP_Usart_Count++;
	}
	if(USART_GetITStatus(ESP_USARTx,USART_IT_IDLE) != RESET)
	{
		ESP_Usart_RecBuf[ESP_Usart_Count] = USART_ReceiveData(ESP_USARTx);
		//ESP_Usart_Count++;
		/*此处加入对接收缓冲区的操作*/
		for(times = 0;times < ESP_Usart_Count;times++)
		{
			USART_SendByte(DEBUG_USART,ESP_Usart_RecBuf[times]);
		}
		ESP_Usart_Count = 0;
	}
}
#endif