介紹
一種AT命令通信解析模塊,支持裸機(jī)(at_chat)和OS版本(at)。適用于modem、WIFI模塊、藍(lán)牙通信。
軟件架構(gòu)
? at_chat.c at_chat.h list.h
用于無OS版本,使用鏈?zhǔn)疥?duì)列及異步回調(diào)方式處理AT命令收發(fā),支持URC處理、自定義命令發(fā)送與解析作業(yè)。
?at.c at.h at_util.h comdef.h
用于OS版本, 使用前需要根據(jù)at_util.h規(guī)定的操作系統(tǒng)相關(guān)的接口進(jìn)行移植,如提供信號量操作、任務(wù)延時等操作。
使用說明
at_chat 模塊(無OS)
基本概念
at_chat 模塊使用鏈?zhǔn)疥?duì)列進(jìn)行管理,包含2條鏈表,空閑鏈表和就緒鏈表。它們的每一個基本工作單元稱為一個作業(yè)項(xiàng),對于將要執(zhí)行的命令都會放到就緒鏈表中,命令執(zhí)行完成之后由空閑鏈表來進(jìn)行回收,作業(yè)項(xiàng)的定義如下:
/*AT作業(yè)項(xiàng)*/ typedefstruct{ unsignedintstate:3; unsignedinttype:3;/*作業(yè)類型*/ unsignedintabort:1; void*param;/*通用參數(shù)*/ void*info;/*通用信息指針*/ structlist_headnode;/*鏈表結(jié)點(diǎn)*/ }at_item_t;
作業(yè)是AT控制器定義時固定分配的,沒有使用動態(tài)內(nèi)存,默認(rèn)支持10個作業(yè)項(xiàng),即同時可以允許10個AT命令排隊(duì)等待處理。
基本接口與描述
?at_send_singlline, 發(fā)送單行命令,默認(rèn)等待OK響應(yīng),超時3S
?at_send_multiline, 多行命令,默認(rèn)等待OK響應(yīng),超時3S
?at_do_cmd,支持自定義發(fā)送格式與接收匹配串
?at_do_work,支持自定義發(fā)送與接收解析
效果演示
詳細(xì)使用可以參考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控制器并放入任務(wù)中輪詢(考慮到處理實(shí)時性,建議20ms以下)
/* *@briefwifi初始化 */ voidwifi_init(void) { at_obj_init(&at,&adap); /*...*/ }driver_init("wifi",wifi_init); /* *@briefwifi任務(wù)(10ms輪詢1次) */ voidwifi_task(void) { at_poll_task(&at); }task_register("wifi",wifi_task,10);
例子演示
//WIFIIO配置命令 =>AT+GPIO_TEST_EN=1 <=?OK
/** *@briefAT執(zhí)行回調(diào)處理程序 */ 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命令通信是一個比較復(fù)雜的過程,對于沒有OS的環(huán)境下處理難度比較大,也很繞,對于不允許阻塞程序,除了使用狀態(tài)與+回調(diào)沒有其它更好的辦法,所以推薦使用這個模塊
基本接口與描述
? at_do_cmd,執(zhí)行AT命令,可以通過這個接口進(jìn)一步封裝出一常用的單行命令、多行命令。
? at_split_respond_lines,命令響應(yīng)分割器。
? at_do_work,適用于發(fā)送組合命令,如GPRS模組發(fā)送短信或者發(fā)送socket數(shù)據(jù)需要等待"<"或者"CONNECT"提示符,可以通過這個接口自定義收發(fā)。
使用步驟
1.定義AT控制器、通信適配器接口(包含URC回調(diào)函數(shù)表,接口緩沖區(qū)URC)
staticat_obj_tat;//定義AT控制器對象 staticcharurc_buf[128];//URC主動上報(bào)緩沖區(qū) 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調(diào)試接口 .debug=at_debug, //適配GPRS模塊的串口讀寫接口 .write=uart_write, .read=uart_read };
2.創(chuàng)建AT控制器并創(chuàng)建輪詢處理線程
voidat_thread(void) { at_obj_create(&at,&adap); while(1){ at_process(&at); } }
例子演示
例子1(查詢無線模組信號質(zhì)量)
/**at_do_cmd接口使用演示 查詢GPRS模組信號質(zhì)量命令 =>AT+CSQ <=?+CSQ:?24,?0 ????<=?OK */ /*? ?*?@brief????獲取csq值 ?*/? bool?read_csq_value(at_obj_t?*at,?int?*rssi,?int?*error_rate) { ????//接收緩沖區(qū) ????unsigned?char?recvbuf[32]; ????//AT應(yīng)答 ????at_respond_t?r?=?{"OK",?recvbuf,?sizeof(recvbuf),?3000}; ????// ????if?(at_do_cmd(at,?&r,?"AT+CSQ")?!=?AT_RET_OK) ????????return?false; ????//提取出響應(yīng)數(shù)據(jù) ????return?(sscanf(recv,?"%*[^+]+CSQ:?%d,%d",?rssi,?error_rate)?==?2); }
例子2(發(fā)送TCP數(shù)據(jù))
/**at_do_work接口使用演示 參考自hl8518模組Socket數(shù)據(jù)發(fā)送命令 =>AT+KTCPSND=, <=?CONNECT ???? ????=> <=?OK */ /* ?*?@brief???????數(shù)據(jù)發(fā)送處理 ?*?@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);//發(fā)送數(shù)據(jù) e->write("--EOF--Pattern--",strlen("--EOF--Pattern--"));//發(fā)送結(jié)束符 if(e->wait_resp(e,"OK",5000)==AT_RET_OK) returntrue; else{ Error: e->write("--EOF--Pattern--",strlen("--EOF--Pattern--")); returnfalse; } } /** *@briefsocket數(shù)據(jù)發(fā)送 *@param[in]s-socket *@param[in]buf-數(shù)據(jù)緩沖區(qū) *@param[in]len-緩沖區(qū)長度 */ 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); }
-
控制器
+關(guān)注
關(guān)注
114文章
17098瀏覽量
184189 -
WIFI
+關(guān)注
關(guān)注
81文章
5402瀏覽量
208279 -
藍(lán)牙通信
+關(guān)注
關(guān)注
0文章
36瀏覽量
11100 -
命令
+關(guān)注
關(guān)注
5文章
737瀏覽量
22873
原文標(biāo)題:推薦一個開源的AT命令解析模塊
文章出處:【微信號:knifewheat,微信公眾號:小麥大叔】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
評論