cubemx stm32 esp8266传感器 wifi模块 获取网络时间驱动代码

本文介绍如何使用ESP8266模块通过Wi-Fi连接互联网并获取网络时间进行本地时间同步。主要内容包括配置ESP8266模块、发送AT指令集、处理接收的数据以及实现时间同步。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

esp8266

这就不介绍了吧,我主要做驱动的

cubemx配置

开个串口,并打开对应的中断

在这里插入图片描述

在这里插入图片描述

代码

esp8266.c

#include "esp8266.h"

#include "delay.h"	
#include "string.h"		
#include "O_redirect.h" 

#include "gpio.h"
#include "usart.h"

/*错误类型*/
typedef enum
{
	REV_OK = 0,
	REV_FAIL
}REV_Bool;


/*Macro definition Start*/

/* WIFI*/
#define ESP8266_WIFI_INFO		"AT+CWJAP=\"ssid\",\"password\"\r\n"
#define ESP8266_TCP_INFO		"AT+CIPSTART=\"TCP\",\"www.bilibili.com\",80\r\n"

esp_time_Struct esp_time;


/*Macro definition End*/

/*Global variable Start*/
esp8266_Struct esp_InitStr;//esp8266 struct

unsigned char ESP_flag=0;

/*Global variable End*/


/*Internal function declaration Start*/
static void esp8266_Struct_ClearInit(void);

/*Internal function declaration End*/

/*Internal function implementation Start*/

/*
 * esp8266_Struct_ClearInit
 * Clear_Init esp8266_Struct
 * 
 * 
 * 
*/
static void esp8266_Struct_ClearInit(void)
{
	for(uint16_t i=0; i<ESP8266_BUF_SIZE; i++)
	{
		esp_InitStr.esp8266_buf[i] = 0;
	}
	esp_InitStr.a_esp8266_buf = 0;
	esp_InitStr.esp8266_cnt = 0;
	esp_InitStr.esp8266_cntPre = 0;
}

/*Internal function implementation End*/


/*External function Start*/

/*
 * ESP8266_Clear
 * Clear esp8266_Struct
 * 
 * 
 * 
*/
void ESP8266_Clear(void)
{
	memset(esp_InitStr.esp8266_buf, 0, sizeof(esp_InitStr.esp8266_buf)); // Empty ESP array
	esp_InitStr.esp8266_cnt = 0;
}
	
	
/*
 * ESP8266_WaitRecive
 * Waiting for receiving
 * 
 * 
 * 
 * 
*/
bool ESP8266_WaitRecive(void)
{
	if(esp_InitStr.esp8266_cnt == 0) // NO data
	{
		return REV_FAIL;
	}
	if(esp_InitStr.esp8266_cnt == esp_InitStr.esp8266_cntPre)	//Finished receiving
	{
		esp_InitStr.esp8266_cnt = 0;	// 
		return REV_OK;					
	}

	esp_InitStr.esp8266_cntPre = esp_InitStr.esp8266_cnt;	//
	return REV_FAIL;
}


/*
 * ESP8266_SendCmd
 * 
 * 
 * 
 * 
*/

bool ESP8266_SendCmd(uint8_t * cmd, uint8_t * res)
{
	uint16_t timeOut = ESP8266_BUF_SIZE;
	//Start UART Send cmd
	HAL_UART_Transmit(&ESP_huart, cmd, strlen((const char *)cmd),0xffff);

	while(timeOut--)	// Wait for receiving after sending
	{
		if(ESP8266_WaitRecive() == REV_OK)	// Data receiving completed
		{
//			U_Printf("%s\r\n", esp_InitStr.esp8266_buf);	// Print data
			
			if(strstr((const char *)esp_InitStr.esp8266_buf, (const char *)res) != NULL)
				// String matching
			{
				ESP8266_Clear();	// Clear ESP_Struct
				return 0;
			}
		}

		delay_ms(10);
	}
	
	ESP8266_Clear();	// Clear ESP_Struct
	return 1;
}


/*
 * ESP8266_SendData
 * Send data
 * 
*/
void ESP8266_SendData(uint8_t *data, uint16_t len)
{
	uint8_t cmdBuf[32];			
	ESP8266_Clear();			
	
	sprintf((char *)cmdBuf, "AT+CIPSEND=%d\r\n", len); // Send cmd
	
	if(!ESP8266_SendCmd(cmdBuf, (uint8_t *)'>'))	// Data can be sent after receiving'>'
	{
		HAL_UART_Transmit(&ESP_huart, data, len, 0xffff); // Data send
	}
}

/*
 * ESP8266_GetIPD
 * 
 * 
 * 
*/
uint8_t *ESP8266_GetIPD(uint16_t timeOut)
{
	uint8_t *ptrIPD = NULL;
	while(timeOut)
	{
		if(ESP8266_WaitRecive() == REV_OK)
		{
			ptrIPD = (uint8_t *)strstr((char *)esp_InitStr.esp8266_buf, "IPD,"); // Search "IPD," hander
			if(ptrIPD != NULL) 
			{
				ptrIPD = (uint8_t *)strchr((const char *)ptrIPD, ':'); // Found ':'
				if(ptrIPD != NULL)
				{
					ptrIPD++;
					return (uint8_t *)(ptrIPD); 
				}
				else
				{
					return NULL;
				}
			}
		}
		
		delay_ms(10);
		timeOut--;
	}
	return NULL; 
}

