一、WIFI模塊介紹
1.?ESP12-F模組介紹
1.1 簡介
ESP12-F模組(安信可(Ai-Thinker)ESP8266系列模組)是一款基于樂鑫(Espressif)公司ESP8266芯片的Wi-Fi無線通信模塊,廣泛應用于物聯網(IoT)領域。它體積小巧,集成度高,內置Wi-Fi功能和32位處理器,支持802.11 b/g/n無線標準。ESP12-F模組內置4MB Flash存儲,擁有豐富的GPIO(通用輸入輸出)、UART、SPI、I2C、PWM、ADC等接口,方便與各種傳感器和外設連接。它既可以通過AT指令作為Wi-Fi串口透傳模塊使用,也可以燒錄自定義固件(如NodeMCU、MicroPython或原生SDK)實現復雜的控制和聯網功能。ESP12-F模組功耗低,支持深度休眠,非常適合智能家居、遠程控制、無線傳感器、數據采集等應用場景。使用時需要注意其所有引腳電平為3.3V,不能直接接5V電源或信號,否則可能損壞芯片。
1.2 什么是固件?
ESP12-F模組本質就是集成好的一個小板子,固件就是代碼存儲的地方,這個模組能做那么多事,就是按照固件里的程序執行任務,是開發這個模組的人員提前燒錄進去的。
1.3 安信可 ESP8266 系列模組
https://docs.ai-thinker.com/esp8266
2. 原理分析
2.1 原理圖分析
三個開放引腳:
(1) GPIO0:控制WIFI模式,GPIO0為低電平是下載模式,高電平為運行模式
運行模式:此時串口為正常的通信功能
下載模式:此時串口為下載固件的功能
注意:一般買WiFi模塊的時候,一定要了解是否已經下載固件到WIFI模塊內,如果有一般都是沒有問題可以直接使用的(功能沒有問題)。
(2) 22號引腳 TXD為WIFI模組的串口發送引腳
可以切換我們的WiFi模組串口發送的消息是直接通過底板typec口和電腦通信還是發送給單片機串口通信
TXD(Transmit Data)是ESP-12F WiFi模組的串口發送端,用于將模塊內部處理后的數據通過串口發送到外部設備。在實際應用中,TXD的信號可以通過底板的電路切換,選擇發送到單片機的串口,實現與主控MCU的數據交互,也可以通過Type-C轉USB串口發送到電腦,便于調試、監控或固件下載。這樣設計的好處是,開發者可以根據需要靈活選擇通信對象:在正常運行模式下,TXD用于與單片機進行數據通信,實現物聯網數據上傳、遠程控制等功能;在調試或下載模式下,TXD則用于與電腦通信,輸出調試信息或配合下載工具燒錄固件。需要注意的是,TXD輸出的電平為3.3V,外部設備應與之匹配,避免電平不兼容導致通信異常或損壞模塊。通過合理切換TXD的連接對象,可以大大提升WiFi模組的開發效率和使用靈活性。
(3) 21號引腳 RXD為WIFI模組的串口接收引腳
RXD(Receive?Data)是ESP-12F?WiFi模組的串口接收端,用于接收外部設備(如單片機或電腦)通過串口發送過來的數據。在實際應用中,RXD可以通過底板的電路切換,實現與單片機串口或通過Type-C轉USB串口與電腦通信。這樣,WiFi模組既可以接收來自單片機的數據,實現本地控制和數據交互,也可以在調試或下載固件時接收來自電腦的指令和數據。需要注意的是,RXD引腳的電平為3.3V,不能直接接收5V電平信號,否則可能損壞模塊。實際使用時,確保信號線連接正確,避免串口信號沖突,保證數據通信的可靠性和安全性。
總結:
- GPIO0控制啟動模式,低電平為下載模式,高電平為運行模式;
- TXD(22腳)為串口發送,RXD(21腳)為串口接收;
- 運行模式下串口用于數據通信,下載模式下串口用于固件燒錄;
- 原理圖設計保證了模式切換和串口功能的靈活性與可靠性。
2.2 WiFi模塊通過串口通信的兩種方式(硬件連線):
都是我從原理圖中找出來相關元器件進行連接,這是一種很好的培養思維的方式,多去嘗試一下。
(1) WiFi模塊串口直接和電腦USB口相連
1. Wi-Fi無線模塊(ESP-12F)部分
ESP-12F模塊的TXD(發送)、RXD(接收)等引腳通過跳線和開關與外部電路相連。通過開關可以選擇WiFi模塊的串口信號是與單片機通信還是與電腦通信,實現模式切換。GPIO0等引腳用于控制模塊的啟動模式(運行/下載)。
2. 協議轉換芯片(CH340E)部分
CH340E芯片用于將USB信號轉換為串口信號,實現電腦與WiFi模塊之間的串口通信。這樣,WiFi模塊既可以和單片機通信,也可以通過CH340E與電腦直接通信,便于調試和固件下載。
3. Type-C接口部分
Type-C接口(J4)用于與電腦進行物理連接,提供數據通信和電源。通過Type-C線纜,電腦可以直接與電路板上的CH340E芯片通信,進而與WiFi模塊進行數據交互。
(2) WiFi模塊串口和單片機串口相連
1. 單片機引腳區:單片機(如STM32)通過串口引腳(如PA9、PA10或PB10、PB11等)與核心板排針接口(J2)連接,信號經過排針擴展,便于模塊化和后續維護。
2. 核心板排針接口(J2):核心板的排針接口將單片機的串口信號引出,通過排線與底板排針接口(J5)相連,實現信號的延伸和分配。
3. 底板排針接口(J5):底板排針接口接收來自核心板的信號,并將其分配到底板上的各個功能模塊,包括Wi-Fi無線模塊(ESP-12F)。
4. Wi-Fi無線模塊(ESP-12F):ESP-12F的TXD(發送)和RXD(接收)引腳分別與底板排針的UART3_RX和UART3_TX相連,實現與單片機的串口通信。同時,ESP-12F的GPIO0引腳通過電阻和插針與外部電路連接,用于切換運行模式和下載模式。
5. USB轉串口接口:底板上還設計了USB轉串口電路,可以通過Type-C接口將Wi-Fi模塊的串口信號與電腦連接,方便調試和固件下載。
6. 電源和地線:各模塊的3.3V電源和GND地線均已連接,保證電路正常供電和信號參考一致。
3.ESP8266的AT指令
3.1 AT指令集,詳細可見安信可官網
https://docs.espressif.com/projects/esp-at/zh_CN/latest/esp32/AT_Command_Set/index.html
3.2 基礎指令集大全:
官網內詳細指令集合,不是所有指令都可以使用,不同的WiFi模組可使用的不同。
3.3 ESP12-F模組連接網絡流程:
準備工作:
按照上面把三個按鍵撥到TXD和RXD模式上,連接WiFi模組所在的板子的typeC口到電腦上,一根線就可以,因為我們目前還不需要進行燒錄,先熟悉一下AT指令。
可以打開一個網絡調試助手,設置好IP和端口號,設置為服務器server,準備后面連接發送數據
(1) 復位
AT+RST
這個指令就是復位指令,也可以通過按板子上的reset復位鍵進行復位,復位后會斷開之前的連接,相當于重啟。有亂碼是正常的。
(2) 設置WiFi模式
查詢/設置 Wi-Fi 模式 (Station/SoftAP/Station+SoftAP)
- 0: 無 Wi-Fi 模式,并且關閉 Wi-Fi RF
- 1: Station 模式---------可以連接其他熱點
- 2: SoftAP 模式---------變身成為一個路由器,可以發射wifi信號成為一個熱點
- 3: SoftAP+Station------模式 混合模式
這里我們要聯網,所以選擇模式1,連接熱點。
(3) 連接WiFi熱點
AT+CWJAP="熱點名字","熱點密碼"
為了保險起見,此處設置的熱點明不要出現比較另類的字符,盡量為純數字或者字母組合。連接錯誤會回復的錯誤碼:回復錯誤碼1:連接超時回復錯誤碼2:密碼錯誤回復錯誤碼3:找不到該AP回復錯誤碼4:連接失敗



