ESP8266+STM32获取天气时间信息

定时器模块介绍(timer.c):

也是用到了两个定时器,定时器二和定时器三。定时器二用来按键扫描。定时器三用来作为本地是时钟源,运行解析出来的时间。

贴一下定时器的初始化代码,STM32的定时器模块还是比较复杂的,不懂的自己去学习一下。

//==================================================================
//函 数 名:TIM3_Int_Init(u32 arr,u16 psc)
//功能描述:定时器3初始化函数
//输入参数:arr-自动重装载值 pre-预分频值 
//定时长度:72000000/(arr+1)*(pre+1)
//==================================================================
void TIM3_Int_Init(u32 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
 
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
 
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	 计数到5000为500ms
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
 
	TIM_ITConfig( TIM3,TIM_IT_Update,ENABLE); //使能或者失能指定的TIM中断
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器					 
}

//==================================================================
//函 数 名:Timer2_Init(void)
//功能描述:定时器2初始化函数
//输入参数:无
//==================================================================
void Timer2_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	
	TIM_InternalClockConfig(TIM2);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 999;
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
}
    

时间解析模块介绍(time.c):

时间戳转换模块是我在网上摘抄下来的,我看csdn平台也有人写相关的,但我看的文章不是csdn的。但现在找关键词找不到了,这里就直接引用了。感谢原作者!

#include <stdio.h>
#include "OLED.h"
#include "timer.h"
#include "time.h"

typedef unsigned short  uint16_t;
typedef unsigned int    uint32_t;
//全局变量,存储时间
int year_1,month_1,day_1,hour_1,minter_1,sec_1,week_1;
//暂时没用的,有时间改一下函数结构,去冗余
const uint16_t month_days_table[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};


/**
* @brief        判断是否为闰年  注:原文的链接忘记复制了,感谢该作者
* @param        [in] year 年
* @retval       1 为闰年
* @retval       0 为平年
*/
uint16_t fml_leap_year(uint16_t year)
{
    return (((year % 4 == 0)&&(year % 100 != 0)) || (year % 400 == 0));
}
 
 
/**
* @brief        日期转时间戳
* @param        [in] date 日期值
* @retval       =0 成功
* @retval       非0 失败,以及失败原因
*/
uint32_t fml_time_to_stamp(date_time_t date)
{
    static  uint32_t dax = 0;
    static  uint32_t day_count = 0;
    uint16_t leap_year_count = 0;
    uint16_t i;
 
    // 计算闰年数
    for (i = 1970; i < date.year; i++)
    {
        if (fml_leap_year(i))
        {
            leap_year_count++;
        }
    }
 
    // 计算年的总天数
    day_count = leap_year_count * 366 + (date.year - 1970 - leap_year_count) * 365;
 
    // 累加计算当年所有月的天数
    for (i = 1; i < date.month; i++)
    {
        if ((2 == i) && (fml_leap_year(date.year)))
        {
            day_count += 29;
        }
        else
        {
            day_count += month_days_table[i];
        }
    }
 
    // 累加计算当月的天数
    day_count += (date.day - 1);
 
    dax = (uint32_t)(day_count * 86400) + (uint32_t)((uint32_t)date.hour * 3600) + (uint32_t)((uint32_t)date.min * 60) + (uint32_t)date.sec;
 
    /* 北京时间补偿 */
    dax = dax - 8*60*60;
 
    return dax;
}
 
