编程之通讯解析框架延伸解析AT指令

编程之通讯解析框架延伸解析AT指令说明:前面讲到用通讯解析框架,一般mcu或者其他的嵌入式系统或多或少涉及到通讯。

欢迎大家来到IT世界,在知识的湖畔探索吧!

说明:前面讲到用通讯解析框架,一般mcu或者其他的嵌入式系统或多或少涉及到通讯。不光有各种各样的字节指令,还有字符串指令比如本文要讲的AT指令,很多模块都涉及使用at指令作为指令集去做命令,比如电话模块,wifi模块,蓝牙模块等等,一般at指令解析比较繁琐,如果用到统一的框架做解析呢?

注:通讯解析框架的介绍可以看之前我写的文章内容,这里不再赘述。


下面我们着重讲解使用通讯解析框架解析at指令

以汉枫wifi模块为例

h框架文件:

typedef struct

{

U8 *Readbuf;//读内容

U16 BufLen;//读内容长度

U8 isUp;//主动上传还是下载

int YAL_WifiCmdPos;//其他命令位置

}YAL_WifiCmdPM;//读数据地址

typedef struct

{

const char *Buf;//at内容

U8 (*Handle)(YAL_WifiCmdPM *);//buf长度

U16 GetID;//获取的CMDId

}YAL_WifiCMDHandle;//读数据框架结构

enum

{

YAL_WIFICMD_GET_ENTERAT = 1,//进入AT

YAL_WIFICMD_GET_ANAENTERAT,//应答进入AT

YAL_WIFICMD_SET_CLOSESHOWAT,//关闭回显

};


C内容文件:

U8 Get_YAL_WIFI_EnterAt(YAL_WifiCmdPM *CmdPm);

U8 Get_YAL_WIFI_AckEnterAt(YAL_WifiCmdPM *CmdPm);

U8 Get_YAL_WIFI_CloseShowAt(YAL_WifiCmdPM *CmdPm);

U8 YAL_WIFI_LINK_END[] = { “\r” };//结尾

//获取指令

const U8 YAL_WIFI_REQ[] = { “AT+” };

const YAL_YAL_WifiCMDHandle YAL_WIFI_Cmd_handle[] = {

“+++”, Get_YAL_WIFI_EnterAt, YAL_WIFICMD_GET_ENTERAT,//进入AT

“a”, Get_YAL_WIFI_AckEnterAt, YAL_WIFICMD_GET_ANAENTERAT,//应答AT

“E”, Get_YAL_WIFI_CloseShowAt, YAL_WIFICMD_SET_CLOSESHOWAT,//关闭回显

}

int YAL_WifiCMD_findCmdPos(U16 Cmd)

{

int i;

U8 CmdCt = sizeof(YAL_WIFI_Cmd_handle) / sizeof(YAL_WIFI_Cmd_handle[0]);

for (i = 0; i < CmdCt; i++)

{

if (Cmd == YAL_WIFI_Cmd_handle[i].GetID) return i;

}

return -1;

}

/***********************************************************************

* 函数名称 : Get_YAL_WIFI_MacID

* 描述 : 获取WiFi版本号和MAC ID

* 输入形参 :

* 返回值 : 无

************************************************************************/

U8 Get_YAL_WIFI_EnterAt(YAL_WifiCmdPM *CmdPm)

{

u8 err = 1;

if (CmdPm->isGet){

return YAL_WIFI_ReadCMD(CmdPm->YAL_WifiCmdPos);//

}

else{

if (Str_cmp(CmdPm->Readbuf, (U8 *)”a”) == 1){

err = 0;

}

}

return err;

}

/***********************************************************************

* 函数名称 : Get_YAL_WIFI_MacID

* 描述 : 获取WiFi版本号和MAC ID

* 输入形参 :

* 返回值 : 无

************************************************************************/

U8 Get_YAL_WIFI_AckEnterAt(YAL_WifiCmdPM *CmdPm)

{

u8 err = 1;

if (CmdPm->isGet){

return YAL_WIFI_ReadCMD(CmdPm->YAL_WifiCmdPos);//

}

else{

if (YAL_WifiCmd_isOk(CmdPm->Readbuf)){

SetAtMode(1);

err = 0;

}

}

return err;

}

