文檔創(chuàng)建時間:2016年3月10日
本文檔描述的是如何在stm32f10x
上用串口轉(zhuǎn)wifi模塊ESP8266
實現(xiàn)與上位機的通信。
模塊介紹
ESP8266模塊,是一款USART轉(zhuǎn)WiFi模塊州叠,可以使嵌入式系統(tǒng)串口通過無線網(wǎng)絡(luò)與上位機進行通信。
引腳
這個模塊的引腳一般引出來的有6個:
- VCC:電源(建議接3.3v,在5v下也可以工作,據(jù)測試發(fā)熱量稍大)
- GND:電源地
- TXD:模塊串口發(fā)送引腳(TTL電平屋休,可接單片機的RXD)
- RXD:模塊串口接收引腳(TTL電平,可接單片機的TXD)
- RST:復位(低電平有效)
- IO-0:低電平是進入固件燒寫模式备韧,高電平為運行狀態(tài)(默認狀態(tài))
工作模式
這個模塊通常會有三種工作模式:
- AP模式劫樟,這種模式下模塊相當于一個WiFi熱點,其他設(shè)備可以接入這個熱點织堂,從而實現(xiàn)無線通信叠艳。(和藍牙類似,不需要網(wǎng)絡(luò)也可以實現(xiàn))
- STA模式捧挺,這個模式下模塊相當于一個WiFi設(shè)備虑绵,需要通過路由器與其他的網(wǎng)絡(luò)設(shè)備通信尿瞭。
- AP+SAT模式闽烙,這種模式是上述兩種模式的并集。
每種模式下声搁,都有若干種“身份”黑竞。本文檔,主要討論的是模塊在STA模式下充當TCP Client的使用方法疏旨。
指令介紹
模塊提供了一套完整的AT指令很魂,供我們來操作,詳細的指令請參考文檔檐涝,這里不逐一列出遏匆。
注意事項
- 波特率115200
- 輸入以回車換行符‘\r\n'結(jié)尾
- 使用雙引號表示字符串數(shù)據(jù)
具體實現(xiàn)
實現(xiàn)WiFi的功能法挨,分成硬件和軟件部分。硬件上幅聘,使用stm32的USART2與ESP8266相連接凡纳。軟件上,根據(jù)手冊帝蒿,封裝AT命令荐糜,使用中斷讀取接收數(shù)據(jù)等。
引腳連接方式:
- ESP8266_RXD連接stm32_USART2_TXD
- ESP8266_TXD連接stm32_USART2_RXD
- ESP8266_VCC連接3.3v
- ESP8266_GND連接GND
- ESP8266_RST懸空
- ESP8266_I0_0懸空
PS:stm32與ESP8266要共地葛超。
軟件上暴氏,主要由下面幾個文件來實現(xiàn)WiFi模塊的驅(qū)動:
- wifi_config.c 這個文件主要完成USART2的初始化,USART2的中斷控制器配置
- wifi_function.c 這個文件主要實現(xiàn)對wifi模塊的AT指令操作绣张,并完成STA TCP Client連接
這里不給出詳細的代碼答渔,具體的代碼可以看這里,這里重點討論wifi_function.c
這個文件侥涵,下面列出它的函數(shù)作解釋研儒,具體實現(xiàn)自己看看源文件:
//使能wifi模塊
void ESP8266_Choose ( FunctionalState enumChoose );
//重啟模塊
void ESP8266_Rst( void );
//執(zhí)行AT測試
void ESP8266_AT_Test( void );
//發(fā)送AT指令
//cmd:AT指令內(nèi)容, reply1:期望的回應独令, reply2:期望的回應端朵,waittime:等待時間
bool ESP8266_Cmd( char * cmd, char * reply1, char * reply2, u32 waittime );
//選擇wifi模塊的模式 AP, STA燃箭, AP+STA
bool ESP8266_Net_Mode_Choose( ENUM_Net_ModeTypeDef enumMode );
//開啟多客戶端連接
bool ESP8266_Enable_MultipleId( FunctionalState enumEnUnvarnishTx );
//連接到服務器(STA模式下需要使用到)
bool ESP8266_Link_Server( ENUM_NetPro_TypeDef enumE, char * ip, char * ComNum, ENUM_ID_NO_TypeDef id);
//開啟透傳模式
bool ESP8266_UnvarnishSend( void );
//發(fā)送數(shù)據(jù)
bool ESP8266_SendString( FunctionalState enumEnUnvarnishTx, char * pStr, u32 ulStrLength, ENUM_ID_NO_TypeDef ucId );
//接收數(shù)據(jù)
char *ESP8266_ReceiveString( FunctionalState enumEnUnvarnishTx );
//配置STA_TCP_Client連接模式
bool ESP8266_STA_TCP_Client( void );
//從透傳模式返回普通AT模式
bool ESP8266_Return_At( void );
//失能透傳模式
bool ESP8266_Disable_UnvarnishSend( void );
//關(guān)閉TCP連接
bool ESP8266_Tcp_Close( void );
//按照配置冲呢,開啟TCP連接
bool ESP8266_Connect_Tcp( void );
具體,是怎么往模塊里面發(fā)送AT指令的招狸,這里以其中一個為例子進行講述:
//加入某個wifi熱點的函數(shù)
//對應的AT指令是:AT+CWJAP=“ssid”,“passwor”
bool ESP8266_JoinAP ( char * pSSID, char * pPassWord ){
//聲明一個存放命令的區(qū)域
char cCmd [120];
//通過sprintf函數(shù)敬拓,將參數(shù)傳進來的ssid和password拼接到字符串后面,放入之前聲明的區(qū)域
sprintf ( cCmd, "AT+CWJAP=\"%s\",\"%s\"", pSSID, pPassWord );
//通過ESP8266_Cmd ()函數(shù)裙戏,往模塊里面寫入命令
return ESP8266_Cmd ( cCmd, "OK", NULL, 7000 );
}
下面乘凸,分析下如何配置TCP連接,并使能它的:
//配置TCP連接
//LCD是為了便于調(diào)試添加的累榜,在液晶屏上顯示程序的運行信息
bool ESP8266_STA_TCP_Client ( void ){
bool statusCur = false;
bool statusLst = true;
// 開啟sta連接模式
LCD_DispStr(0,0,(uint8_t *)"begin to sta connection ...",BLUE);
ESP8266_AT_Test ();
statusCur = ESP8266_Net_Mode_Choose ( STA );
if (statusCur == true){
LCD_DispStr(0,20,(uint8_t *)"sta mode success",0xffff);
statusLst = true;
}else{
LCD_DispStr(0,20,(uint8_t *)"sta mode fail",0xffff);
statusLst = false;
}
//加入熱點的SSID和PASSWORD
LCD_DispStr(0,40,(uint8_t *)"begin to join ERIC_LAI ...",BLUE);
//這里寫死了熱點的ssid和pw营勤,需要根據(jù)各自的情況自行修改
statusCur = ESP8266_JoinAP ( "ERIC_LAI", "lai686868" );
if (statusCur == true && statusLst == true){
LCD_DispStr(0,60,(uint8_t *)"join ERIC_LAI success",0xffff);
statusLst = true;
} else{
LCD_DispStr(0,60,(uint8_t *)"join ERIC_LAI success",0xffff);
statusLst = false;
}
}
//使能TCP連接
bool ESP8266_Connect_Tcp(void){
bool status = false;
// 連接到TCP服務器
ESP8266_Enable_MultipleId ( ENABLE );
LCD_DispStr(0,120,(uint8_t *)"begin to connect the server ...",BLUE);
status = ESP8266_Link_Server ( enumTCP, serverIpAddress, "9998", Multiple_ID_0 );
if (status == true){
LCD_DispStr(0,140,(uint8_t *)"connect server success",0xffff);
} else{
LCD_DispStr(0,140,(uint8_t *)"connect server fail",0xffff);
}
return status;
}
這一步成功之后,就是接受和發(fā)送數(shù)據(jù)的事情了壹罚。因為是串口葛作,所以本質(zhì)上用的還是串口中斷來接收數(shù)據(jù)的。在wifi_config.c里面猖凛,我們完成了串口的使用和中斷的配置赂蠢。但是,串口只能一位一位的發(fā)送數(shù)據(jù)辨泳,所以虱岂,我們需要寫一些代碼來實現(xiàn)字符串的接收玖院。上面的注意事項,’\r\n‘是發(fā)送完成的標志第岖。所以司恳,我們一直接收數(shù)據(jù),知道接收到回車換行符為止绍傲。接收到后扔傅,標志位置位,退出接收循環(huán)烫饼。詳細代碼如下:
//以下的代碼在stm32f10x_it.c里面
void USART2_IRQHandler( void ){
char ch;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET){
ch = USART_ReceiveData( USART2 );
if( strEsp8266_Fram_Record .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) ){ //預留1個字節(jié)寫結(jié)束符
strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ++ ] = ch;
}
}
if ( USART_GetITStatus( USART2, USART_IT_IDLE ) == SET ) {//數(shù)據(jù)幀接收完畢
strEsp8266_Fram_Record .InfBit .FramFinishFlag = 1;
ch = USART_ReceiveData( USART2 ); //由軟件序列清除中斷標志位(先讀USART_SR猎塞,然后讀USART_DR)
}
}
以上,完成之后杠纵,通過上面給出的ESP8266_ReceiveString()
函數(shù)就可以獲取接收到的字符串荠耽,注意:這是一個堵塞的函數(shù)!一旦調(diào)用就會等待接收到回車換行符為止比藻。
上面的代碼铝量,在發(fā)送數(shù)據(jù)和接收數(shù)據(jù)的情況,都沒有使用透傳模式银亲。所以慢叨,發(fā)送數(shù)據(jù)的時候需要確定數(shù)據(jù)的長度(最長不超過1024),接收數(shù)據(jù)的時候會有報頭(+IDP,*,*:)务蝠。所以拍谐,發(fā)送圖片的時候需要將圖片分割開來發(fā)送,接收的時候需要做數(shù)據(jù)截斷馏段,把報頭去掉轩拨。關(guān)于圖片分割,在圖片傳輸?shù)臅r候講述院喜,截斷數(shù)據(jù)的方法在下面給出:
char* getRealRecv(char *pStr){
char *pBuf, *ppStr, *pStrDelimiter[2];
int uc = 0;
char cStrInput [100];
sprintf(cStrInput, "%s", pStr);
pBuf = cStrInput;
uc = 0;
while ( ( ppStr = strtok ( pBuf, ":" ) ) != NULL ){
pStrDelimiter [ uc ++ ] = ppStr;
pBuf = NULL;
}
return pStrDelimiter[1];
}
以上亡蓉,是WiFi模塊的完成過程。