//==================================================================
//函 数 名:fml_stamp_to_time;
//功能描述:时间戳转换年月日
//输入参数:无
//公式来源:蔡勒公式
//==================================================================
uint32_t fml_stamp_to_time( uint32_t timep, date_time_t *date)
{
    uint32_t days = 0;
    uint32_t rem = 0;
 
    /* 北京时间补偿 */
    timep = timep + 8*60*60;
 
    // 计算天数
    days = (uint32_t)(timep / 86400);
    rem = (uint32_t)(timep % 86400);
 
 
    // 计算年份
    uint16_t year;
    for (year = 1970; ; ++year)
    {
        uint16_t leap = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
        uint16_t ydays = leap ? 366 : 365;
        if (days < ydays)
        {
            break;
        }
        days -= ydays;
    }
    date->year  =  year;
 
 
    // 计算月份
    static const uint16_t days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    uint16_t month;
    for (month = 0; month < 12; month++)
    {
        uint16_t mdays = days_in_month[month];
        if (month == 1 && ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
        {
            mdays = 29;
        }
        if (days < mdays)
        {
            break;
        }
        days -= mdays;
    }
    date->month = month;
    date->month += 1;
 
    // 计算日期
    date->day = days + 1;
 
    // 计算时间
    date->hour = rem / 3600;
    rem %= 3600;
    date->min = rem / 60;
    date->sec = rem % 60;
	year_1 = data1.year;
	month_1 = data1.month;
	day_1 = data1.day;
	hour_1 = data1.hour;
	minter_1 = data1.min;
	sec_1 = data1.min;
    return 0;
}
//==================================================================
//函 数 名:get_week();
//功能描述:计算出星期
//输入参数:无
//公式来源:蔡勒公式
//==================================================================
void get_week(void)
{
	if (month_1 == 1 || month_1 == 2)//判断month是否为1或2 
			year_1--, month_1 += 12;
		int c = year_1 / 100;
		int y = year_1 - c * 100;
		int week = y + y / 4 + c / 4 - 2 * c + 26 * (month_1 + 1) / 10 + day_1 - 1;
		while (week < 0)
		week += 7;
		week %= 7;
		week_1 = week;
}

我这里修改了时间戳转换日期的函数、新增一个星期转换函数。传入10位数的时间戳就可得出对应的日期。

OLED模块介绍(oled.c):

OLED的库函数我也是走了不少弯路才找到的,过程曲折,没想到答案远在天边近在眼前。感谢中景园电子!

这个库函数的功能是我见过比较丰富的了,还有更复杂的是GITHUB上的自制驱动,但是他们用的OLED屏幕和我用的不一样,试图移植过但失败了。贴上.h文件,给大伙看看这个驱动能实现的功能。

/*初始化函数*/
void OLED_Init(void);

/*更新函数*/
void OLED_Update(void);
void OLED_UpdateArea(uint8_t X, uint8_t Y, uint8_t Width, uint8_t Height);

/*显存控制函数*/
void OLED_Clear(void);
void OLED_ClearArea(uint8_t X, uint8_t Y, uint8_t Width, uint8_t Height);
void OLED_Reverse(void);
void OLED_ReverseArea(uint8_t X, uint8_t Y, uint8_t Width, uint8_t Height);

/*显示函数*/
void OLED_ShowChar(uint8_t X, uint8_t Y, char Char, uint8_t FontSize);
void OLED_ShowString(uint8_t X, uint8_t Y, char *String, uint8_t FontSize);
void OLED_ShowNum(uint8_t X, uint8_t Y, uint32_t Number, uint8_t Length, uint8_t FontSize);
void OLED_ShowSignedNum(uint8_t X, uint8_t Y, int32_t Number, uint8_t Length, uint8_t FontSize);
void OLED_ShowHexNum(uint8_t X, uint8_t Y, uint32_t Number, uint8_t Length, uint8_t FontSize);
void OLED_ShowBinNum(uint8_t X, uint8_t Y, uint32_t Number, uint8_t Length, uint8_t FontSize);
void OLED_ShowFloatNum(uint8_t X, uint8_t Y, double Number, uint8_t IntLength, uint8_t FraLength, uint8_t FontSize);
void OLED_ShowChinese(uint8_t X, uint8_t Y, char *Chinese);
void OLED_ShowImage(uint8_t X, uint8_t Y, uint8_t Width, uint8_t Height, const uint8_t *Image);
void OLED_Printf(uint8_t X, uint8_t Y, uint8_t FontSize, char *format, ...);

/*绘图函数*/
void OLED_DrawPoint(uint8_t X, uint8_t Y);
uint8_t OLED_GetPoint(uint8_t X, uint8_t Y);
void OLED_DrawLine(uint8_t X0, uint8_t Y0, uint8_t X1, uint8_t Y1);
void OLED_DrawRectangle(uint8_t X, uint8_t Y, uint8_t Width, uint8_t Height, uint8_t IsFilled);
void OLED_DrawTriangle(uint8_t X0, uint8_t Y0, uint8_t X1, uint8_t Y1, uint8_t X2, uint8_t Y2, uint8_t IsFilled);
void OLED_DrawCircle(uint8_t X, uint8_t Y, uint8_t Radius, uint8_t IsFilled);
void OLED_DrawEllipse(uint8_t X, uint8_t Y, uint8_t A, uint8_t B, uint8_t IsFilled);
void OLED_DrawArc(uint8_t X, uint8_t Y, uint8_t Radius, int16_t StartAngle, int16_t EndAngle, uint8_t IsFilled);

支持两个大小的汉字显示、数字字母显示、图像显示、简单的图形绘制、图片显示。

还是和第一版的一样,我会把取字模和图像的软件打包起来,直接用就可以。

ESP8266驱动函数(ESP8266.c):

这个就比较的复杂了,直接贴代码吧,大家看了有不懂的评论区留言我帮忙解答

#include "stm32f10x.h"
#include "sys.h"
#include "string.h"
#include "stdlib.h"
#include "esp8266.h"
#include "usart2.h"
#include "delay.h"
#include "init.h"

//WIFI的SSID和密码
#define ESP8266_WIFI_INFO		"AT+CWJAP=\"TP-LINK_C568\",\"zz18835784774\"\r\n"

//心知天气API
#define Xinzhi_TCP		"AT+CIPSTART=\"TCP\",\"api.seniverse.com\",80\r\n"
//拼多多API
#define Time_TCP		"AT+CIPSTART=\"TCP\",\"qapi.pinduoduo.com\",80\r\n"


//获取当天天气
#define Now_GET			"GET https://api.seniverse.com/v3/weather/now.json?key=SEa9maHD3BOFLn8Xv&location=beijing&language=en&unit=c\r\n"
//获取天气预报
#define Forcast_GET		"GET https://api.seniverse.com/v3/weather/daily.json?key=SEa9maHD3BOFLn8Xv&location=beijing&language=en&unit=c&start=0&days=3\r\n"
//获取生活指数
#define Life_GET		"GET https://api.seniverse.com/v3/life/suggestion.json?key=SEa9maHD3BOFLn8Xv&location=shanghai&language=en&days=1\r\n"
//获取拼多多时间戳
#define Time_GET		"GET https://api.pinduoduo.com/api/server/_stm\r\n"

unsigned char esp8266_buf[1000] = {0};
unsigned short esp8266_cnt = 0, esp8266_cntPre = 0;
unsigned char Xinzhi_buff[1000];   
unsigned char Time_buff[50];   

//==================================================================
//函 数 名:ESP8266_Init()
//功能描述:ESP8266模块初始化
//介绍说明:按照我写的第一篇文章的步骤,使用串口助手在电脑端通过串口
//助手分别发送相应的AT指令验证是否能初始化
//==================================================================
void ESP8266_Init(void)
{
    ESP8266_Clear();
    while(ESP8266_SendCmd("+++", ""));               
    while(ESP8266_SendCmd("AT+RESTORE\r\n", "OK"));   
    while(ESP8266_SendCmd("AT\r\n", "OK"));           
    ESP8266_SendCmd("AT+RST\r\n", "");                
    delay_ms(500);
    ESP8266_SendCmd("AT+CIPCLOSE\r\n", "");           
    delay_ms(500);
    while(ESP8266_SendCmd("AT+CWMODE=1\r\n", "OK"));   
    while(ESP8266_SendCmd("AT+CIPMUX=0\r\n", "OK"));   
    while(ESP8266_SendCmd(ESP8266_WIFI_INFO, "WIFI GOT IP"));
}

//==================================================================
//函 数 名:Get_current_time(unsigned char s)
//功能描述:获取指定API的数据
//介绍说明:按照我写的第一篇文章的步骤,使用串口助手在电脑端通过串口
//助手分别发送相应的AT指令验证是否能获取到对应的数据报文
//==================================================================
void Get_current_time(unsigned char s)
{
    ESP8266_Init();	                                   
    ESP8266_Clear();  
	switch(s)
	{
		//case 0:获取时间戳报文
		case 0 :{while(ESP8266_SendCmd(Time_TCP, "CONNECT"));      
		         while(ESP8266_SendCmd("AT+CIPMODE=1\r\n", "OK"));
		         ESP8266_SendData((u8 *)Time_GET, sizeof(Time_GET));
		         ESP8266_GetIPD_GET(50, Time_buff); 
			} break;
		//case 1:获取当前天气报文
		case 1 :{while(ESP8266_SendCmd(Xinzhi_TCP, "CONNECT"));       
		         while(ESP8266_SendCmd("AT+CIPMODE=1\r\n", "OK"));  
		         ESP8266_SendData((u8 *)Now_GET, sizeof(Now_GET));
		         ESP8266_GetIPD_GET(200, Xinzhi_buff);               
			} break;
		//case 2:获取天气预报报文
		case 2 :{while(ESP8266_SendCmd(Xinzhi_TCP, "CONNECT"));       
		         while(ESP8266_SendCmd("AT+CIPMODE=1\r\n", "OK"));  
		         ESP8266_SendData((u8 *)Forcast_GET, sizeof(Forcast_GET));
		         ESP8266_GetIPD_GET(1000, Xinzhi_buff);               
			} break;
		//case 3:未完成部分-生活指数
//		case 3 :{while(ESP8266_SendCmd(Xinzhi_TCP, "CONNECT"));       
//		         while(ESP8266_SendCmd("AT+CIPMODE=1\r\n", "OK"));  
//		         ESP8266_SendData((u8 *)Life_GET, sizeof(Life_GET));
//		         ESP8266_GetIPD_GET(1000, Xinzhi_buff);               
//			} break;
	}
    ESP8266_Clear();
    while(ESP8266_SendCmd("+++", ""));              
}


#define  NAME_ADD_DRES 7
#define  TEXT_ADD_DRES 7
#define  TEMP_ADD_DRES 14

#define  HIGH_TEMP_DRES 7
#define  LOW_TEMP_DRES 6
#define  RAINFALL_DRES 11
#define  WIND_DIRCTION 17
#define  WIND_SCAL 13
#define  HUMITIDITY 11

//#define  AIR_POLLU 25

#define  TIME_ADD_DRES 13

int TEXT,TEMP,LOW_TEMP,HIGH_TEMP,RAINFALL,WIND_DIR,SCAL_WIND,HUMI;

unsigned int stamp;

//==================================================================
//函 数 名:cJSON_Time_Parse(unsigned char s)
//功能描述:通过标志位启动不同的数据解析方式
//输入参数:0-解析时间、1-解析当前天气、2-解析天气预报
//==================================================================
void cJSON_Time_Parse(unsigned char s)
{
    char *data_pt;   
    char *text_string;
    char *temp_string;
	char *time;
		switch(s){
			case 0:{
						data_pt = strstr((const char *)Time_buff, (const char *)"server_time");
						time = data_pt + TIME_ADD_DRES; 
						stamp = Get_Time(time);
			}    break;       
			case 1:{
						data_pt = strstr((const char *)Xinzhi_buff, (const char *)"code"); 
						text_string = data_pt + TEXT_ADD_DRES;          
						data_pt = strstr((const char *)Xinzhi_buff, (const char *)"temperature"); 
						temp_string = data_pt + TEMP_ADD_DRES;       
						TEXT = Get_Temp(text_string);			     
						TEMP = Get_Temp(temp_string);	
			}    break;
			case 2:{
						data_pt = strstr((const char *)Xinzhi_buff, (const char *)"high");
						time = data_pt + HIGH_TEMP_DRES; 
						HIGH_TEMP = Get_Temp(time);
						data_pt = strstr((const char *)Xinzhi_buff, (const char *)"low");
						time = data_pt + LOW_TEMP_DRES; 
						LOW_TEMP = Get_Temp(time);
						data_pt = strstr((const char *)Xinzhi_buff, (const char *)"rainfall");
						time = data_pt + RAINFALL_DRES; 
						RAINFALL = Get_Temp(time);
						data_pt = strstr((const char *)Xinzhi_buff, (const char *)"wind_direction");
						time = data_pt + WIND_DIRCTION; 
						WIND_DIR = Get_Wind(time);
						data_pt = strstr((const char *)Xinzhi_buff, (const char *)"wind_scale");
						time = data_pt + WIND_SCAL; 
						SCAL_WIND = Get_Temp(time);
						data_pt = strstr((const char *)Xinzhi_buff, (const char *)"humidity");
						time = data_pt + HUMITIDITY; 
						HUMI = Get_Temp(time);
			}    break;
			//未完成部分-生活指数
//			case 3:{
//						data_pt = strstr((const char *)Xinzhi_buff, (const char *)"air_pollution"); 
//						text_string = data_pt + AIR_POLLU;          
//						data_pt = strstr((const char *)Xinzhi_buff, (const char *)"comfort"); 
//						temp_string = data_pt + TEMP_ADD_DRES;       
//						TEXT = Get_Temp(text_string);			     
//						TEMP = Get_Temp(temp_string);	
//			}    break;
    }
}

//==================================================================
//函 数 名:Get_Wind(char *y)
//功能描述:得到风向
//输入参数:无
//介绍说明:不同的返回值代表不同的风向
//==================================================================
int Get_Wind(char *y)
{
	char dir[] = {'W','E','N','S','"'};// 0 1 2 3
	int flag , i , j = 1;
	for(i=0;i<4;i++) 
	{
		if(*y == dir[i]){
			flag = i+4;
		}
	}
	for(i=0;i<2;i++)
	{
		for(j=0;j<2;j++)
		{
			if(*y == dir[i + 2] && *(y+1) == dir[j]){
				if(i==0){flag = i*2 + j*1;};
				if(i==1){flag = i*2 + j*1;};
			}
		}
	}
	return flag;
}

//==================================================================
//函 数 名:Get_Temp(char *y)
//功能描述:从字符串中取出时间戳-最长10位长度
//输入参数:无
//==================================================================
int Get_Temp(char *y)
{
	int temp_return;
    temp_return = atoi(y); 
    return temp_return;
}
 
//==================================================================
//函 数 名:Get_Time(char *d)
//功能描述:从字符串中取出数字-最长7位长度
//输入参数:无
//==================================================================
unsigned int Get_Time(char *d)
{
    unsigned int u;
	char dest[10] = {0};
	strncpy(dest, d, 10);
	u = atoi(dest);
	return u;
}

//==================================================================
//函 数 名:USART2_IRQHandler(void)
//功能描述:串口2中断控制函数
//输入参数:无
//介绍说明:将串口2接收到的数据转发出去
//==================================================================
void USART2_IRQHandler(void)
{
    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) 
    {

        if(esp8266_cnt >= sizeof(esp8266_buf))	esp8266_cnt = 0; 

        esp8266_buf[esp8266_cnt++] = USART2->DR;
		USART_SendData(USART1,USART2->DR);      
		
        USART_ClearFlag(USART2, USART_FLAG_RXNE);
    }
}

