2023年12月9日發(fā)(作者:俄文字母)

AT指令框架
通信模塊:BC28
主控:HC32F176KATA
背景:
在公司接受相應的通訊模塊,發(fā)現(xiàn)要頻繁的使用AT指令,然而公司使用的AT指令都是一條條的寫的,需要逐條維護,十分麻煩。借著寫
nbiot項目時,便自己寫了統(tǒng)一的AT指令框架,便于以后對于通訊模塊的統(tǒng)一維護。
思路:
結(jié)合狀態(tài)機原理,建立一個二維數(shù)組,即表格樣式。里面分別存有at指令當前狀態(tài),下一狀態(tài),發(fā)送指令,接受正確應答指令,指令發(fā)送后
沒有應答的超時時間,重發(fā)次數(shù),串口狀態(tài),以及特殊處理函數(shù)。
特殊處理函數(shù)是用來處理非單純應答正確即可的指令的,比如存儲設備的imei號碼,我把它放在讀取到所有應答數(shù)據(jù)后的下一步執(zhí)行。
代碼:
定義串口的狀態(tài),以及要用到的at指令
typedef enum
{
IDLE = 0,
SUCCESS_REC, //
成功
TIME_OUT, //
超時
NO_REC //
未收到
} rec_state_t;
typedef enum
{
AT = 0, /*
發(fā)送
AT
指令測試
*/
CFUN0,
NCSEARFCN,
NCONFIG1,
NCONFIG2,
NCONFIG3,
NCONFIG4,
NBAND,
NCDP,
QREGSWT,
CFUN1,
NCCID,
CIMI,
CGSN,
CPSMS,
// CEDRXS,
NPTWEDRXS,
NRB,
CEREG,
CGATT,
NNMI,
CSQ,
QLWULDATA,
FINISH
} comd_state_e;
定義at指令的狀態(tài)機對象:
typedef struct
{
comd_state_e cur_state; //
當前狀態(tài)
comd_state_e next_state; //
下一個狀態(tài)
char AtSendStr[128]; //
發(fā)送字符串(
AT
命令)
char ATRecStr[128]; //
需要返回的正確字符串
int wait_time; //
等待時間,單位為
ms
rec_state_t at_status; //
接收狀態(tài)
int try_cnt; //
重試次數(shù)
uint8_t (*recv_deal)(char* data, uint8_t len); //
動作
:
需要對某些返回的數(shù)據(jù)記錄或者錯誤處理
}fsm_state_t;
定義完整的at指令表格,程序基本按照表格里的at指令順序執(zhí)行
fsm_state_t ATCmds[] =
{
//
參數(shù)分別為
//
當前狀態(tài)
下一個狀態(tài)
向
NB-IOT
發(fā)送字符串(
AT
命令)、
模塊應該返回的正確指令、
設置超時(毫秒)、
AT
指令接收狀
態(tài)、設置重發(fā)次數(shù)
{AT, CFUN0, "ATrn", "OK", 10000, IDLE, 10,default_deal},//
發(fā)送
at
指令,確定模塊是否正
常
{CFUN0, NCSEARFCN, "AT+CFUN=0rn", "OK", 5000, IDLE, 3, default_deal},//
關閉射頻功能(不
進行無線通訊)
{NCSEARFCN, NCONFIG1, "AT+NCSEARFCNrn", "OK", 300, IDLE, 3, default_deal},//
清除存儲的頻
點
{NCONFIG1, NCONFIG2, "AT+NCONFIG=CR_0354_0338_SCRAMBLING,TRUErn", "OK", 300, IDLE, 3, default_de
al},//
打開擾碼控制
{NCONFIG2, NCONFIG3, "AT+NCONFIG=CR_0859_SI_AVOID,TRUErn", "OK", 300, IDLE, 3, default_deal},//
打開擾碼控制
{NCONFIG3, NCONFIG4, "AT+NCONFIG=AUTOCONNECT,TRUErn", "OK", 300, IDLE, 3, default_deal},//
配
置模塊自動連接網(wǎng)絡
{NCONFIG4, NBAND, "AT+NCONFIG=CELL_RESELECTION,TRUErn", "OK", 300, IDLE, 3, default_deal},//
小
區(qū)重選
{NBAND, NCDP, "AT+NBAND=5rn", "OK", 300, IDLE, 3, default_deal},//
設置頻段為電信的頻
段
{NCDP, QREGSWT, "AT+NCDP=221.229.214.202,5683rn", "OK", 300, IDLE, 3, default_deal},//
云平臺接
入
ip
地址及端口設置
{QREGSWT, CFUN1, "AT+QREGSWT=1rn", "OK", 300, IDLE, 3, default_deal},//
設置為
1
,模塊
在重啟并連接到網(wǎng)絡后會觸發(fā)自動注冊物聯(lián)網(wǎng)平臺
{CFUN1, NCCID, "AT+CFUN=1rn", "OK", 5000, IDLE, 10, default_deal},//
開啟射頻功能
{NCCID, CIMI, "AT+NCCIDrn", "OK", 300, IDLE, 3, default_deal},//
確認
sim
卡是否存在
{CIMI, CGSN, "AT+CIMIrn", "OK", 300, IDLE, 3, default_deal},//
返回
IMSI
碼
{CGSN, CPSMS, "AT+CGSN=1rn", "rn+CGSN:", 300, IDLE, 3, default_deal},//
返回
IMEI
碼
{CPSMS, NPTWEDRXS, "AT+CPSMS=0rn", "OK", 300, IDLE, 3, default_deal},// PSM
模式設置
// {CEDRXS, NRB, "AT+CEDRXS=0,5rn", "OK", 300, IDLE, 3, default_deal},// eDRX
模式設置
{NPTWEDRXS, NRB, "AT+NPTWEDRXS=3,5rn", "OK", 300, IDLE, 3, default_deal},// eDRX
模式設置
{NRB, CEREG, "AT+NRBrn", "+QLWEVTIND:3", 60000, IDLE, 5, default_deal},//
模塊重啟
{CEREG, CGATT, "AT+CEREG?rn", "rn+CEREG:0,1", 5000, IDLE, 10,default_deal},//
查詢網(wǎng)絡注冊
狀態(tài)
{CGATT, NNMI, "AT+CGATT=1rn", "OK", 300, IDLE, 3, default_deal},//
使能網(wǎng)絡附著
{NNMI, CSQ, "AT+NNMI=1rn", "OK", 300, IDLE, 3, default_deal},//
接收到一個下行消息后會
發(fā)送新消息指示
{CSQ, FINISH, "AT+CSQrn", "rn+CSQ:", 300, IDLE, 3, CSQ_deal},//
查詢信號強度
{QLWULDATA, FINISH, "AT+QLWULDATA=", "OK", 1000, IDLE, 3, QLWULDATA_deal},//
發(fā)送數(shù)
據(jù)
};
接下來是AT指令的接收,發(fā)送函數(shù):
fsm_state_t cur = {0,0,0,0,0,0,0,0}; //
相當于一個游動指針,表示當前狀態(tài)
,
執(zhí)行完就更新
static void At_nd(fsm_state_t cmd)
{
if(_status == IDLE)
{
Uart__SendString(Str,strlen(Str));
at_recv_time = _time;
}
}
static void At_recv(fsm_state_t *cmd)
{
uint8_t i;
if(_cnt == 0) //
發(fā)送次數(shù)用完處理
{
//
暫定初始化重來
_status = NO_REC;
}
//
尚有發(fā)送次數(shù)時
el
{
if(at_recv_time > 0) //
接收時間未超時
{
_status = NO_REC; //
沒收到數(shù)據(jù)
//while( (Uart__flag != 1) && (at_recv_time > 0) );
if(Uart__flag == 1) //
規(guī)定時間內(nèi)
nbiot
串口接收到數(shù)據(jù)
{
Uart__flag = 0;
memt(atbuff, 0, sizeof(atbuff));//
清空
at
指令接收緩存
for(i=0; i 接收到的數(shù)據(jù)復制到緩存 { atbuff[i] = U1_RxBuffer[i]; } if( strstr(atbuff, cmd->ATRecStr ) != NULL) { _status = SUCCESS_REC; // 接收狀態(tài)賦值為成功 cmd->recv_deal(atbuff, Uart__cnt); // 接收 nb 模塊數(shù)據(jù)處理 // 接收到數(shù)據(jù)后,更新當前執(zhí)行狀態(tài)機狀態(tài) _state = _state; _state = ATCmds[_state].next_state; _cnt = ATCmds[_state].try_cnt; _status = ATCmds[_state].at_status; } Uart__cnt = 0; // 串口接收緩存清零 } } el if(at_recv_time == 0) // 超時處理 { _cnt--; _status = IDLE; } } } 封裝相應的初始化函數(shù)和任務函數(shù),后續(xù)注冊給相應的通訊模塊,放進主循環(huán)即可:void AT_init(){ _state = ATCmds[AT].cur_state; _state = ATCmds[AT].next_state; _cnt = ATCmds[AT].try_cnt;}void At_task(){ if(_state != FINISH ) { At_nd(ATCmds[_state]); At_recv(&ATCmds[_state]); } ZD_NB_transfer();}-
本文發(fā)布于:2023-12-09 21:27:01,感謝您對本站的認可!
本文鏈接:http://www.newhan.cn/zhishi/a/1702128421116498.html
版權(quán)聲明:本站內(nèi)容均來自互聯(lián)網(wǎng),僅供演示用,請勿用于商業(yè)和其他非法用途。如果侵犯了您的權(quán)益請與我們聯(lián)系,我們將在24小時內(nèi)刪除。
本文word下載地址:AT指令框架.doc
本文 PDF 下載地址:AT指令框架.pdf
| 留言與評論(共有 0 條評論) |