赞
踩
普通代码发送at指令的,至少我去年搜这方面资料的时候,很多都是堵塞性的,主体框架大部分是
:send AT rec ok send ATEO rec OK ... 将连接网络的at流程全部走一遍,然后再正常调用网络发送接收的数据。这样就是堵塞式的收发流程。尤其在低功耗场景下。设备发送完就立刻低功耗,这样堵塞的时间占比明显就过高。故此退出以下框架。
- /*
- * 作者: GG
- * 邮箱: guotaoyuan1998@163.com
- * VX: qingya_1998
- * 创建日期: 22/08/17
- * 更新日期: 22/08/18
- * 版本: V1.3
- * 更新说明:
- * (BETA):增加了指令错误多次后的处理函数
- * (BETA):统一的失败判定,默认为重发,特殊需求自改
- * (V1.3):新增了部分地方注释,将大部分要移植微调的部分加入标识(GG修改@GSM)区别
- * 与之前写的库。
- * (V1.3):新增了csq,ccid等外部接口
- * ps: 计划下个版本内容:外部接口多场景测试,除了AT和ATE的action判定修改
- *
- * 使用方式: 调用 g_GsmWork.send();-> g_GsmWork.rec(USART_RX_BUF); (推荐可以在串口完成标志判断后调用)
- * -> 对应界面逻辑方面修改,尤其是标识部分
- */
-
- #define AT_SENDDATA printf
-
- static GG_GsmSignSta_TypeDef s_AT_SignSta;
- static GG_GsmSendSta Gsm_SignRecHandleCallback(unsigned char *buf);//接收处理(GG修改@GSM)
-
- typedef struct
- {
- GG_ATStepName Step;//当前步骤
- GG_ATStepName NextStep;//下一步骤
- void (*action)();//当前步骤指令发送
- void (*outTimeAction)(); //超时处理
- void (*delAction)(); //多次超时错误处理
- uint16_t outtime;//超出单位时间
- uint16_t outtimeloop;//超时错误次数
-
- }GG_ATWORK_TypeDef;
-
- static GG_ATWORK_TypeDef s_atBobyHandleMap[] =
- {
- {AT,ATEO,AT_Action,OutTimeAction,DelAction,100,5},
- {ATEO,CCID,ATEO_Action,OutTimeAction,DelAction,100,5},
- {CCID,CGDCONT,CCID_Action,OutTimeAction,DelAction,100,5},
- {CGDCONT,CSQ,CGDCONT_Action,OutTimeAction,DelAction,100,5},
- {CSQ,CREG,CSQ_Action,OutTimeAction,DelAction,100,5},
- {CREG,QMTCFG,CREG_Action,OutTimeAction,DelAction,100,5},
- {QMTCFG,QMTOPEN,QMTCFG_Action,OutTimeAction,DelAction,100,5},
- {QMTOPEN,QMTCONN,QMTOPEN_Action,OutTimeAction,DelAction,100,5},
- {QMTCONN,QMTSUB,QMTCONN_Action,OutTimeAction,DelAction,100,5},
- {QMTSUB,QMTPUBEX,QMTSUB_Action,OutTimeAction,DelAction,100,5},
- {QMTPUBEX,ATWAIT,QMTPUBEX_Action,OutTimeAction,DelAction,100,5},
- {QMTPUBEX,ATWAIT,QMTPUBEX_Action,OutTimeAction,DelAction,100,5},
-
- };//(GG修改@GSM)
-
- GG_GsmWork_TypeDef g_GsmWork =
- {
- Gsm_Process_Send,
- Gsm_Process_Rec,
-
- };
如上代码所示,MAP第一个属性是第一个步骤,第二个属性是下一步,之后就是对应的处理,超时或错误处理,和多次超时错误处理。最后是时间和错误允许次数
用的时候自行添加步骤和下一步。
- static void AT_Action(void)
- {
- AT_SENDDATA("AT\r\n");
-
- }
-
- static void ATEO_Action(void)
- {
- AT_SENDDATA("ATEO\r\n");
-
- }
-
- static void CCID_Action(void)
- {
- AT_SENDDATA("AT+CCID\r\n");
-
- }
-
- static void CGDCONT_Action(void)
- {
- AT_SENDDATA("AT+CGDCONT?\r\n");
-
- }
action里面如上代码,自行填入处理,这样做增加了代码量但是维护起来无疑更方便,可以直接跳转,并对特殊指令自行拼接。
- static GG_GsmSendSta Gsm_SignRecHandleCallback(unsigned char *buf)
- {
- //uint8_t sta;
- char *p;
-
- switch(s_AT_SignSta.Step)
- {
- case AT:
- {
- if(NULL != (p = strstr( (char*)buf,"OK")))
- {
- //printf("1111");
- return WAIT;
- }
- else
- {
- return ERR;
- }
- break;
- }
- case ATEO:
- {
- if(NULL != (p = strstr( (char*)buf,"OK")))
- {
- //printf("1111");
- return WAIT;
- }
- else
- {
- return ERR;
- }
- break;
- }
之后在上述代码中修改如何判定字符返回是否正确,目前由于初次写,当前框架是ok都算对,后续可以改代码字符“ok”来匹配不同指令回复,因为指令回复和发送不同,回复的变数比较小,基本属于定值,除了接收数据协议帧,所以用了一个长的switch case
- //用户接口
- //信号,ccid,获取写入
- void Gsm_GSQSetData(uint8_t csq);
- uint8_t Gsm_GetCSQData(void);
- void Gsm_CCIDSetData(uint8_t *buf);
- uint8_t* Gsm_GetCCIDData(void);
- //联网后发送数据
- void Gsm_NetSendData(uint8_t *buf);
- //网络连接成功标志,自行放在at指令发送处理中
- void Gsm_NetWorkStaSetBit(void);
用户接口除了刚刚说的,也就这块要修改了,ccid和csq读取等接口,因为是初测,没有写这块函数处理,只开通的读取和写入的接口。
测试平台stm32f1,移植在原子基本例程
发送错误或者超时都会重发,五次后会重新发at(这个多次超时接口默认的重新开始,其他功能比如模块断电啥,可以自己从map跳转修改)
该框架原则将驱动和应用层分离。用户调用方便调用方法见本人git链接https://github.com/gglingyishu/AT_INSTRUCT
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。