/**下面的代码来源于:
	************************************************************
	************************************************************
	************************************************************
	*	文件名: 	esp8266.c
	*
	*	作者: 		张继瑞
	*
	*	日期: 		2017-05-08
	*
	*	版本: 		V1.0
	*
	*	说明: 		ESP8266的简单驱动
	*
	*	修改记录:
	************************************************************
	************************************************************
	************************************************************
**/
//==========================================================
//	函数名称:	ESP8266_Clear
//
//	函数功能:	清空缓存
//
//	入口参数:	无
//
//	返回参数:	无
//
//	说明:
//==========================================================
void ESP8266_Clear(void)
{

    memset(esp8266_buf, 0, sizeof(esp8266_buf));
    esp8266_cnt = 0;

}
//==========================================================
//	函数名称:	ESP8266_SendData
//
//	函数功能:	发送数据
//
//	入口参数:	data:数据
//				len:长度
//
//	返回参数:	无
//
//	说明:
//==========================================================
void ESP8266_SendData(unsigned char *data, unsigned short len)
{
    char cmdBuf[32];

    ESP8266_Clear();								//清空接收缓存
    sprintf(cmdBuf, "AT+CIPSEND\r\n");		//发送命令

    if(!ESP8266_SendCmd(cmdBuf, ">"))				//收到‘>’时可以发送数据
    {
        //printf("8.开始处于透传发送状态!\r\n");
        /*发送请求数据*/
        Usart_SendString(USART2, data, len);		//发送设备连接请求数据
    }
}

