搜索
bottom↓
回复: 40

自定义AT命令解析引擎-奉献全部代码

  [复制链接]

出0入0汤圆

发表于 2014-10-9 09:50:51 | 显示全部楼层 |阅读模式
前几天用NRF24L01+做了个无线串口,因为需要用命令行来改变波特率,频道.有无ACK,地址...谢了这个AT命令解析引擎,使用时直接修改结构体数组中的命令,命令长度,数据长度,指向函数即可.
命令分析:
完整的指令可以表示为
AT+XXX=DDD
其中AT+为命令行开头
XXX=为命令
DDD为数据
函数中注释还算清晰,本人新手,大神请拍砖

ATCMD.C
  1. /****************************************
  2. AT指令解析引擎
  3. at_scan函数用于监测AT开头,并存储一条AT数据,此例放到串口接收中断
  4. at_cmp函数用于解析存储的AT数组,并执行相应命令
  5. 结构体部分位AT指令描述以及函数的对应关系
  6. 制作人:Fancy
  7. QQ:652774317
  8. ******************************************/
  9. #include        "ATCMD.H"


  10. code        unsigned char        at_head[AT_HEAD_LEN]={'A','T','+'};        //AT指令开头
  11. unsigned char        addr_cmp=0;                //AT指令开头校验位置
  12. unsigned char        at_addr=0;                //AT缓冲区最后一个数据位置
  13. bit        at_head_flag=0;                        //检测AT指令开头标志位
  14. unsigned char at_buf[AT_BUF_MAX]={0};


  15. code        AT_STRUCT        at_array[AT_CMD_COUNT]=
  16. {
  17.         {"CH=",3,3,&AT_CH},
  18.         {"ACK=",4,2,&AT_ACK},
  19.         {"?=",2,0,&AT_SEND}
  20. };
  21. //监测AT开头并将AT命令存储到缓冲区
  22. void        at_scan(void)
  23. {
  24.                 if(at_head_flag)
  25.                         if(at_addr<AT_BUF_MAX)                at_buf[at_addr++]=SBUF;
  26.                        
  27.                         if(SBUF==at_head[addr_cmp])                                addr_cmp++;
  28.                         else        addr_cmp=0;
  29.                         if(addr_cmp==AT_HEAD_LEN)
  30.                                 {
  31.                                         at_head_flag=1;
  32.                                         addr_cmp=0;
  33.                                         at_addr=0;
  34.                                 }
  35.                        
  36. }                       
  37. //比较两个字符串cont字节,相同为1,否则返回0                       
  38. unsigned char at_cmp(unsigned char *s,unsigned char count)  
  39. {
  40.     unsigned char res;
  41.     for(res=0;res<count;res++)
  42.                 {
  43.                         if(*(s+res)        !=        at_buf[res])                return        0;
  44.                 }
  45.                 return        1;  
  46. }
  47. //AT指令解析后并执行相应函数
  48. void        AT_CMD(void)
  49. {
  50.         unsigned char        i;
  51.         if(at_head_flag)
  52.                 {
  53.                 for(i=0;i<AT_CMD_COUNT;i++)
  54.                         {
  55.                                 if(at_addr        >=        (at_array[i].cmd_len+at_array[i].data_len))
  56.                                 {
  57.                                 if(at_cmp(at_array[i].s,at_array[i].cmd_len))
  58.                                         {
  59.                                                 at_head_flag=0;
  60.                                                 (*at_array[i].Subs)();
  61.                                         }
  62.                                 }
  63.                         }
  64.                 }
  65. }

  66. void        AT_CH(void)
  67. {
  68.         unsigned char        chanel;
  69.         unsigned char        point;
  70.         point=at_array[0].cmd_len;
  71.         chanel=(at_buf[point]-0x30)*100        +        (at_buf[point+1]-0x30)*10        +        (at_buf[point+2]-0x30);
  72.         NRF24L01_Change_Ch(chanel);
  73. }

  74. void        AT_ACK(void)
  75. {
  76.         unsigned char        point;
  77.         point=at_array[1].cmd_len;
  78.         if(at_buf[point]        ==        '1')        NRF24L01_FLAG |= NRF24L01_AUTO_ACK;
  79.         if(at_buf[point]        ==        '0')        NRF24L01_FLAG &= ~NRF24L01_AUTO_ACK;
  80. }

  81. void        AT_SEND(void)
  82. {
  83.         if(NRF24L01_FLAG & NRF24L01_AUTO_ACK)                SendString("ACK");
  84.         else        SendString("NOACK");
  85.         SendString("CH=");
  86.         SendData(RF_CH/100+0x30);
  87.         SendData(RF_CH%100/10+0x30);
  88.         SendData(RF_CH%10+0x30);
  89. }
