1. 程式人生 > 其它 >STM32 Esp8266 獲取天氣時間

STM32 Esp8266 獲取天氣時間

技術標籤:STM32esp8266

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估計要下學期開學