(4) 連接服務器
此時需要打開一個同網絡下的服務器,可以是虛擬機的用代碼寫的服務器或者在Windows上打開一個服務器模擬器
1. 網絡架構理解
當你使用電腦開熱點給WiFi模組提供網絡時,你的電腦實際上扮演了路由器的角色:
- 電腦 = 路由器(提供網絡服務)
- WiFi模組 = 客戶端設備(連接到電腦熱點)
2.?IP地址的區分
錯誤的做法:查看電腦連接公共網絡的IP地址
- 使用?ipconfig?查看的是電腦連接外網的IP
- 這個IP是電腦作為客戶端獲取的,不是路由器IP
正確的做法:查看電腦熱點網絡的IP地址
- 需要在網絡調試助手中查看熱點網絡的主機IP
- 這個IP才是WiFi模組能夠訪問的地址
3. 網絡層次:
公共網絡 ←→ 電腦(路由器) ←→ WiFi模組
? ? ? ? 外網IP ? ? ? ? ? ? 熱點IP


(5) 發送數據
AT+CIPSEND=5 ????????//發送五個字節給服務器
這種方式只能實現單次固定長度數據的發送
輸入后會出現箭頭,表示等待串口向服務器發送五個字節的數據。
發送五個字節數據:
服務器成功接收到數據。
(6)總結
通信數據走向:
3.4 透傳模式設置
之前的發送很別扭,每次都要提前發送指令告訴WiFi模塊準備發送數據,還有長度限制,十分不友好,有什么辦法解決嗎?有的兄弟有的!
(1) 什么是透傳模式
簡介:
透傳模式(Transparent Transmission)是一種數據傳輸方式,設備或系統在通信過程中不對數據內容進行解析或處理,僅作為通道將原始數據完整、無修改地傳遞給目標端。常見于串口通信、網絡協議、物聯網設備等場景。
也就是ESP8266作為一個搬運共,不去辨別串口發送過來的數據是什么,只是無腦的發送給服務器。
(2) 設置透傳
1.設置透傳模式:
2.使能透傳發送:
AT+CIPSEND
連續發送數據:
想退出透傳模式可以發送"+++",就會退出透傳模式:
4. 使用單片機控制WiFi模塊
4.1 思路梳理
核心設備:
STM32 MCU:主控制器
ESP8266模塊:通過 USART1 連接 STM32(自帶固件程序)
PC串口調試助手:通過 UART5 連接 STM32(Type-C直連核心板)
關鍵開關設置:
S2/S3:撥向?MCU方向(連接ESP8266與STM32)
S4:撥到?運行模式(使能ESP8266正常工作)
Type-C:插入核心板(供電+調試通信)
整體流程總結:
1. PC通過串口調試助手(UART5)發送指令給STM32。
2. STM32通過空閑中斷接收完整指令,解析指令。
3. STM32通過USART1向ESP8266發送相應的AT指令或數據。
4. ESP8266執行操作(如連接服務器、發送數據等)。
5. ESP8266將服務器返回的數據通過USART1傳給STM32。
6. STM32將結果通過UART5格式化輸出到PC串口調試助手。
4.2??cubeMX 配置
4.3 代碼編寫
1. 向uart.c添加驅動函數
(1) 兩個串口格式化輸出函數:
static char *itoa(int value, char *string, int radix ) //把一整數轉換為字符串。
{int i, d;int flag = 0; char *ptr = string;/* This implementation only works for decimal numbers. */if (radix != 10){*ptr = 0;return string;}if (!value){*ptr++ = 0x30;*ptr = 0;return string;}/* if this is a negative value insert the minus sign. */if (value < 0){*ptr++ = '-';/* Make the value positive. */value *= -1;}for (i = 10000; i > 0; i /= 10){d = value / i;if (d || flag){*ptr++ = (char)(d + 0x30);value -= (d * i);flag = 1;}}/* Null terminate the string. */*ptr = 0;return string;
} /* NCL_Itoa */
void USART_printf(UART_HandleTypeDef * USARTx, char * Data, ... )
{const char *s;int d; char buf[16];char singleBuff[1];va_list ap;va_start(ap, Data);while ( * Data != 0 ) // 判斷數據是否到達結束符{ if ( * Data == 0x5c ) //'\'{ switch ( *++Data ){case 'r': //回車符singleBuff[0] = 0x0d; __HAL_UART_CLEAR_FLAG(USARTx, UART_CLEAR_TCF); HAL_UART_Transmit(USARTx, (void*)singleBuff, 1, 1);//阻塞式發送數據Data ++;break;case 'n': //換行符singleBuff[0] = 0x0a; __HAL_UART_CLEAR_FLAG(USARTx, UART_CLEAR_TCF);/* Clear the TC flag in the ICR register */HAL_UART_Transmit(USARTx, (void*)singleBuff, 1, 1);//阻塞式發送數據Data ++;break;default:Data ++;break;} }else if ( * Data == '%'){ switch ( *++Data ){ case 's': //字符串s = va_arg(ap, const char *);for ( ; *s; s++) {singleBuff[0] = *s; HAL_UART_Transmit(USARTx, (void*)singleBuff, 1, 1);//阻塞式發送數據while(__HAL_UART_GET_FLAG(USARTx, UART_FLAG_TXE) == RESET);}Data++;break;case 'd': d = va_arg(ap, int);itoa(d, buf, 10);for (s = buf; *s; s++) {singleBuff[0] = *s; HAL_UART_Transmit(USARTx, (void*)singleBuff, 1, 1);//阻塞式發送數據while(__HAL_UART_GET_FLAG(USARTx, UART_FLAG_TXE) == RESET);}Data++;break;default:Data++;break;} }else{singleBuff[0] = *Data++; __HAL_UART_CLEAR_FLAG(USARTx, UART_CLEAR_TCF);/* Clear the TC flag in the ICR register */HAL_UART_Transmit(USARTx, (void*)singleBuff, 1, 1);//阻塞式發送數據} while (__HAL_UART_GET_FLAG(USARTx, UART_FLAG_TXE) == RESET);}
}
(3) 把頭文件加入uart.c文件中,因為上面兩個函數用到這些庫
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
(4) 然后在uart.h文件中加上對兩個函數的聲明,保證導入.h文件主函數可以正常使用,后面的wifi驅動文件也會用到:
static char *itoa(int value, char *string, int radix );
void USART_printf(UART_HandleTypeDef * USARTx, char * Data, ... );
?2. 添加WiFi驅動文件
(1) 下面是ESP8266的WiFi驅動文件,導入項目后,就可以使用內置狀態機函數實現單片機代替串口發送AT指令給WiFi模塊,讓WiFi模塊進行聯網和通信。
wifi.c:#include "wifi.h"int connect_flag = 0; // 是否連接成功的標志 int tt_flag = 0; // 是否有網絡發過來的透傳數據標志char WIFI_Config0(int time) // 找到ready 返回 沒有找到返回1 {memset(WiFi_RX_BUF, 0, 1024);WiFi_RxCounter = 0;while (time--){HAL_Delay(100);if (strstr((char *)WiFi_RX_BUF, "ready")){break;}// u1_USART ("WIFI_Config0:=%s",WiFi_RX_BUF);}if (time > 0)return 0;elsereturn 1; }char WIFI_Config(int time, char *cmd, char *response) // 等待時間 發送內容 判斷返回的內容 {memset(WiFi_RX_BUF, 0, 1024);WiFi_RxCounter = 0;ESP8266_USART("%s\r\n", cmd);while (time--){HAL_Delay(100);if (strstr((char *)WiFi_RX_BUF, response)){break;}// u1_USART("%d ", time);}if (time > 0)return 0;elsereturn 1; }char WIFI_Router(int time) // 配置WIFI名和密碼 {memset(WiFi_RX_BUF, 0, 1024);WiFi_RxCounter = 0;// ESP8266_USART("AT+CIPMUX=0");// HAL_Delay(100);ESP8266_USART("AT+CWJAP=\"%s\",\"%s\"\r\n", ID, PASSWORD);while (time--){HAL_Delay(1000);if (strstr((char *)WiFi_RX_BUF, "OK")){break;}u1_USART("連接路由倒計時: %d\r\n ", time);}if (time > 0)return 0;elsereturn 1; }char WIFI_ConnectTCP(int time) // 配置TCP {memset(WiFi_RX_BUF, 0, 1024);WiFi_RxCounter = 0;ESP8266_USART("AT+CIPSTART=\"TCP\",\"%s\",%d\r\n", ServerIP, ServerPort);while (time--){HAL_Delay(100);if (strstr((char *)WiFi_RX_BUF, "OK")){break;}u1_USART("正在建立TCP連接 :%d ", time);}if (time > 0)return 0;elsereturn 1; }enum WIFI_STATE {WIFI_READY = 0,WIFI_CONFIG1,WIFI_ROUTER,WIFI_CONFIG2, //進入透傳模式WIFI_CONNECT, //連接服務器WIFI_CONFIG3,WIFI_COMPLETE //連接完成 };#define WAIT_TIME 1000void WIFI_Connect()//狀態機 {int state = WIFI_READY; //默認等待復位while (1){if(state == WIFI_COMPLETE){u1_USART("連接服務器完成并開啟透傳!\r\n");memset(WiFi_RX_BUF,0,1024);//WIFI_SendData("hello world");break; //這里直接跳出while(1)循環即可}switch (state){case WIFI_READY://檢測是否手動復位了/*0、按鍵復位*/u1_USART("0、準備按鍵復位!\r\n");if (WIFI_Config0(100))//判是否收到ready{u1_USART("按鍵復位失敗!\r\n");HAL_Delay(WAIT_TIME);}else//成功了 找到了{u1_USART("按鍵復位成功!\r\n");state = WIFI_CONFIG1;}break;case WIFI_CONFIG1:/*1、配置WIFI模式*/u1_USART("1、準備配置WIFI模式!\r\n");if (WIFI_Config(50, "AT+CWMODE=1\r\n", "OK"))//發送命令 檢測OK{u1_USART("配置WIFI模式失敗!\r\n");HAL_Delay(WAIT_TIME);break;}else//成功u1_USART("配置WIFI模式成功!\r\n");u1_USART("\r\n");/*2、重啟(命令方式)*/u1_USART("2、準備復位!\r\n");if (WIFI_Config(50, "AT+RST\r\n", "ready")){u1_USART("復位失敗!\r\n");HAL_Delay(WAIT_TIME);break;}elseu1_USART("復位成功!\r\n");u1_USART("\r\n");/*3、取消自動連接*/u1_USART("3、準備取消自動連接\r\n");if (WIFI_Config(50, "AT+CWAUTOCONN=0\r\n", "OK"))//取消熱點自動連接 檢測OK{u1_USART("取消自動連接失敗!\r\n");HAL_Delay(WAIT_TIME);break;}elseu1_USART("取消自動連接成功!\r\n");WiFi_RxCounter = 0;state = WIFI_ROUTER;break;case WIFI_ROUTER:/*4、連接路由器*/u1_USART("4、準備連接路由器\r\n");if (WIFI_Router(50))//連接熱點并檢測是否連接成功{u1_USART("連接路由器失敗!\r\n");HAL_Delay(WAIT_TIME);}else{u1_USART("連接路由器成功!\r\n");state = WIFI_CONFIG2;}break;case WIFI_CONFIG2:/*5、配置單路連接模式*/u1_USART("5、準備配置單路連接模式!\r\n");if (WIFI_Config(50, "AT+CIPMUX=0\r\n", "OK"))//配置單路連接{u1_USART("配置單路連接模式失敗!\r\n");HAL_Delay(WAIT_TIME);break;}else{u1_USART("配置單路連接模式成功!\r\n");}u1_USART("\r\n");/*6、開啟透傳模式*/u1_USART("6、準備開啟透傳模式\r\n");if (WIFI_Config(50, "AT+CIPMODE=1\r\n", "OK")){u1_USART("開啟透傳模式失敗!\r\n");HAL_Delay(WAIT_TIME);break;}else{u1_USART("開啟透傳模式成功!\r\n");}state = WIFI_CONNECT;break;case WIFI_CONNECT:/*7、建立TCP連接*/u1_USART("7、準備建立TCP連接\r\n");if (WIFI_ConnectTCP(50))//連接TCP{u1_USART("建立TCP連接失敗!\r\n");HAL_Delay(WAIT_TIME);}else{u1_USART("建立TCP連接成功!\r\n");state = WIFI_CONFIG3;}break;case WIFI_CONFIG3:/*8、進入透傳模式*/u1_USART("8、準備進入透傳模式\r\n");if (WIFI_Config(50, "AT+CIPSEND\r\n", "\r\nOK\r\n\r\n>")){u1_USART("進入透傳模式失敗!\r\n");HAL_Delay(WAIT_TIME);}else{u1_USART("進入透傳模式成功!\r\n");state = WIFI_COMPLETE;connect_flag = 1;break;}default:break;}} }//int WIFI_SendData(const char *data) //{ // ESP8266_USART("%s", data); // //u1_USART("數據發送完成\r\n"); // return 0; // if (WIFI_Config(10, "AT+CIPSEND=5\r\n", ">")) // { // ESP8266_USART("%s", data); // u1_USART("數據發送完成\r\n"); // return 0; // } // else // { // u1_USART("數據發送失敗!\r\n"); // return -1; // } //}
wifi.h:
#ifndef _WIFI_H #define _WIFI_H #include <string.h> #include "usart.h" extern uint8_t USART5_RxBuff[1024]; extern volatile uint8_t USART5_RxCounter; #define WiFi_RxCounter USART5_RxCounter #define WiFi_RX_BUF USART5_RxBuff #define ESP8266_USART(fmt, ...) USART_printf(&huart5, fmt, ##__VA_ARGS__) #define u1_USART(fmt, ...) USART_printf(&huart1, fmt, ##__VA_ARGS__) #define ID "zkm" //網絡名字 #define PASSWORD "12345611" //網絡密碼#define ServerIP "192.168.43.148" //服務器IP地址 #define ServerPort 4399 //服務器端口char WIFI_Config0(int time); char WIFI_Config(int time,char*cmd,char*response); char WIFI_Router(int time); char WIFI_ConnectTCP(int time); void WIFI_Connect(void); void ESP8266_Clear(void); #endif
添加外部文件的方式可以參考之前文章,在標題五下的8.2:單片機(STM32-IIC)-CSDN博客
3. 添加串口5空閑中斷
? ? ? ?上述準備工作做完,我們已經有了WiFi模組的函數WIFI_Connect(),還有直接向串口五發送數據的函數USART_printf(UART_HandleTypeDef * USARTx, char * Data, ... ),WIFI_Connect()函數是依賴于串口接收中斷函數,所以我們需要搭建串口五點空閑中斷。(推薦自己先看看wifi文件)
? ? ? ?在我們之前使用AT指令的時候,發送給ESP8266一個數據,會回復相應的消息,WIFI_Connect()函數就是依靠這個邏輯。這個函數讓單片機按順序給ESP8266發送指令,只有接收到ESP8266的ready消息才會發送下一條指令,如果沒有接收到ready消息或者接收到錯誤消息,會一直嘗試連接,由此可見這個函數是阻塞進程的,所以我們要開啟串口5的空閑接收中斷,而且必須在調用WIFI_Connect()函數前開啟一次中斷接收,再在中斷回調函數內開啟中斷接收,每接收到一次數據就開啟下一次中斷接收。
(1)?定義全局變量
uint8_t USART5_RxBuff[1024]={0};
volatile uint8_t USART5_RxCounter=0;

