目录
前言
实现图片
一、串口编程的实现
二、发送AT指令
esp01s.c
esp01s.h
三、数据处理
1、初始化
2、cjson处理函数
3、核心控制代码
四、修改堆栈大小
前言
实现图片
前面讲解了使用AT指令获取天气与cjson的解析数据,本章综合将时间显示到屏幕
一、串口编程的实现
uint8_t rx_dat;
char rxdata[1000];
int rx_p = 0,rx_ppre = 0;
int fputc(int ch,FILE *f)
{//采用轮询方式发送1字节数据,超时时间设置为无限等待HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY);return ch;
}
int fgetc(FILE *f)
{uint8_t ch;// 采用轮询方式接收 1字节数据,超时时间设置为无限等待HAL_UART_Receive( &huart1,(uint8_t*)&ch,1, HAL_MAX_DELAY );return ch;
}// 串口中断接收数据
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if(huart->Instance == USART1){// if(rx_p >= sizeof(rxdata)) rx_p = 0; //防止串口被刷爆rxdata[rx_p ++] = rx_dat;HAL_UART_Receive_IT(&huart1,&rx_dat,1);}
}
二、发送AT指令
esp01s.c
#include "esp01s.h"
#include "usart.h"uint8_t rx_dat;
char rxdata[1000];
int rx_p = 0,rx_ppre = 0;unsigned char Time_buff[1000];int fputc(int ch,FILE *f)
{//采用轮询方式发送1字节数据,超时时间设置为无限等待HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY);return ch;
}
int fgetc(FILE *f)
{uint8_t ch;// 采用轮询方式接收 1字节数据,超时时间设置为无限等待HAL_UART_Receive( &huart1,(uint8_t*)&ch,1, HAL_MAX_DELAY );return ch;
}// 串口中断接收数据
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if(huart->Instance == USART1){// if(rx_p >= sizeof(rxdata)) rx_p = 0; //防止串口被刷爆rxdata[rx_p ++] = rx_dat;HAL_UART_Receive_IT(&huart1,&rx_dat,1);}
}//清空缓存
void esp01s_clear(void)
{memset(rxdata,0,sizeof(rxdata));rx_p = 0;
}//esp01s等待接收完成 0成功 1失败
int esp01s_waitrecive(void)
{if(rx_p == 0) //如果接收计数为0 则说明没有处于接收数据中,所以直接跳出,结束函数return 1;if(rx_p == rx_ppre) //如果上一次的值和这次相同,则说明接收完毕{rx_p = 0; //清0接收计数return 0; //返回接收完成标志}rx_ppre = rx_p; //置为相同return 1; //返回接收未完成标志
}//esp01s发送指令 0成功 1失败
int esp01s_sendcmd(char *cmd,char *res)
{unsigned char timeout = 250;printf(cmd);while(timeout --){if(esp01s_waitrecive() == 0) //如果收到数据{if(strstr(rxdata,res) != NULL) //如果检索到关键词{esp01s_clear();return 0;}}HAL_Delay(10);}return 1;
}//esp01s发送数据
void esp01s_senddata(char *data)
{esp01s_clear(); //清空接收缓存if(!esp01s_sendcmd("AT+CIPSEND\r\n",">")) //收到‘>’时可以发送数据//printf(data);{/*发送请求数据*/printf(data); //发送设备连接请求数据}}unsigned char *ESP8266_GetIPD_GET(unsigned short timeOut, uint8_t *buff) //这里我用了一个全局变量将esp8266buf储存到这个全局变量里面
{do{HAL_Delay(5);}while(timeOut--);strcpy((char*)buff, (char*)rxdata);return buff;
}
esp01s.h
#ifndef __ESP01S_H
#define __ESP01S_H#include "main.h"
#include "string.h"
#include "stdio.h"extern uint8_t rx_dat;
extern char rxdata[1000];
extern int rx_p,rx_ppre;
extern unsigned char Time_buff[1000];void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
void esp01s_clear(void);
int esp01s_waitrecive(void);
int esp01s_sendcmd(char *cmd,char *res);
void esp01s_senddata(char *data);
unsigned char *ESP8266_GetIPD_GET(unsigned short timeOut, uint8_t *buff);#endif
三、数据处理
1、初始化
esp01s_clear();while(esp01s_sendcmd("+++",""));while(esp01s_sendcmd("AT\r\n", "OK"));while(esp01s_sendcmd("AT+RST\r\n", "OK"));while(esp01s_sendcmd("AT+CWMODE=1\r\n", "OK"));while(esp01s_sendcmd("AT+CIPMUX=0\r\n", "OK"));while(esp01s_sendcmd("AT+CWJAP=\"meng\",\"20010131\"\r\n", "WIFI GOT IP"));while(esp01s_sendcmd("AT+CIPSTART=\"TCP\",\"api.seniverse.com\",80\r\n","CONNECT"));// while(esp01s_sendcmd("AT+CIPSTART=\"TCP\",\"api.pinduoduo.com\",80\r\n","CONNECT"));while(esp01s_sendcmd("AT+CIPMODE=1\r\n", "OK"));HAL_GPIO_WritePin(led_blue_GPIO_Port,led_blue_Pin,GPIO_PIN_RESET);
2、cjson处理函数
int test2_jiexi()
{char *data;cJSON *json=NULL,*arrayItem=NULL,*object=NULL,*subobject=NULL,*nowobject=NULL,*mingobject=NULL,*houobject=NULL,*nowtext=NULL,*nowhigh=NULL,*nowlow=NULL,*mingtext=NULL,*minghigh=NULL,*minglow=NULL,*houtext=NULL,*houhigh=NULL,*houlow=NULL;cJSON *nowdate = NULL,*mingdate = NULL,*houdate = NULL;data = (char*)te;json = cJSON_Parse(data); //解析数据包// if(json == NULL) //解析失败// {// sprintf(text,"Error:%s",cJSON_GetErrorPtr());// lcd_showstr(0,0,(uint8 *)text,WHITE);// return 1;// }if(json){ HAL_GPIO_WritePin(led_red_GPIO_Port,led_red_Pin,GPIO_PIN_RESET);if((arrayItem = cJSON_GetObjectItem(json,"results")) != NULL) //匹配字符串results,获取数组内容{HAL_GPIO_WritePin(led_red_GPIO_Port,led_red_Pin,GPIO_PIN_RESET);int size = cJSON_GetArraySize(arrayItem);// sprintf(text,"size is %d",size);// lcd_showstr(0,0,(uint8 *)text,WHITE);if((object = cJSON_GetArrayItem(arrayItem,0)) != NULL) //results第0位{//if((subobject = cJSON_GetObjectItem(object,"location")) != NULL); //位置信息if((subobject = cJSON_GetObjectItem(object,"daily")) != NULL) //天气信息{int tianqi_size = cJSON_GetArraySize(subobject);// sprintf(text,"size is %d",tianqi_size);// lcd_showstr(0,1,(uint8 *)text,WHITE);if((nowobject = cJSON_GetArrayItem(subobject,0)) != NULL) //今天{nowtext = cJSON_GetObjectItem(nowobject,"text_day"); //天气状况nowhigh = cJSON_GetObjectItem(nowobject,"high"); //高温nowlow = cJSON_GetObjectItem(nowobject,"low"); //低温nowdate = cJSON_GetObjectItem(nowobject,"date"); //日期sprintf(text,"%s:",nowdate->valuestring);lcd_showstr(0,0,(uint8 *)text,WHITE);sprintf(text,"%s %sC/%sC",nowtext->valuestring,nowhigh->valuestring,nowlow->valuestring);lcd_showstr(20,1,(uint8 *)text,WHITE);}if((mingobject = cJSON_GetArrayItem(subobject,1)) != NULL) //明天{mingtext = cJSON_GetObjectItem(mingobject,"text_day"); //天气状况minghigh = cJSON_GetObjectItem(mingobject,"high"); //高温minglow = cJSON_GetObjectItem(mingobject,"low"); //低温mingdate = cJSON_GetObjectItem(mingobject,"date"); //日期sprintf(text,"%s:",mingdate->valuestring);lcd_showstr(0,3,(uint8 *)text,WHITE);sprintf(text,"%s %sC/%sC",mingtext->valuestring,minghigh->valuestring,minglow->valuestring);lcd_showstr(20,4,(uint8 *)text,WHITE);}if((houobject = cJSON_GetArrayItem(subobject,2)) != NULL) //后天{houtext = cJSON_GetObjectItem(houobject,"text_day"); //天气状况houhigh = cJSON_GetObjectItem(houobject,"high"); //高温houlow = cJSON_GetObjectItem(houobject,"low"); //低温houdate = cJSON_GetObjectItem(houobject,"date"); //日期sprintf(text,"%s:",houdate->valuestring);lcd_showstr(0,6,(uint8 *)text,WHITE);sprintf(text,"%s %sC/%sC",houtext->valuestring,houhigh->valuestring,houlow->valuestring);lcd_showstr(20,7,(uint8 *)text,WHITE);}}//if((subobject = cJSON_GetObjectItem(object,"last_update")) != NULL); //更新信息}}} cJSON_Delete(json);return 0;
}
3、核心控制代码
u8g2_ClearBuffer(&u8g2);if(key[0].single_flag == 1){key[0].single_flag = 0;// esp01s_senddata("GET http://api.pinduoduo.com/api/server/_stm\r\n");esp01s_senddata("GET https://api.seniverse.com/v3/weather/daily.json?key=S6H95GCCwULqmbSE8&location=weifang&language=en&unit=c&start=-1&days=4\r\n");te = ESP8266_GetIPD_GET(200, Time_buff); //将串口数据取出来esp01s_clear();//清除缓存数据HAL_Delay(500);while(esp01s_sendcmd("+++", "")); /*退出透传模式,发送两次*/HAL_GPIO_WritePin(led_blue_GPIO_Port,led_blue_Pin,GPIO_PIN_SET);}// int num1 = strlen((char*) te);// sprintf(text,"%d",num1);// lcd_showstr(0,7,(uint8 *)text,WHITE);test2_jiexi();u8g2_SendBuffer(&u8g2);// lcd_clear(BLACK);
四、修改堆栈大小
在json处理长字符串时,需要修改堆栈大小(卡了好长时间)
将 Stack_Size与Heap_Size改大,程序正常运行
有需要的可以联系我,给工程代码