stm32-esp8266驅動程式
esp8266模組是串列埠通訊,通訊的協議是AT指令,要正確的配置對應的AT指令模組才可以工作,這裡就需要知道AT指令有沒有配置成功,這個比較容易實現,一般傳送AT指令配置成功的話,晶片都會返回至少一個OK,當然還有其它資料,我們只需要去解析有沒有接收到OK就知道指令傳送是否成功了。我這裡是作為TCP客服端,所以只需要以下一些指令即可:
1>> 傳送 AT\r\n 返回 "OK" 以上操作確保晶片連線正常,工作正常 2>> 傳送 ATE0\r\n 返回 "OK" 關閉回顯 3>> 傳送 AT+CWMODE=1\r\n 返回 "OK" 設定成客服端模式 4>> 傳送 AT+CIPSTATUS 返回 "2 3 4 5" 2 3為連線 確保連線到路由器 5>> 傳送 AT+CWJAP="HES_WIFI","wifi_pass" 返回 "OK" 返回 "FAIL" 連線到路由器 6>> 傳送 AT+CWAUTOCONN=1 返回 "OK" 開機自動連線 7>> 傳送 AT+CIPSTART="TCP","192.168.0.105",8888 返回 "OK" 連線到伺服器 8>> 傳送 AT+CIPCLOSE 返回 "OK" 關閉伺服器連線 8>> 傳送 AT+CIPMODE=1 返回 "OK" 設定透傳模式1 9>> 傳送 AT+CIPSEND 返回 ">" 進入透傳 10>> 傳送 +++ 返回 無
程式驅動也會按照這個流程來實現;
大概框架如下
esp8266wifi.c檔案主要是AT指令配置
serial_config.c檔案主要用於解析返回的資料,例如OK,>等
uart.c是串列埠的應用協議
1-先看看esp8266wifi的內容
#define FANHUI_V "OK" //普通指令返回值 extern u8 wifi_name[20]; //路由器名字 extern u8 wifi_pass[20]; //路由器密碼 extern u8 wifi_ip[32]; //伺服器ip extern u8 wifi_port[6]; //伺服器埠 static u8 wifi_work_mode; //wifi模組的工作模式,1為配置模式,2為透傳模式 #define _WIFI_TRAN_MODE 2 #define _WIFI_CONFIG_MODE 1 /*模組初始化 1.測試AT命令,保證晶片工作正常 2.關閉回顯 3.設定成客服端模式 4.連線到路由器 5.連線到伺服器 6.設定透傳模式1 7.開始透傳 8.關閉透傳 */ u8 esp8266_init(void); //測試AT指令,確保連線和晶片正常 u8 test_at(void); //關閉回顯 u8 close_huixian(void); //設定成客戶端 u8 set_client(void); //判斷是否連線路由器 u8 is_connect_ap(void); //連線到路由器 u8 connect_ap(void); //設定自動連線路由器 u8 aotu_connect_ap(void); //連線到伺服器 u8 connect_server(void); //斷開伺服器 u8 disconnect_server(void); //設定透傳模式 u8 set_mode1(void); //開始透傳 u8 start_tran(void); //關閉透傳 u8 close_tran(void); //設定為透傳模式 void set_tran_mode(void); //設定成配置模式 void set_config_mode(void); //獲取工作模式 u8 get_work_mode(void); //傳送命令和等待時間 u8 send_cmd_wait(u8 *str,u8 len,u32 d_ms); #endif
這裡主要介紹一下
//傳送命令和等待時間 u8 send_cmd_wait(u8 *str,u8 len,u32 d_ms);
這個函式比較重要,主要功能還是發生一個AT指令,等待nms後檢測是否收到OK,下面是實現
//傳送命令和等待時間
u8 send_cmd_wait(u8 *str,u8 len,u32 d_ms)
{
serial2_sned_buff(str,len);
delay_ms(d_ms);
if(find_quq_del(OK)) //查詢串列埠資料快取是否OK
{
return 1;
}
return 0;
}
關閉透傳也比較特殊,實現如下
//關閉透傳
u8 close_tran()
{
serial2_sned_buff((u8*)"+++",3);
delay_ms(20);
serial2_sned_buff((u8*)"+++",3);
delay_ms(20);
serial2_sned_buff((u8*)"\r\n",2);
delay_ms(20);
return 1;
}
所有函式太多,只介紹幾個關鍵的,其它的可以在後面下載原始碼。
接下來是serial_config檔案
這個檔案主要實現1-串列埠緩衝區新增資料(資料要在串列埠中斷新增),2-解析是否存在相應指令
#define MES_LEN 200
//command
#define OK (char*)"OK"
#define AP2 (char*)"2\r\n"
#define AP3 (char*)"3\r\n"
#define OFF (char*)"off"
#define ON (char*)"on"
#define STATE (char*)"state"
//Log Switch
#define ERIAL_CONFIG_LOG 0
static int num;
static char mes_buf[MES_LEN]; //串列埠佇列長度
//尋找子並移除子串
int find_str_del(char *mes,char *str);
//尋找命令
//引數:命令
//查詢到命令返回1,否則0
int find_quq_del(char *str);
//新增資料到佇列
void add_mes_buf(char ch);
#endif
uart.c應用協議是自己定義的,和模組沒有關係,其實以上2個檔案已經看正常的初始化esp8266了。
初始化函式:
u8 esp8266_init()
{
//設定成配置模式
set_config_mode();
//測試AT
if(test_at())
{
#if ESP8266_LOG
printf("esp8266硬體 正常\r\n");
#endif
}
else
{
#if ESP8266_LOG
printf("esp8266硬體 異常\r\n");
printf("嘗試關閉透傳...\r\n");
#endif
close_tran();
}
//關回顯
if(close_huixian())
{
#if ESP8266_LOG
printf("關閉esp8266回顯 正常\r\n");
#endif
}
else
{
#if ESP8266_LOG
printf("關閉esp8266回顯 異常\r\n");
#endif
}
//設定成客戶端
if(set_client())
{
#if ESP8266_LOG
printf("設定成客戶端 正常\r\n");
#endif
}
else
{
#if ESP8266_LOG
printf("設定成客戶端 異常\r\n");
#endif
}
//判斷是否連線到路由器 is_connect_ap
if(is_connect_ap())
{
#if ESP8266_LOG
printf("連線路由器 正常\r\n");
#endif
}
else //如果沒有連線路由器,則去連線
{
#if ESP8266_LOG
printf("連線路由器 異常\r\n");
printf("嘗試連線路由器...\r\n");
#endif
if(connect_ap())
{
#if ESP8266_LOG
printf("連線路由器 正常\r\n");
#endif
aotu_connect_ap();
}
else
{
#if ESP8266_LOG
printf("連線路由器 異常\r\n");
#endif
}
}
//連線到伺服器
if(connect_server())
{
#if ESP8266_LOG
printf("連線伺服器 正常\r\n");
#endif
}
else
{
#if ESP8266_LOG
printf("連線伺服器 異常\r\n");
printf("嘗試關閉連線伺服器,重新連線...\r\n");
#endif
if(disconnect_server())
{
#if ESP8266_LOG
printf("關閉連線伺服器 正常\r\n");
#endif
//連線到伺服器
if(connect_server())
{
#if ESP8266_LOG
printf("重新連線伺服器 正常\r\n");
#endif
}
else
{
#if ESP8266_LOG
printf("連線伺服器 異常\r\n");
#endif
}
}
else
{
#if ESP8266_LOG
printf("關閉連線伺服器 異常\r\n");
#endif
}
}
//設定透傳模式1
if(set_mode1())
{
#if ESP8266_LOG
printf("設定透傳模式1 正常\r\n");
#endif
}
else
{
#if ESP8266_LOG
printf("設定透傳模式1 異常\r\n");
#endif
}
//開始透傳
if(start_tran())
{
#if ESP8266_LOG
printf("開始透傳 正常\r\n");
#endif
//設定成配置模式
set_tran_mode();
}
else
{
#if ESP8266_LOG
printf("開始透傳 異常\r\n");
#endif
return 0;
}
return 1;
}
整體使用的過程。
1,主函式必須初始化串列埠,esp8266_init()
2,while(1)裡面實現如下,
//任務2函式
void task2_func(void *param)
{
u8 data_count_time=0;
int j=1;
while(1)
{
if(get_work_mode()==_WIFI_TRAN_MODE) //判斷是否是透傳模式
{
//檢查wifi資料
check_wifi_data();
if(wifi_mes.recv_len>0)
{
printf("%dwifi:%s\r\n",j++,wifi_mes.recv_data);
}
else
{
data_count_time++;
if(data_count_time==5) //如果很久沒有接到資料
{
clear_wifi_buf(); //清空快取
}
}
//serial2_sned_buff((u8*)"hello world\r\n",13);
}
task_delay(1);
}
}
串列埠中斷實現如下:如果是配置模式,把資料放到命令解析的快取裡,如果是透傳模式,把資料放到應用協議的快取裡
void USART2_IRQHandler(void)
{
USART_ClearFlag(USART2,USART_FLAG_TC);
if(USART_GetITStatus(USART2,USART_IT_RXNE)!=Bit_RESET)//檢查指定的USART中斷髮生與否
{
u8 k=USART_ReceiveData(USART2);
if(get_work_mode()==_WIFI_CONFIG_MODE) //如果是配置模式
{
add_mes_buf(k);
}else
{
wifi_buf_add(k);
//printf("%x ",k);
}
}
}
整體測試下來,效果還是很不錯的,一晚上通訊沒有宕機掉線。用的是TCP工具,沒有自己寫socket
程式碼量還是比較多的,不能一一講解,可以下載原始碼學習,看部分程式碼可以知道註釋是很足的。