STM32与ESP8266物联网编程
小白能懂:嵌入式進階:RTOS嵌入式系統框架
第一章 嵌入式常用裸機編程框架
第二章 面向對象編程基礎
第三章 ESP8622物聯網基礎
第四章 STM32與ESP8266物聯網編程
文章目錄
- **小白能懂:嵌入式進階:RTOS嵌入式系統框架**
- 前言
- 一、復位、模式設置、WIFI連接,UDP連接
- 二、獲取IP
- 三、發送數據
- 1 按鍵設置
- 2 按鍵主函數發送
- 四、接收數據
- 總結
前言
學習韋東山老師的七天物聯網實戰及直播課相關內容,以其課程筆記為骨,記錄一下學習的過程,可能會加入一些自己的感想。
最后歡迎點贊、收藏與評論交流!
提示:本章主要是對上一章的框架進行編程
一、復位、模式設置、WIFI連接,UDP連接
在上一節的內容中我們得知物聯網的復位,模式設置、WIFI連接,創建UDP連接這四個功能的模式類似,都是STM32要向ESP發送數據然后接收返回數據,比較返回數據或者報文是不是正確,為此我們設計的功能函數如下所示:
//向ESP8266發送數據 uint8_t ESP8266_SendCommand(char *cmd, char *reply, uint16_t timeout) {//1.保存傳入的指令char buf[256] = {0};strcat(buf, cmd); //strcpy //2.處理AT指令(添加換行),因為ESP8622的AT指令要以換行為結束標志if (strstr(buf, "\r\n") == 0){strcat(buf, "\r\n");}//3.清理前面接收的bufUSART2_ClearBuf(); //4.發送數據USART2_Transmit((uint8_t *)buf, strlen(buf), 500);//5.接收數據memset(buf, 0, 256); //buf清空while(timeout != 0) //超時控制{if (USART2_Receive((uint8_t *)buf)) //接收數據{//檢查結果if (strstr(buf, reply)) {printf("%s Send ok!\r\n", cmd);//發送成功return 0;}else{timeout--;HAL_Delay(1);}} }printf("%s Send error!\r\n", cmd);//發送失敗return 1; }程序中的1、2、3和4部分主要是數據發送的內容,步驟5是設置了接收超時之后比較接收的數據或報文是否和預設的數據和報文是否相同,如果相同,則證明數據發送正確,若不同,則證明發送錯誤。
因此復位,模式設置、WIFI連接,創建UDP連接的功能可以通過以下函數完成。
ESP8266_SendCommand(“AT+RST”, “OK”, 500);
ESP8266_SendCommand(“AT+CWMODE=1”, “OK”, 500);
ESP8266_SendCommand(“AT+CWJAP=“NETGEAR”,“100ask.cq””, “OK”, 5000);
ESP8266_SendCommand(“AT+CIPSTART=“UDP”,“192.168.50.230”,9999,9999,2”, “OK”, 500);
二、獲取IP
獲取IP的功能和以上功能不一樣,因為獲取IP的函數返回的值我們不知道具體返回的值,不像上面那些功能知道返回的值為“OK”,因此我們需要設計一個新的函數將接收到的IP進行打印,如果接收錯誤,返回接收失敗。
//獲取ESP8266的IP uint8_t ESP8266_GetIP(void) {uint16_t timeout = 500;//1.準備發送的指令 AT+CIFSR,注意ESP8622的AT指令要以換行為結束標志char buf[256] = {0};strcat(buf, "AT+CIFSR\r\n");//2.清理前面接收的bufUSART2_ClearBuf(); //4.發送數據USART2_Transmit((uint8_t *)buf, strlen(buf), 500);//5.接收數據memset(buf, 0, 256); //buf清空while(timeout != 0) //超時控制{if (USART2_Receive((uint8_t *)buf)) //接收數據{//檢查結果if (strstr(buf, "OK")) {printf("%s", buf); //打印IPreturn 0;}else{timeout--;HAL_Delay(1);}} }printf("Get IP Failed! \r\n"); //獲取失敗return 1; }其函數架構與前面第一節架構類似,只不過在接收里面添加了一句輸出buf的內容。
三、發送數據
本節主要介紹stm32端給PC或者手機端發送數據的案例。
1 按鍵設置
發送數據通過按鍵來實現,當按鍵按下,就會發送一組指令。
首先設置案件標志位,為了減少全局變量的使用,在此我們定義了Key_GetFlag函數進行標志位的傳輸,具體流程如下所述:
2 按鍵主函數發送
在main函數中進行輪詢查詢,當按鍵按下(1 按鍵設置節中的標志位置位),就發送相應的數據。
<main.c>if (Key_GetFlag()) {ESP8266_Send_UDP("{\"data\":\"doorbell\",\"status\":\"1\"}");}發送的函數ESP8266_Send_UDP編寫如下所示:
<gpio.c>uint8_t ESP8266_Send_UDP(char *data) {//1.準備發送的指令 AT+CIPSEND=lenchar buf[256] = {0};uint8_t len = strlen(data);sprintf(buf, "AT+CIPSEND=%d\r\n", len); //把格式化(%d)的數據寫入字符串if (ESP8266_SendCommand(buf, "OK", 500) == 0) //發送指令,如果可以放松的話,執行下面語句{ESP8266_SendCommand(data, "SEND OK", 1000); //發送數據return 0;}return 1; }四、接收數據
本節主要介紹stm32端(ESP8622)接收PC或者手機端數據的實例。
ESP8622接收的數據格式如下所示:
本節主要介紹stm32端給PC或者手機端發送數據的案例。
在main函數中查詢接收的數據,然后進行解析工作。
<main.c>//收到UDP數據if (USART2_Receive(rx_data)) //如果接收到數據{//printf("%s\r\n", rx_data);if (strstr((char *)rx_data, "\"dev\":\"led\",\"status\":\"0\"")) {printf("led off\r\n");HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);USART2_ClearBuf(); memset(rx_data, 0, 200);}else if (strstr((char *)rx_data, "\"dev\":\"led\",\"status\":\"1\"")){printf("led on\r\n");HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);USART2_ClearBuf(); memset(rx_data, 0, 200); }}上面的流程是接收到數據進行分析;然后根據數據進行如果是該開燈的話執行else if,反之執行上面的if;然后清理一下usart2的buf;最后清理緩存區rx_data。
緩存區rx_data數據的來源是通過中斷來的,一次次進入中斷進行一次次的接收。
<usart.c>static uint8_t rx_data = 0; //接收的字符 static uint8_t rx_len = 0; //接收的長度 static uint8_t usart_rx_buf[200] = {0};//保存接收的數據//調用HAL庫接收函數,等待接收數據 void USART_StartRx(void) {HAL_UART_Receive_IT(&huart2, (uint8_t*)&rx_data, 1); }//USART中斷回調函數,保存接收的數據并啟動下一次接收 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {usart_rx_buf[rx_len%200]= rx_data;rx_len++;HAL_UART_Receive_IT(&huart2, (uint8_t*)&rx_data, 1); }//獲取接收的數據 uint8_t USART2_Receive(uint8_t *rx_data) {memcpy(rx_data, (uint8_t*)usart_rx_buf, rx_len);return rx_len; }總結
本文主要介紹了stm32與ESP8622進行連接的相關編程,屬于第三章的延續。
總結
以上是生活随笔為你收集整理的STM32与ESP8266物联网编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Latex设置指定区域的行距
- 下一篇: 什么是预付卡及预付卡发展前景