//==========================================================
//	函数名称:	ESP8266_GetIPD
//
//	函数功能:	copy天气数据到buff数组里面
//
//	返回参数:	平台返回的原始数据
//
//	说明:		copy天气数据到buff
//==========================================================

unsigned char *ESP8266_GetIPD_GET(unsigned short timeOut, u8 *buff) //这里我用了一个全局变量将esp8266buf储存到这个全局变量里面
{
    do
    {
        delay_ms(5);
    }
    while(timeOut--);

    strcpy((char*)buff, (char*)esp8266_buf);
    return buff;
}

//==========================================================
//	函数名称:	ESP8266_WaitRecive
//
//	函数功能:	等待接收完成
//
//	入口参数:	无
//
//	返回参数:	REV_OK-接收完成		REV_WAIT-接收超时未完成
//
//	说明:		循环调用检测是否接收完成
//==========================================================
_Bool ESP8266_WaitRecive(void)
{

    if(esp8266_cnt == 0) 							//如果接收计数为0 则说明没有处于接收数据中,所以直接跳出,结束函数
        return REV_WAIT;

    if(esp8266_cnt == esp8266_cntPre)				//如果上一次的值和这次相同,则说明接收完毕
    {
        esp8266_cnt = 0;							//清0接收计数

        return REV_OK;								//返回接收完成标志
    }

    esp8266_cntPre = esp8266_cnt;					//置为相同

    return REV_WAIT;								//返回接收未完成标志

}