/*
 * ESP8266_Init
 * 
 * 
 * 
*/
void ESP8266_Init(void)
{
	esp8266_Struct_ClearInit();	//
	
	HAL_UART_Receive_IT(&ESP_huart, (uint8_t *)&(esp_InitStr.a_esp8266_buf), 1);//开启wifi接收中断

	U_Printf("1. AT\r\n");
	while(ESP8266_SendCmd((uint8_t *)"AT\r\n", (uint8_t *)"OK"))
		delay_ms(50);
	
	U_Printf("2. CWMODE\r\n");
	while(ESP8266_SendCmd((uint8_t *)"AT+CWMODE=1\r\n", (uint8_t *)"OK"))
		delay_ms(50);
	
	U_Printf("3. AT+CWDHCP\r\n");
	while(ESP8266_SendCmd((uint8_t *)"AT+CWDHCP=1,1\r\n", (uint8_t *)"OK"))
		delay_ms(50);
	
	U_Printf("4. AT+CWJAP\r\n");
	while(ESP8266_SendCmd((uint8_t *)ESP8266_WIFI_INFO, (uint8_t *)"OK"))
		delay_ms(50);
	
	uint8_t iii=0;
	while(iii++ <= 5)
	{
		GetTime();
	}
	
	U_Printf("ESP8266 OK!!!\r\n");
}

/* 获取网络时间 */


void GetTime(void)
{
	U_Printf("GetTime...\r\n");
	while(ESP8266_SendCmd((uint8_t *)ESP8266_TCP_INFO, (uint8_t *)"CONNECT"))
		delay_ms(10);
	
	/* 发送GET请求 */
	ESP8266_SendData((uint8_t*)"GET\n",4);
	
	/* 获取服务器返回的时间信息用于校准RTC */
	uint8_t *ipd = NULL;
	ipd = ESP8266_GetIPD(100);
	if(ipd != NULL)
	{
		char str[30];
		char * strSon;
		ipd = (uint8_t*)strstr((char*)ipd, "Date:");
		strncpy(str, (char*)(ipd + 6), 30);
//		U_Printf("Time: %s\r\n", str);
		
		strSon = strstr((const char *)str, (const char *)"202");
		if(strSon != NULL)
		{
			esp_time.esp_hour	= ((*(strSon+ 5)-48)*10) + (*(strSon+ 6)-48) + 8; //0时区加8小时到北京时间
			if(esp_time.esp_hour>23)
			{
				esp_time.esp_hour -= 24;
			}
			esp_time.esp_min	= ((*(strSon+ 8)-48)*10) + (*(strSon+ 9)-48);
			esp_time.esp_sec	= ((*(strSon+11)-48)*10) + (*(strSon+12)-48);
			
//			U_Printf("strSon:%s\r\n", strSon+5);
			U_Printf("time:%d:%d:%d\r\n", 
			esp_time.esp_hour, esp_time.esp_min, esp_time.esp_sec);
		}
	}
}


/*esp8266串口中断函数*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance == ESP_UART)
	{
		if(esp_InitStr.esp8266_cnt >= ESP8266_BUF_SIZE)//溢出判断
		{
			U_Printf("ESP data overflow\r\n");
//			U_Printf("%s\r\n", esp_InitStr.esp8266_buf);

			esp_InitStr.esp8266_cnt = 0;
			memset(esp_InitStr.esp8266_buf, 0, sizeof(esp_InitStr.esp8266_buf));
		}
		else
		{
			//数据存入
//			U_Printf("%d : %c\r\n", esp_InitStr.esp8266_cnt, esp_InitStr.a_esp8266_buf);
			
			esp_InitStr.esp8266_buf[esp_InitStr.esp8266_cnt] = esp_InitStr.a_esp8266_buf;
			esp_InitStr.esp8266_cnt++;
		}
		HAL_UART_Receive_IT(&ESP_huart, (uint8_t *)&(esp_InitStr.a_esp8266_buf), 1);   //再开启接收中断
	}
}

/*Extrnal function End*/





esp8266.h

#ifndef __ESP8266_H_
#define __ESP8266_H_

#include "stdbool.h"	//bool开启库
#include "stdint.h"

#define ESP_huart	huart3
#define ESP_UART	USART3
#define ESP_print	U_UART3

#define ESP8266_BUF_SIZE	1024	//缓冲区大小

typedef struct esp8266_struct
{
	uint8_t  esp8266_buf[ESP8266_BUF_SIZE];//wifi缓冲存取区
	uint8_t  a_esp8266_buf;		//缓冲区元素暂存位置
	uint16_t esp8266_cnt;			//当前接收计数
	uint16_t esp8266_cntPre;	//上次计数
}esp8266_Struct;

typedef struct espTime
{
	uint8_t esp_hour;
	uint8_t esp_min;
	uint8_t esp_sec;
	uint8_t esp_GetTimeCnt;	// 获取时间计数
}esp_time_Struct;

/*全局变量区*/
extern esp8266_Struct esp_InitStr;	//esp 结构体
extern esp_time_Struct esp_time;	//esp 获取的时间
extern unsigned char ESP_flag;		//联网flag

/*枚举区*/


/*函数区*/
void ESP8266_Clear(void);
bool ESP8266_WaitRecive(void);
bool ESP8266_SendCmd(uint8_t * cmd, uint8_t * res);
void ESP8266_SendData(uint8_t *data, uint16_t len);
uint8_t *ESP8266_GetIPD(uint16_t timeOut);
void ESP8266_Init(void);
//void Onenet_Link(void);
//void ssidPass_wifi(uint8_t * ssid, uint8_t * wifiPassword);//通过ssid和密码登入WiFi

void GetTime(void); // 获取网络时间 


#endif /*__ESP8266_H_*/

初始化

ESP8266_Init();

获取网络时间

代码更改

更改ssid和密码连接周围wifi即可获取网络时间

在这里插入图片描述

代码使用

GetTime();

U_Printf("%02d:%02d:%02d", esp_time.esp_hour, esp_time.esp_min, esp_time.esp_sec); // 通过串口1发送到电脑上

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入一下?

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值