介紹
一種AT命令通信解析模塊,支持裸機(at_chat)和OS版本(at)。適用于modem、WIFI模塊、藍牙通信。
軟件架構
? at_chat.c at_chat.h list.h
用于無OS版本,使用鏈式隊列及異步回調方式處理AT命令收發,支持URC處理、自定義命令發送與解析作業。
?at.c at.h at_util.h comdef.h
用于OS版本, 使用前需要根據at_util.h規定的操作系統相關的接口進行移植,如提供信號量操作、任務延時等操作。
使用說明
at_chat 模塊(無OS)
基本概念
at_chat 模塊使用鏈式隊列進行管理,包含2條鏈表,空閑鏈表和就緒鏈表。它們的每一個基本工作單元稱為一個作業項,對于將要執行的命令都會放到就緒鏈表中,命令執行完成之后由空閑鏈表來進行回收,作業項的定義如下:
/*AT作業項*/ typedefstruct{ unsignedintstate:3; unsignedinttype:3;/*作業類型*/ unsignedintabort:1; void*param;/*通用參數*/ void*info;/*通用信息指針*/ structlist_headnode;/*鏈表結點*/ }at_item_t;
作業是AT控制器定義時固定分配的,沒有使用動態內存,默認支持10個作業項,即同時可以允許10個AT命令排隊等待處理。
基本接口與描述
?at_send_singlline, 發送單行命令,默認等待OK響應,超時3S
?at_send_multiline, 多行命令,默認等待OK響應,超時3S
?at_do_cmd,支持自定義發送格式與接收匹配串
?at_do_work,支持自定義發送與接收解析
效果演示
詳細使用可以參考Demo程序wifi_task.c模塊
m169 wifi模組通信效果圖
使用步驟
1.定義AT控制器及通信適配器接口
/* *@brief定義AT控制器 */ staticat_obj_tat; constat_adapter_tadap={//AT適配器接口 //適配GPRS模塊的串口讀寫接口 .write=uart_write, .read=uart_read ... };
1.初始化AT控制器并放入任務中輪詢(考慮到處理實時性,建議20ms以下)
/* *@briefwifi初始化 */ voidwifi_init(void) { at_obj_init(&at,&adap); /*...*/ }driver_init("wifi",wifi_init); /* *@briefwifi任務(10ms輪詢1次) */ voidwifi_task(void) { at_poll_task(&at); }task_register("wifi",wifi_task,10);
例子演示
//WIFIIO配置命令 =>AT+GPIO_TEST_EN=1 <=?OK
/** *@briefAT執行回調處理程序 */ staticvoidtest_gpio_callback(at_response_t*r) { if(r->ret==AT_RET_OK){ printf("Executesuccessfully "); }else{ printf("Executefailure "); } } at_send_singlline(&at,test_gpio_callback,"AT+GPIO_TEST_EN=1");
at 模塊(OS版本)
由于AT命令通信是一個比較復雜的過程,對于沒有OS的環境下處理難度比較大,也很繞,對于不允許阻塞程序,除了使用狀態與+回調沒有其它更好的辦法,所以推薦使用這個模塊
基本接口與描述
? at_do_cmd,執行AT命令,可以通過這個接口進一步封裝出一常用的單行命令、多行命令。
? at_split_respond_lines,命令響應分割器。
? at_do_work,適用于發送組合命令,如GPRS模組發送短信或者發送socket數據需要等待"<"或者"CONNECT"提示符,可以通過這個接口自定義收發。
使用步驟
1.定義AT控制器、通信適配器接口(包含URC回調函數表,接口緩沖區URC)
staticat_obj_tat;//定義AT控制器對象 staticcharurc_buf[128];//URC主動上報緩沖區 utc_item_tutc_tbl[]={//定義URC表 "+CSQ:",csq_updated_handler } constat_adapter_tadap={//AT適配器接口 .urc_buf=urc_buf, .urc_bufsize=sizeof(urc_buf), .utc_tbl=utc_tbl, .urc_tbl_count=sizeof(utc_tbl)/sizeof(utc_item_t), //debug調試接口 .debug=at_debug, //適配GPRS模塊的串口讀寫接口 .write=uart_write, .read=uart_read };
2.創建AT控制器并創建輪詢處理線程
voidat_thread(void) { at_obj_create(&at,&adap); while(1){ at_process(&at); } }
例子演示
例子1(查詢無線模組信號質量)
/**at_do_cmd接口使用演示 查詢GPRS模組信號質量命令 =>AT+CSQ <=?+CSQ:?24,?0 ????<=?OK */ /*? ?*?@brief????獲取csq值 ?*/? bool?read_csq_value(at_obj_t?*at,?int?*rssi,?int?*error_rate) { ????//接收緩沖區 ????unsigned?char?recvbuf[32]; ????//AT應答 ????at_respond_t?r?=?{"OK",?recvbuf,?sizeof(recvbuf),?3000}; ????// ????if?(at_do_cmd(at,?&r,?"AT+CSQ")?!=?AT_RET_OK) ????????return?false; ????//提取出響應數據 ????return?(sscanf(recv,?"%*[^+]+CSQ:?%d,%d",?rssi,?error_rate)?==?2); }
例子2(發送TCP數據)
/**at_do_work接口使用演示 參考自hl8518模組Socket數據發送命令 =>AT+KTCPSND=, <=?CONNECT ???? ????=> <=?OK */ /* ?*?@brief???????數據發送處理 ?*?@retval??????none ?*/ static?bool?socket_send_handler(at_work_ctx_t?*e) { ????struct?socket_info?*i?=?(struct?socket_info?*)e->params; structril_sock*s=i->s; if(s->type==SOCK_TYPE_TCP) e->printf(e,"AT+KTCPSND=%d,%d",s->session,i->bufsize); else e->printf(e,"AT+KUDPSND=%d,%s,%d,%d",s->session,s->host, s->port,i->bufsize); if(e->wait_resp(e,"CONNECT",5000)!=AT_RET_OK){//等待提示符 gotoError; } e->write(i->buf,i->bufsize);//發送數據 e->write("--EOF--Pattern--",strlen("--EOF--Pattern--"));//發送結束符 if(e->wait_resp(e,"OK",5000)==AT_RET_OK) returntrue; else{ Error: e->write("--EOF--Pattern--",strlen("--EOF--Pattern--")); returnfalse; } } /** *@briefsocket數據發送 *@param[in]s-socket *@param[in]buf-數據緩沖區 *@param[in]len-緩沖區長度 */ staticboolhl8518_sock_send(ril_obj_t*r,structril_sock*s,constvoid*buf, unsignedintlen) { structsocket_infoinfo={s,(unsignedchar*)buf,len,0}; if(len==0) returnfalse; returnat_do_work(&r->at,(at_work)socket_send_handler,&info); }
-
控制器
+關注
關注
112文章
16448瀏覽量
179475 -
WIFI
+關注
關注
81文章
5309瀏覽量
204798 -
藍牙通信
+關注
關注
0文章
31瀏覽量
10957 -
命令
+關注
關注
5文章
696瀏覽量
22114
原文標題:推薦一個開源的AT命令解析模塊
文章出處:【微信號:knifewheat,微信公眾號:小麥大叔】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論