買正點原子的開發板時送了一塊ESP8266wifi模塊,一直沒使用,最近幾天剛好有時間就拿出來玩了一下,現在實作程序分享出來,
用到的模塊:
1.STM32F103C8T6最小系統板

2.正點原子ESP8266wifi模塊

3.USB轉串口模塊

整體連接圖

ESP8266模塊與單片機引腳連接關系 :
| STM32F103C8T6最小系統 | ESP8266 模塊 |
| 5V | VCC |
| GND | GND |
| PB11(USART3_RX) | TXD |
| PB10(USATR3_TX) | RXD |
ESP8266模塊的RST引腳和ID_0引腳懸空,可以不用管,
串口模塊與單片機引腳連接關系 :
| STM32F103C8T6最小系統 | USB轉串口TTL模塊 |
| PA9(USART1_TX) | RXD |
| PA10(USART1_RX) | TXD |
| GND | GND |
USB轉串口模塊連接到單片機的串口1上,單片機串口1用來作為除錯埠,監控程式的執行程序,ESP8266模塊連接到單片機串口3上,串口3用來實作與wifi模塊的通信,
具體實作的功能是:單片機通過wifi模塊連接上原子云,并實時向云端發送資料,通過云端可以向單片機發送 “led on”、“led off”、“led toggle”指令,實作開發板上LED燈的點亮、熄滅、翻轉,
串口1監控資料結果

原子云上監控資料

通過原子云上位機測驗軟體監控

通過手機上原子云客戶端監控:

