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

2020-01-12 17:26发布

前几天用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
复制代码
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
39条回答
fancyboy
1楼-- · 2020-01-12 22:33
再上一张无线串口图,因为使用了FIFO缓冲区,发送也做了优化,现在串口230400波特率全速传文件在ACK模式下不丢包..
调试好帮手......

IMG_20141009_095511.jpg (1.12 MB, 下载次数: 1)

下载附件

2014-10-9 10:07 上传

xiatao1800
2楼-- · 2020-01-13 02:02
 精彩回答 2  元偷偷看……
richards
3楼-- · 2020-01-13 05:07
楼主 不错哦 还自己腐蚀板子  对比一下我好懒啊  借鉴了 at命令解析
Puppey
4楼-- · 2020-01-13 10:24
支持一波。之前都是判断简单帧头的方法
size327948964
5楼-- · 2020-01-13 10:29
学习一下
oooios
6楼-- · 2020-01-13 15:25
谢谢分享学习

一周热门 更多>