//==========================================================
//	函数名称:	ESP8266_SendCmd
//
//	函数功能:	发送命令
//
//	入口参数:	cmd:命令
//				res:需要检查的返回指令
//
//	返回参数:	0-成功	1-失败
//
//	说明:
//==========================================================
_Bool ESP8266_SendCmd(char *cmd, char *res)
{

    unsigned char timeOut = 250;

    Usart_SendString(USART2, (unsigned char *)cmd, strlen((const char *)cmd));

    while(timeOut--)
    {
        if(ESP8266_WaitRecive() == REV_OK)							//如果收到数据
        {
            if(strstr((const char *)esp8266_buf, res) != NULL)		//如果检索到关键词
            {
                ESP8266_Clear();									//清空缓存

                return 0;
            }
        }

        delay_ms(10);
    }
    return 1;
}
## 最后

**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。**

**因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**

![img](https://img-blog.csdnimg.cn/img_convert/6105296745867ec824ec07da44066162.png)

![img](https://img-blog.csdnimg.cn/img_convert/4b0a305775df7918def1fb01cda38eac.jpeg)

![img](https://img-blog.csdnimg.cn/img_convert/b91b184ea5b3f04379c428076d8ec0d5.png)

 ![img](https://img-blog.csdnimg.cn/img_convert/f859b1f4c7091e6aff19aa139676e752.png)

![img](https://img-blog.csdnimg.cn/img_convert/c8920a24ca0cf31582dd8c125e830157.png)

![img](https://img-blog.csdnimg.cn/img_convert/55cfbbd055b7e4dc2812486f7df08a8b.png)

![](https://img-blog.csdnimg.cn/img_convert/ef6c61b289987a7ac3ee3181f049fe12.png)

 

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!**

[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618654289)

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**!!


,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。**

**因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**

[外链图片转存中...(img-Fbs0weBF-1715574849270)]

[外链图片转存中...(img-IZLwk3SL-1715574849271)]

[外链图片转存中...(img-SUfFZPbs-1715574849271)]

 [外链图片转存中...(img-ILuUkBVL-1715574849272)]

[外链图片转存中...(img-bNkzq2K1-1715574849272)]

[外链图片转存中...(img-1kyUP5Wb-1715574849273)]

[外链图片转存中...(img-h8u9gshj-1715574849273)]

 

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!**

[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618654289)

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**!!


  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值