通過網頁、上位機軟體、手機客戶端可以向單片機發送 “led on”、“led off”、“led toggle”指令,實作開發板上LED燈的點亮、熄滅、翻轉,基本實作的功能就這些,下面說一下實作思想,
ESP8266模塊的驅動代碼是在野火【WiFi_ESP8266】模塊資料上修改的,具體下載地址:https://ebf-products.readthedocs.io/zh_CN/latest/module/wifi/esp8266.html
正點原子ESP8266wifi模塊相關資料下載地址:http://www.openedv.com/thread-308397-1-1.html
通過單片機控制ESP8266模塊連接原子云的程序和直接通過串口除錯ESP8266模塊的程序差不多,實作流程如下:
1.向模塊發送測驗指令
向模塊發生指令: AT
模塊回復指令: OK
2.設定模塊模式為STA模式
向模塊發生指令: AT+CWMODE=1
模塊回復指令: OK
3.設定要連接熱點的 ID 和密碼
向模塊發生指令: AT+CWJAP=“enbiens”,”EB88858804”
模塊回復指令: OK
4.連接原子云 發送設備編號和密碼
向模塊發生指令: AT+ATKCLDSTA="61212332528032817648","12345678"
模塊回復指令: CLOUD CONNECTED
只需要4步就可以連接到原子云上,ESP8266模塊要連接原子云必須要刷原子云的韌體,否則最后一步連接原子云的命令是識別不了的,
首先發送測驗命令,判斷模塊與單片機的連接狀態是否正常,模塊連接正常后就可以發送設定命令了,第二步設定模塊為station模式,也就是設定模塊為從機,第三步連接路由器,發送wifi名稱和密碼,連接上wifi后,模塊就可以通過路由器連接到互聯網上了,最后連接原子云,直接發送原子云上的設備編號和密碼接可以了,這個原子云的設備編號是在原子云網站https://cloud.alientek.com/注冊的時候會默認分配一個設備編號,密碼自己在原子云上可以設定,
要用單片機控制ESP8266模塊的關鍵就是要用代碼實作向ESP8266模塊發送指令,在野火提供的例子中已經實作了這個函式的封裝,
/*
* 函式名:ESP8266_Cmd
* 描述 :對WF-ESP8266模塊發送AT指令
* 輸入 :cmd,待發送的指令
* reply1,reply2,期待的回應,為NULL表不需回應,兩者為或邏輯關系
* waittime,等待回應的時間
* 回傳 : 1,指令發送成功
* 0,指令發送失敗
* 呼叫 :被外部呼叫
*/
bool ESP8266_Cmd ( char * cmd, char * reply1, char * reply2, u32 waittime )
{
strEsp8266_Fram_Record .InfBit .FramLength = 0; //接識訓沖區資料長度清0
macESP8266_Usart ( "%s\r\n", cmd ); //向模塊發送命令
if ( ( reply1 == 0 ) && ( reply2 == 0 ) ) //不需要接收資料
return true;
Delay_ms ( waittime ); //延時 等待接收模塊回傳的指令
strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ] = '\0'; //接收到的字串末尾加入 結束符
macPC_Usart ( "%s", strEsp8266_Fram_Record .Data_RX_BUF ); //除錯口列印接收到模塊的指令
if ( ( reply1 != 0 ) && ( reply2 != 0 ) )
return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply1 ) ||
( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply2 ) );
else if ( reply1 != 0 )
return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply1 ) );
else
return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply2 ) );
}
這個函式主要實作了向ESP82676模塊發送指令,并判斷模塊回傳的指令是否正確,第一個引數cmd中存放要發送的指令,第二個引數存放模塊需要回傳的字串,第三個引數也存放模塊需要回傳的字串,最后一個引數用來設定向模塊發送完指令后需要等待的時間,因為向模塊發送指令到模塊回傳指令還有一段時間的延時,向模塊發送完指令后需要等待一段時間,再去判斷串口3接收到的資料是否正確,
首先將要發送的命令 通過macESP8266_Usart()函式發送出去,
macESP8266_Usart ( "%s\r\n", cmd );
這個函式其實就是通過串口3將字串發送出去,通過串口3向ESP8266模塊發送指令后,延時一段時間等待串口接收資料,
Delay_ms ( waittime );
這行代碼實作延時,因為要等待ESP8266模塊回傳指令,所以代碼不能跳出去,必須在這里死等,
strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ] = '\0'; //接收到的字串末尾加入 結束符
macPC_Usart ( "%s", strEsp8266_Fram_Record .Data_RX_BUF ); //除錯口列印接收到模塊的指令
延時一段時間后,就會在串口3的中斷函式中接收到ESP8266模塊回傳的資料,在接收到的資料最后一位添加上字串結束標志,然后通過除錯埠串口1將模塊回傳的資料列印出來,
最后判斷模塊回傳的字串是否和引數中提供字串一樣,如果一樣說明模塊設定正確,否則說明模塊設定失敗,
要設定不同的命令時,直接呼叫這個命令設定函式就行,比如第一步向模塊發送測驗指令
void ESP8266_AT_Test ( void )
{
char count = 0;
Delay_ms ( 1000 );
while ( count < 10 )
{
if( ESP8266_Cmd ( "AT", "OK", NULL, 500 ) ) return; //如果接收到模塊回傳的OK指令,就直接回傳
ESP8266_Rst(); //否則復位模塊,重新發送AT測驗指令
++ count;
}
}
向模塊發送“AT”字串,如果模塊回傳“OK”則退出,否則回圈發送10次,
第二步設定模塊為station模式
ESP8266_Net_Mode_Choose ( STA );
/*
* 函式名:ESP8266_Net_Mode_Choose
* 描述 :選擇WF-ESP8266模塊的作業模式
* 輸入 :enumMode,作業模式
* 回傳 : 1,選擇成功
* 0,選擇失敗
* 呼叫 :被外部呼叫
*/
bool ESP8266_Net_Mode_Choose ( ENUM_Net_ModeTypeDef enumMode )
{
switch ( enumMode )
{
case STA:
return ESP8266_Cmd ( "AT+CWMODE=1", "OK", "no change", 2500 );
case AP:
return ESP8266_Cmd ( "AT+CWMODE=2", "OK", "no change", 2500 );
case STA_AP:
return ESP8266_Cmd ( "AT+CWMODE=3", "OK", "no change", 2500 );
default:
return false;
}
}
第三步連接路由器
ESP8266_JoinAP ( macUser_ESP8266_ApSsid, macUser_ESP8266_ApPwd );
/*
* 函式名:ESP8266_JoinAP
* 描述 :WF-ESP8266模塊連接外部WiFi
* 輸入 :pSSID,WiFi名稱字串
* :pPassWord,WiFi密碼字串
* 回傳 : 1,連接成功
* 0,連接失敗
* 呼叫 :被外部呼叫
*/
bool ESP8266_JoinAP ( char * pSSID, char * pPassWord )
{
char cCmd [120];
sprintf ( cCmd, "AT+CWJAP=\"%s\",\"%s\"", pSSID, pPassWord );
return ESP8266_Cmd ( cCmd, "OK", NULL, 5000 );
}
第四步連接原子云
ESP8266_ConnectYuanziyun ( yuanziyun_DeviceID, yuanziyun_DevicePassWord );
/*
* ESP8266_ConnectYuanziyun
* 描述 :WF-ESP8266模塊連接原子云
* 輸入 :pSSID,原子云上設備ID
* :pPassWord,原子云上設備密碼
* 回傳 : 1,連接成功
* 0,連接失敗
* 呼叫 :被外部呼叫
*/
bool ESP8266_ConnectYuanziyun ( char * pSSID, char * pPassWord )
{
char cCmd [120];
sprintf ( cCmd, "AT+ATKCLDSTA=\"%s\",\"%s\"", pSSID, pPassWord );
return ESP8266_Cmd ( cCmd, "OK", "CONNECTED", 5000 );
}
這樣通過不同的函式,將不同的命令通過命令發送函式發送到串口3上,也就是發送到ESP8266模塊上,從而實作ESP8266模塊連接到原子云上,
當模塊連接到原子云上之后,就可以通過單片機向云端發送資料了,
void ESP8266_Station_Mode_yuanziyun_Test ( void )
{
uint8_t value1 = 0, value2 = 0;
uint8_t ucStatus;
char cStr [ 100 ] = { 0 };
uint8_t ucId;
char cStr1 [ 100 ] = { 0 };
char * pCh;
printf ( "\r\n正在配置 ESP8266 ......\r\n" );
//1、向模塊發送測驗指令 AT
ESP8266_AT_Test ();
//2、設定模塊模式為STA模式 AT+CWMODE=1
ESP8266_Net_Mode_Choose ( STA );
//3、設定要連接路由器的 ID 和密碼 AT+CWJAP=“enbiens”,”EB88858804”
while ( ! ESP8266_JoinAP ( macUser_ESP8266_ApSsid, macUser_ESP8266_ApPwd ) );
//4、連接原子云 發送設備編號和密碼 AT+ATKCLDSTA="61212332528032817648","12345678"
while ( ! ESP8266_ConnectYuanziyun ( yuanziyun_DeviceID, yuanziyun_DevicePassWord ) );
printf ( "\r\n配置 ESP8266 完畢\r\n" );
while ( 1 )
{
value1++;
value2++;
sprintf ( cStr, "\r\nThe humidity: %d RH ,The temperature: %d C \r\n", value1, value2 );
printf ( "%s", cStr ); //列印資料
ESP8266_SendString ( ENABLE, cStr, 0, Single_ID_0 ); //通過透傳模式 發送資訊到原子云
Delay_ms ( 1500 );
if ( strEsp8266_Fram_Record .InfBit .FramFinishFlag )
{
USART_ITConfig ( macESP8266_USARTx, USART_IT_RXNE, DISABLE ); //禁用串口接收中斷
strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ] = '\0'; //接收到的資料末尾添加結束符
printf ( "\r\n%s\r\n", strEsp8266_Fram_Record .Data_RX_BUF ); //除錯口列印接收到的資料
//strstr是C語言中的函式,作用是回傳字串中首次出現子串的地址,
// 若接收到的字串中包含字串 "led on" 就點亮LED燈
if ( ( pCh = strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "led on" ) ) != 0 )
{
LED1_ON;
}
// 若接收到的字串中包含字串 "led off" 就熄滅LED燈
else if ( ( pCh = strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "led off" ) ) != 0 )
{
LED1_OFF;
}
// 若接收到的字串中包含字串 "led toggle" 就反轉LED燈
else if ( ( pCh = strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "led toggle" ) ) != 0 )
{
LED1_TOGGLE;
}
strEsp8266_Fram_Record .InfBit .FramLength = 0;
strEsp8266_Fram_Record .InfBit .FramFinishFlag = 0;
USART_ITConfig ( macESP8266_USARTx, USART_IT_RXNE, ENABLE ); //使能串口接收中斷
}
}
}
通過兩個變數value1和value2模擬單片機采集到的溫度和濕度值,向云端發送資料,每發送一次資料后這兩個變數加1.當串口3中接收到云端發送的資料后,通過除錯口串口1將接收到的內容列印出來,并判斷云端接收到資料的內容,如果是"led on"就點亮 LED燈,如果是"led off"就熄滅LED燈,如果是"led toggle"就翻轉LED的狀態,最后清除串口接收標志,
通過上面的步驟就能實作單片機和手機客戶端的通信了,也可以通過手機直接控制單片機,如果將單片機連接上家電后,也可以通過手機直接控制家電,
完整工程連接下載地址:
stm32f103c8t6+ESP8266 模塊設定為Station模式并連接原子云
stm32f103c8t6+ESP8266 模塊設定為Station模式向電腦發送資料
stm32f103c8t6+ESP8266 模塊設定為Station模式向手機熱點發送資料
stm32f103c8t6+ESP826 設定為AP模式
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/232517.html
標籤:其他