复制代码


ATCMD.H
  1. /****************************************
  2. AT指令解析引擎
  3. at_scan函数用于监测AT开头,并存储一条AT数据,此例放到串口接收中断
  4. at_cmp函数用于解析存储的AT数组,并执行相应命令
  5. 结构体部分位AT指令描述以及函数的对应关系
  6. 制作人:Fancy
  7. QQ:652774317
  8. ******************************************/
  9. #ifndef __ATCMD_H_
  10. #define __ATCMD_H_

  11. #include        <STC/STC15F2K60S2.H>
  12. #include "uart.h"
  13. #include        "NRF24L01.H"

  14. #define        AT_BUF_MAX                7                                        //AT指令缓冲区空间,不包含AT开头
  15. #define        AT_HEAD_LEN                3                                        //AT指令头长度
  16. #define        AT_CMD_COUNT        3                                //AT指令总数
  17. /************************
  18. AT+CMD=XX
  19. AT+        指令开头
  20. CMD=        命令
  21. XX                数据
  22. *************************/
  23. typedef        struct
  24. {
  25.         unsigned char        *s;                //AT命令行
  26.         unsigned        char        cmd_len;        //命令长度,不含AT开头
  27.         unsigned        char        data_len;        //数据长度
  28.         unsigned char         (*Subs)();        //命令对应函数
  29. }AT_STRUCT;

  30. extern        code        unsigned char        at_head[AT_HEAD_LEN];        //AT指令开头
  31. extern        unsigned char        addr_cmp;                //AT指令开头校验位置
  32. extern        unsigned char        at_addr;                //AT缓冲区最后一个数据位置
  33. extern        bit        at_head_flag;                        //检测AT指令开头标志位
  34. extern        unsigned char at_buf[AT_BUF_MAX];
  35. extern        code        AT_STRUCT        at_array[AT_CMD_COUNT];
  36. //监测AT开头并将AT命令存储到缓冲区
  37. extern        void        at_scan(void);
  38. //比较两个字符串cont字节,相同为1,否则返回0                       
  39. extern        unsigned char at_cmp(unsigned char *s,unsigned char count);  
  40. //AT指令解析后并执行相应函数
  41. extern        void        AT_CMD(void);
  42. extern        void        AT_CH(void);
  43. extern        void        AT_ACK(void);
  44. extern        void        AT_SEND(void);
  45. #endif
复制代码

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2014-10-9 10:07:26 | 显示全部楼层
再上一张无线串口图,因为使用了FIFO缓冲区,发送也做了优化,现在串口230400波特率全速传文件在ACK模式下不丢包..
调试好帮手......

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-10-9 10:27:08 | 显示全部楼层
正需要了解AT命令,谢谢!再想问下通讯距离多远啊?

出0入0汤圆

发表于 2014-10-9 10:27:18 | 显示全部楼层
楼主 不错哦 还自己腐蚀板子  对比一下我好懒啊  借鉴了 at命令解析

出0入0汤圆

发表于 2014-10-9 10:27:22 | 显示全部楼层
支持一波。之前都是判断简单帧头的方法

出0入0汤圆

发表于 2014-10-9 10:29:41 | 显示全部楼层
学习一下

出0入0汤圆

发表于 2014-10-9 10:31:22 | 显示全部楼层
谢谢分享学习

出0入0汤圆

发表于 2014-10-9 10:56:51 | 显示全部楼层
楼主牛逼,顶顶。。

出0入0汤圆

 楼主| 发表于 2014-10-9 11:02:19 | 显示全部楼层
xiatao1800 发表于 2014-10-9 10:27
正需要了解AT命令,谢谢!再想问下通讯距离多远啊?


不带天线三四十米,带天线百米无压力,250KBPS不穿墙

出0入0汤圆

发表于 2014-10-9 11:36:16 | 显示全部楼层

出0入4汤圆

发表于 2014-10-9 16:57:05 | 显示全部楼层
谢谢奉献 make

