STM32 Esp8266 獲取天氣時間
阿新 • • 發佈:2021-01-04
STM32 Esp8266 獲取天氣(筆記)
STM32通過串列埠傳送AT指令控制Esp8266
補充知識:
棧區(stack):由編譯器自動分配和釋放,存放函式的引數值、區域性變數的值等,其操作方式類似於資料結構中的棧。
堆區(heap):一般由程式設計師分配和釋放,若程式設計師不釋放,程式結束時可能由作業系統回收。分配方式類似於資料結構中的連結串列。
全域性區(靜態區)(static):全域性變數和靜態變數的儲存是放在一塊的,初始化的全域性變數和靜態變數在一塊區域,未初始化的全域性變數和未初始化的靜態變數在相鄰的另一塊區域。程式結束後由系統自動釋放。
程式程式碼區:存放函式體的二進位制程式碼。
注意:堆和棧,一般堆是由低地址往上(高地址)增長,棧是由高地址向下(低地址)增長。都是連續的,C語言不提供記憶體保護機制類似的功能,如果一直堆一直增長,棧一直申請,然後就會導致棧溢位,程式崩潰。
JSON是首先一種 資料結構,說白了就是對資料的描述,剛剛出現是為了取代XML,可惜並沒有,但是在作為配置檔案上,卻是很好,由於它小巧靈活,描述資料很好,所以在網路上進行資料傳輸更加方便。
請記住JSON對資料的描述形式,既然是形式,那麼它的資料形式是什麼樣的:
物件的描述是: {} 這個表示jsonobject(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估計要下學期開學