/***********************************************************************

* 函数名称 : Get_YAL_WIFI_CloseShowAt

* 描述 : 关闭回显

* 输入形参 :

* 返回值 : 无

************************************************************************/

U8 Get_YAL_WIFI_CloseShowAt(YAL_WifiCmdPM *CmdPm)

{

u8 err = 1;

if (CmdPm->isGet){

U8 info_str[10];

//转义字符处理

memset(info_str, 0, sizeof(info_str));

sprintf_s((char *)info_str, sizeof(info_str), “=off%s”, YAL_WIFI_LINK_END);

//strcat((char *)info_str,(char *)YAL_WIFI_LINK_END);

return YAL_WIFI_ReadWriteCMD(CmdPm->YAL_WifiCmdPos, info_str);//

}

else{

if (YAL_WifiCmd_isOk(CmdPm->Readbuf)){

err = 0;

}

}

return err;

}

/***********************************************************************

* 函数名称: YAL_WIFI_ReadCMD

* 描述 : 读WiFi指令

* 输入形参: YAL_WifiCmdPos 列表位置

* 返回值 : 0成功 1失败

************************************************************************/

u8 YAL_WIFI_ReadCMD(int YAL_WifiCmdPos)

{

if (CheckCmdPos(YAL_WifiCmdPos)) return 0;

memcpy(SENDBUF, YAL_WIFI_Cmd_handle[YAL_WifiCmdPos].Buf, strlen((char *)YAL_WIFI_Cmd_handle[YAL_WifiCmdPos].Buf));

USART1_SendString(SENDBUF, strlen((char *)SENDBUF));

return 0;

}

int YAL_WifiCMD_findCmdPos(U16 Cmd)

{

int i;

U8 CmdCt = sizeof(YAL_WIFI_Cmd_handle) / sizeof(YAL_WIFI_Cmd_handle[0]);

for (i = 0; i < CmdCt; i++)

{

if (Cmd == YAL_WIFI_Cmd_handle[i].GetID) return i;

}

return -1;

}

//解析at指令:将字符串数据内容解析到该函数中

U8 YAL_AnaData_revcmd(U8 *Buf, U16 BufLen)

{

int YAL_WifiCmdPos;

YAL_WifiCmdPM cmdPm;

YAL_WifiCmdPos = YAL_WifiCMD_findCmdPos(GetLastCmdId());//上一次请求的内容

if (CheckCmdPos(YAL_WifiCmdPos))return 1;

cmdPm.Readbuf = Buf;

cmdPm.BufLen = BufLen;

cmdPm.YAL_WifiCmdPos = YAL_WifiCmdPos;

cmdPm.isGet = 0;

return YAL_WIFI_Cmd_handle[YAL_WifiCmdPos].Handle(&cmdPm);//回调函数

}

//发送cmd消息:通过CMDId请求对应的at指令

void YAL_WifiCMD_SetCmd(U16 Cmd)

{

int WifiCmdPos;

YAL_WifiCmdPM cmdPm;

cmdPm.Readbuf = SendBuf;

cmdPm.BufLen = 0;

cmdPm.isGet = 1;

WifiCmdPos = WifiCMD_findCmdPos(Cmd);

if (WifiCmdPos == -1)return;

if (CheckCmdPos(WifiCmdPos))return;

cmdPm.WifiCmdPos = WifiCmdPos;

YAL_WIFI_Cmd_handle[WifiCmdPos].Handle(&cmdPm);

SetLastCmdId(YAL_WIFI_Cmd_handle[WifiCmdPos].GetID);

}

总结:通过框架将AT指令的头尾等公共部分作为框架一部分,可变的内容部分作为识别的内容实体,用于解析和发送,比如”+++”作为识别码,“AT+E”中的“E”作为识别码

识别解析的内容通过各种的handle回调处理,当发送一条AT指令,对应的回一条AT指令,解析和发送对应LastCmdId的关系去解对应的回应的AT指令内容,当然AT指令多变,本文只是

抛砖引玉,可相互交流,欢迎评论转发加关注。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/73888.html

(0)
上一篇 2024年 9月 21日 上午10:55
下一篇 2024年 9月 23日 下午6:45

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信