(2) 添加接受中斷函數(不定長)和接收中斷回調函數
細節可以看我的單片機(STM32-串口通信)_stm32串行同步通信-CSDN博客,最好是用不定長接收,因為接收長度是未知的,只要設定長度夠大就能接收并觸發中斷。
中斷函數:
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
寫回調:?
extern int connect_flag;
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{if(huart == &huart5){USART5_RxCounter=1;//此變量置1,則代表wifi發過來了數據HAL_UARTEx_ReceiveToIdle_IT(&huart5,USART5_RxBuff,1024);}
}
4. 嘗試聯網:
5. 打開服務器,燒錄后復位單片機
注意:
(1) 別忘了要更換USB口到單片機的核心板,讓單片機和串口直接通信,ESP8266的模式(S3,S2)也需要切換,切換為MCU模式。
(2) 服務器和單片機連接的網絡處于一個網絡下,按照之前連接網絡和配置網絡虛擬機(服務器)的方式的方式。
(3) 串口助手顯示單片機接收信息,網絡虛擬機充當服務器發送數據到單片機,如下圖:
點擊復位后,串口會輸出下面提示信息,如果成功就說明網絡連接成功,如果卡在某一個位置就去處理響應的問題。?
6. 常見問題解決:
問題一:卡在0.復位,那就是單片機接受不到ESP8266發送的信息
(1) 查看s3,s2是否調節到mcu模式,
(2) 查看cubemx是否配置串口5的中斷
(3) 再查看是否在調用wifi_connect函數前開啟串口5的中斷接收。
(4) 最后再檢查配置流程是否和前面一致。
問題二:卡在4.連接路由器
(1) 先耐心等待幾分鐘,有時候連接時間比較長
(2) 查看網絡是否可用,是否是2.4GHZ頻段下
問題三:卡在準備6.建立TCP連接
查看服務器地址和端口號是否準確,是否按照前面配置方式確定服務器IP地址。
7. 和服務器通信
和服務器通信分兩部分:接收和發送;
(1)、接收已經有了,就是串口5接收中斷函數,只需要在中斷內判斷USART5_RxBuff[1024]字符串,執行操作就可以:
extern int connect_flag;
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{if(huart == &huart5){USART5_RxCounter=1;//此變量置1,則代表wifi發過來了數據if(connect_flag == 1){u1_USART("server:%s\n",USART5_RxBuff);if(strcmp(USART5_RxBuff,"FAN_ON") == 0) //服務器發送FAN_ON打開風扇{HAL_GPIO_WritePin(GPIOC,GPIO_PIN_6,1);}if(strcmp(USART5_RxBuff,"FAN_OFF") == 0) //關閉風扇{HAL_GPIO_WritePin(GPIOC,GPIO_PIN_6,0);}memset(USART5_RxBuff,0,1024); //清空字符數組}HAL_UARTEx_ReceiveToIdle_IT(&huart5,USART5_RxBuff,1024);}
}
(2)、發送就是uart.c函數內添加的驅動函數USART_printf函數,在wifi.c中宏定義改名為ESP8266_USART函數,導入頭文件wifi.h后,兩個函數都可以用,最好直接發送字符串,sprintf拼接字符串后發送。雖然可以“USART_printf("temp:%d",temp);”進行發送,但是對“USART_printf("temp:%f",temp);”就會發送錯誤字符串。
當可以通過串口調試助手控制單片機就大功告成。