AT指令框架

更新时间:2023-12-09 21:27:01 阅读: 评论:0

2023年12月9日发(作者:俄文字母)

-

AT指令框架

AT指令框架

通信模块:BC28

主控:HC32F176KATA

背景:

在公司接受相应的通讯模块,发现要频繁的使用AT指令,然而公司使用的AT指令都是一条条的写的,需要逐条维护,十分麻烦。借着写

nbiot项目时,便自己写了统一的AT指令框架,便于以后对于通讯模块的统一维护。

思路:

结合状态机原理,建立一个二维数组,即表格样式。里面分别存有at指令当前状态,下一状态,发送指令,接受正确应答指令,指令发送后

没有应答的超时时间,重发次数,串口状态,以及特殊处理函数。

特殊处理函数是用来处理非单纯应答正确即可的指令的,比如存储设备的imei号码,我把它放在读取到所有应答数据后的下一步执行。

代码:

定义串口的状态,以及要用到的at指令

typedef enum

{

IDLE = 0,

SUCCESS_REC, //

成功

TIME_OUT, //

超时

NO_REC //

未收到

} rec_state_t;

typedef enum

{

AT = 0, /*

发送

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指令的状态机对象:

typedef struct

{

comd_state_e cur_state; //

当前状态

comd_state_e next_state; //

下一个状态

char AtSendStr[128]; //

发送字符串(

AT

命令)

char ATRecStr[128]; //

需要返回的正确字符串

int wait_time; //

等待时间,单位为

ms

rec_state_t at_status; //

接收状态

int try_cnt; //

重试次数

uint8_t (*recv_deal)(char* data, uint8_t len); //

动作

:

需要对某些返回的数据记录或者错误处理

}fsm_state_t;

定义完整的at指令表格,程序基本按照表格里的at指令顺序执行

fsm_state_t ATCmds[] =

{

//

参数分别为

//

当前状态

下一个状态

NB-IOT

发送字符串(

AT

命令)、

模块应该返回的正确指令、

设置超时(毫秒)、

AT

指令接收状

态、设置重发次数

{AT, CFUN0, "ATrn", "OK", 10000, IDLE, 10,default_deal},//

发送

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},//

置模块自动连接网络

{NCONFIG4, NBAND, "AT+NCONFIG=CELL_RESELECTION,TRUErn", "OK", 300, IDLE, 3, default_deal},//

区重选

{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

,模块

在重启并连接到网络后会触发自动注册物联网平台

{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},//

查询网络注册

状态

{CGATT, NNMI, "AT+CGATT=1rn", "OK", 300, IDLE, 3, default_deal},//

使能网络附着

{NNMI, CSQ, "AT+NNMI=1rn", "OK", 300, IDLE, 3, default_deal},//

接收到一个下行消息后会

发送新消息指示

{CSQ, FINISH, "AT+CSQrn", "rn+CSQ:", 300, IDLE, 3, CSQ_deal},//

查询信号强度

{QLWULDATA, FINISH, "AT+QLWULDATA=", "OK", 1000, IDLE, 3, QLWULDATA_deal},//

发送数

};

接下来是AT指令的接收,发送函数:

fsm_state_t cur = {0,0,0,0,0,0,0,0}; //

相当于一个游动指针,表示当前状态

,

执行完就更新

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) //

发送次数用完处理

{

//

暂定初始化重来

_status = NO_REC;

}

//

尚有发送次数时

el

{

if(at_recv_time > 0) //

接收时间未超时

{

_status = NO_REC; //

没收到数据

//while( (Uart__flag != 1) && (at_recv_time > 0) );

if(Uart__flag == 1) //

规定时间内

nbiot

串口接收到数据

{

Uart__flag = 0;

memt(atbuff, 0, sizeof(atbuff));//

清空

at

指令接收缓存

for(i=0; i

接收到的数据复制到缓存

{

atbuff[i] = U1_RxBuffer[i];

}

if( strstr(atbuff, cmd->ATRecStr ) != NULL)

{

_status = SUCCESS_REC; //

接收状态赋值为成功

cmd->recv_deal(atbuff, Uart__cnt); //

接收

nb

模块数据处理

//

接收到数据后,更新当前执行状态机状态

_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;

}

}

}

封装相应的初始化函数和任务函数,后续注册给相应的通讯模块,放进主循环即可: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();}

-

AT指令框架

本文发布于:2023-12-09 21:27:01,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/zhishi/a/1702128421116498.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:AT指令框架.doc

本文 PDF 下载地址:AT指令框架.pdf

下一篇:返回列表
标签:指令   模块   状态   接收   发送   网络   应答
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 实用文体写作网旗下知识大全大全栏目是一个全百科类宝库! 优秀范文|法律文书|专利查询|