出0入0汤圆

发表于 2014-10-9 17:56:13 | 显示全部楼层
挺厉害。标记一下。

出0入0汤圆

发表于 2014-10-9 18:46:31 来自手机 | 显示全部楼层
楼主真棒,谢谢

出0入0汤圆

发表于 2014-10-9 20:45:59 | 显示全部楼层
收藏一下,很不错

出0入0汤圆

发表于 2014-10-9 22:45:27 | 显示全部楼层
楼主好东东,坐等开源      

出10入0汤圆

发表于 2014-10-10 00:36:04 | 显示全部楼层
能做到“串口230400波特率全速传文件”不丢数据??
mark!!!

出0入0汤圆

发表于 2014-10-10 08:32:32 | 显示全部楼层
好东西,谢谢分楼主享

出0入0汤圆

发表于 2014-10-10 08:56:59 | 显示全部楼层
好东东,mark

出0入0汤圆

发表于 2014-10-10 09:14:20 | 显示全部楼层
mark. 谢谢分享~

出0入0汤圆

发表于 2014-10-10 09:17:42 来自手机 | 显示全部楼层
收藏,以前搞GSM模块时被AT弄伤了

出0入0汤圆

发表于 2014-10-10 09:33:10 | 显示全部楼层
mark. 谢谢分享~

出0入0汤圆

 楼主| 发表于 2014-10-10 10:27:27 | 显示全部楼层
dgtg 发表于 2014-10-10 00:36
能做到“串口230400波特率全速传文件”不丢数据??
mark!!!

呵呵,这是我测试过的,不穿墙30m内不会丢...230400全速

出0入0汤圆

发表于 2014-10-10 10:57:28 | 显示全部楼层
了解了,3KS

出0入0汤圆

发表于 2014-10-10 11:33:17 | 显示全部楼层
好东西!

出0入0汤圆

发表于 2014-10-10 11:57:09 | 显示全部楼层
make一下,有需要的时候来,感谢楼主的分享。

出0入0汤圆

发表于 2014-10-10 12:32:09 | 显示全部楼层
支持一下~

出10入0汤圆

发表于 2014-10-10 12:58:32 | 显示全部楼层
fancyboy 发表于 2014-10-10 10:27
呵呵,这是我测试过的,不穿墙30m内不会丢...230400全速

是通过什么方式判断收到的数据是否正确呢?
收到的数据保存起来比较? 还是判断接收到的数据个数?

出0入0汤圆

发表于 2014-10-10 14:45:11 | 显示全部楼层
之间搞过GSM模块,用的就是这个AT指令集

出0入0汤圆

发表于 2014-10-10 15:13:42 | 显示全部楼层
学习了 谢谢

出0入0汤圆

发表于 2014-10-10 15:44:36 | 显示全部楼层
学习一下

出0入0汤圆

 楼主| 发表于 2014-10-10 23:03:36 来自手机 | 显示全部楼层
dgtg 发表于 2014-10-10 12:58
是通过什么方式判断收到的数据是否正确呢?
收到的数据保存起来比较? 还是判断接收到的数据个数? ...

用串口调试发送文件,然后md5检验,通信本身都是有crc检验的,数据量大小一致的话,出错可能性很小。

出30入54汤圆

发表于 2014-10-10 23:23:37 | 显示全部楼层
这个绝壁要顶啊啊啊

出0入0汤圆

发表于 2014-10-11 00:49:40 | 显示全部楼层
学习一下

出0入0汤圆

发表于 2014-10-13 08:58:38 | 显示全部楼层
学习一下, 之前一直在网上找ascii码命令的解析,真是个好东西。

出0入0汤圆

发表于 2019-2-20 14:15:33 | 显示全部楼层
多谢分享,谢谢!

出0入0汤圆

发表于 2019-2-20 15:02:27 来自手机 | 显示全部楼层
多谢分享,谢谢

出0入0汤圆

发表于 2019-2-20 15:06:53 | 显示全部楼层
这个不错哦。

出0入0汤圆

发表于 2019-7-5 20:54:35 | 显示全部楼层
学习AT命令的好文章,学习了

出0入0汤圆

发表于 2019-7-18 17:56:46 | 显示全部楼层
学习学习

出0入0汤圆

发表于 2021-1-24 14:38:48 | 显示全部楼层
多谢分享,谢谢
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-21 01:54

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表