STM32 Esp8266 获取天气(笔记)
STM32通过串口发送AT指令控制Esp8266
补充知识:
栈区(stack):由编译器自动分配和释放,存放函数的参数值、局部变量的值等,其操作方式类似于数据结构中的栈。
堆区(heap):一般由程序员分配和释放,若程序员不释放,程序结束时可能由操作系统回收。分配方式类似于数据结构中的链表。
全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统自动释放。
文字常量区:常量字符串就是存放在这里的。
程序代码区:存放函数体的二进制代码。
注意:堆和栈,一般堆是由低地址往上(高地址)增长,栈是由高地址向下(低地址)增长。都是连续的,C语言不提供内存保护机制类似的功能,如果一直堆一直增长,栈一直申请,然后就会导致栈溢出,程序崩溃。
JSON是首先一种 数据结构,说白了就是对数据的描述,刚刚出现是为了取代XML,可惜并没有,但是在作为配置文件上,却是很好,由于它小巧灵活,描述数据很好,所以在网络上进行数据传输更加方便。
请记住JSON对数据的描述形式,既然是形式,那么它的数据形式是什么样的:
对象的描述是: {} 这个表示jsonobject(json对象)
数组的描述是: [] 表示jsonarray(json数组)
属性或值的描述是: “”
连接之间的描述是: :
JSON 语法是 JavaScript 对象表示法语法的子集。
- 数据在名称/值对中:如 “firstName” : “John”
- 数据由逗号分隔
- 花括号保存对象
- 方括号保存数组
组成JSON的值可以为以下几种:
- 数字(整数或浮点数)
- 字符串(在双引号中)
- 逻辑值(true 或 false)
- 数组(在方括号中)
- 对象(在花括号中)
- null
例如
{“results”:[{“location”:{“id”:“WBXXFKE4F”,“name”:“Beijing”,“country”:“CN”,“path”:“Beijing,Beijing,China”,“timezone”:“Asia/Shanghai”,“timezone_offset”:"+08:00"},“now”:{“text”:“Sunny”,“code”:“0”,“temperature”:"-1"},“last_update”:“2021-01-02T13:20:00+08:00”}]}
(都网上找的有啥问题联系我删除)
#include "esp8266.h"
extern UART_HandleTypeDef huart4;
extern UART_HandleTypeDef huart1;
extern char ReBuffer[1024];
extern char CopyBuffer[1024];
uint16_t BufferNum = 0;
char Abuffer = '0';
uint8_t Esp_Cmd(UART_HandleTypeDef *huart,uint8_t *Buffer,uint8_t size)
{
uint8_t state = 0;
uint8_t i = 0;
state = HAL_UART_Transmit(huart,Buffer,size,0xffff);
for(i=0;i<3;i++){
switch(state){
case HAL_TIMEOUT:
case HAL_ERROR:
case HAL_BUSY:state = HAL_UART_Transmit(huart,Buffer,size,0xffff);break;
case HAL_OK: return 1;
}
}
return 0;
}
/*************************************
HAL_Delay等待接受数据通过串口助手观察现象
让stm32延迟的这种办法不好后面会改下
关闭uart4接受中断防止接收奇怪数据
通过esp是否返回ok判断指令是否成功
*************************************/
uint8_t Esp_Cmd_Back(UART_HandleTypeDef *huart,uint8_t *Buffer,uint8_t size,uint16_t time)
{
HAL_UART_Receive_IT(huart,(uint8_t *)&Abuffer,1);
if(Esp_Cmd(huart,Buffer,size) ==1){
HAL_Delay (time);
HAL_UART_Transmit(&huart1,(uint8_t *)ReBuffer,BufferNum,0xffff);
while(HAL_UART_GetState (&huart1) == HAL_UART_STATE_BUSY_TX)
;
__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
__HAL_UART_DISABLE_IT(huart, UART_IT_PE);
__HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
huart->RxState = HAL_UART_STATE_READY;
if(((strrchr(ReBuffer,'O') != NULL) && (*(strrchr(ReBuffer,'O')+1) == 'K')) != 1){
memset(ReBuffer,0,sizeof(ReBuffer));
BufferNum = 0;
return 0;
} else {
memset(ReBuffer,0,sizeof(ReBuffer));
BufferNum = 0;
return 1;
}
}
return 0;
}
/*************
和Esp_Cmd_Back差不多主要是复制重要
数据以便后续操作
*************/
uint8_t Esp_Get_Data(UART_HandleTypeDef *huart,uint8_t *Buffer,uint8_t size,uint16_t time)
{
HAL_UART_Receive_IT(huart,(uint8_t *)&Abuffer,1);
if(Esp_Cmd(huart,Buffer,size) == 1){
HAL_Delay(time);
strcpy(CopyBuffer,ReBuffer);
HAL_UART_Transmit(&huart1,(uint8_t *)CopyBuffer,BufferNum,0xffff);
while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX)
;
__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
__HAL_UART_DISABLE_IT(huart, UART_IT_PE);
__HAL_UART_DISABLE_IT(huart, UART_IT_ERR);//¹Ø±ÕÖжÏ
huart->RxState = HAL_UART_STATE_READY;
memset(ReBuffer,0,sizeof(ReBuffer));
BufferNum = 0;
return 1;
}
return 0;
}
/********************************
wife配置
上电esp要自动连wife导致卡死怀疑是数组溢出不过不应该会出现跑飞数组还是够大的
AT+CWAUTOCONN=0关闭自动连接wife
*********************************/
uint8_t Esp_Init(UART_HandleTypeDef *huart)
{
uint8_t i;
for(i=0;i<3;i++){
if(Esp_Cmd_Back(huart,(uint8_t *)"AT\r\n",sizeof("AT\r\n")-1,1000) == 1){
if(Esp_Cmd_Back(huart,(uint8_t *)"AT+CWAUTOCONN=0\r\n",sizeof("AT+CWAUTOCONN=0\r\n")-1,1000) == 1){
if(Esp_Cmd_Back(huart,(uint8_t *)"AT+CWMODE=1\r\n",sizeof("AT+CWMODE=1\r\n")-1,1000) == 1){
if(Esp_Cmd_Back(huart,(uint8_t *)"AT+RST\r\n",sizeof("AT+RST\r\n")-1,1000) == 1){
if(Esp_Cmd_Back(huart,(uint8_t *)"AT+CWJAP=\"555\",\"12345689\"\r\n",sizeof("AT+CWJAP=\"555\",\"12345689\"\r\n")-1,15000) == 1){
if(Esp_Cmd_Back(huart,(uint8_t *)"AT+CIFSR\r\n",sizeof("AT+CIFSR\r\n")-1,1000) == 1){
return 1;
}
}
}
}
}
}
}
return 0;
}
/************************
心知天气 透传最后关闭透传
密钥我改了可自己去官网免费的
等待时间可修改除了连接wife的时候等待时间比较长
************************/
uint8_t Esp_Weather(UART_HandleTypeDef *huart)
{
if(Esp_Cmd_Back(huart,(uint8_t *)"AT+CIPMODE=1\r\n",sizeof("AT+CIPMODE=1\r\n")-1,1000) == 1){
if(Esp_Cmd_Back(huart,(uint8_t *)"AT+CIPSTART=\"TCP\",\"api.seniverse.com\",80\r\n",sizeof("AT+CIPSTART=\"TCP\",\"api.seniverse.com\",80\r\n")-1,1000) == 1){
if(Esp_Cmd_Back(huart,(uint8_t *)"AT+CIPSEND\r\n",sizeof("AT+CIPSEND=1\r\n")-1,1000) == 1){
if(Esp_Get_Data(huart,(uint8_t *)"GET https://api.seniverse.com/v3/weather/now.json?key=SWMpeKFOuUVOXI5nL&location=beijing&language=en&unit=c\r\n",
sizeof("GET https://api.seniverse.com/v3/weather/now.json?key=peKFOuUVOXI5nL&location=beijing&language=en&unit=c\r\n")-1,5000) == 1){
return 1;
}
}
}
}
return 0;
}
/***************
返回命令模式
**************/
uint8_t Esp_Quit_Tcp(UART_HandleTypeDef *huart)
{
uint8_t i;
for(i=1;i<3;i++){
Esp_Cmd_Back(huart,(uint8_t *)"+++",sizeof("+++")-1,1000);
Esp_Cmd_Back(huart,(uint8_t *)"+++",sizeof("+++")-1,1000);
if(Esp_Cmd_Back(huart,(uint8_t *)"AT\r\n",sizeof("AT\r\n")-1,1000) == 1)
break;
else
return 0;
}
Esp_Cmd_Back(huart,(uint8_t *)"AT+CIPMODE=0\r\n",sizeof("AT+CIPMODE=0\r\n")-1,1000);
return 1;
}
/******************
研究了几个小时的json解析出来了
有点类似树可能有点小问题吧
可能要去启动文件吧堆改大一点
*****************/
void Esp_Cjson(char * p)
{
cJSON *Root,*Array,*Location,*data,*Last_update;
//uint8_t num = 0;
char *Data = 0;
Root = cJSON_Parse(p);
if(Root != NULL){
Array = cJSON_GetObjectItem(Root,"results");
if(Array != NULL){
//num = cJSON_GetArraySize(Array);
//HAL_UART_Transmit(&huart1,(uint8_t *)&num,1,0xffff);
Location = Array->child;
Last_update = Location+1;
data = cJSON_GetObjectItem(Location,"location");
Data = cJSON_GetObjectItem(data,"id")->valuestring;
HAL_UART_Transmit(&huart1,(uint8_t *)Data,strlen(Data)+1,0xffff);
while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX)
;
memset(Data,0,strlen(Data)+1);
Data = cJSON_GetObjectItem(Last_update,"last_update")->valuestring;
HAL_UART_Transmit(&huart1,(uint8_t *)Data,strlen(Data)+1,0xffff);
while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX)
;
}
}
cJSON_Delete(Root);
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(BufferNum>1023){
BufferNum = 0;
memset(ReBuffer,0,sizeof(ReBuffer));
} else{
ReBuffer[BufferNum] = Abuffer;
BufferNum++;
}
HAL_UART_Receive_IT(&huart4,(uint8_t *)&Abuffer,1);
}
可能时间换一个api这个心知天气的时间好像不准
从标准库转hal库第一次写
敲代码没多久风格可能比较难以描述
后面可能会从硬件到软件做一个wife天气闹钟吧
毕竟刚开始学AD估计要下学期开学