AT(Attention)指令是由 Dennis Hayes 发明的,所以也称为 Hayes command set
。AT 指令最初是用来指导 modem 工作的,后面随着技术的发展,低速 modem 已经退出了市场,但 AT 指令却不断发展,并且在今天 AT 指令依旧扮演这非常重要的角色。
虽然在 PC 端、手机上已经没有了 AT 的使用,但其却在嵌入式行业里各类联网模块中发挥着重要的作用,而且不仅仅只应用在蜂窝模块,还应用到了 WiFi、BLE 等模块中。
1. 相关标准
随着技术的发展,目前 AT 指令发展过程中形成两个重要标准:
- V.250:该标准于 1995 年建立,1998 年重命名为 V.250
- ETSI GSM 07.07(3GPP TS 27.007):用于控制 GSM modem 的 AT 指令集
GSM 07.07 是基于 V.250 标准的。是目前最新的 AT 标准。
当下 AT 指令的应用
目前的 AT 指令着重应用在蜂窝模块、WiFi 模块、BLE 模块中,目的是为了简化嵌入式设备联网的复杂度。
AT 标准定义了 AT 命令的格式本身,比如命令以 AT 为前缀开头,以 或者 结尾,这被现有的 AT 模块所延用。
但是,由于每个厂家的模块不一样,实现的功能不一样,导致每个 AT 模块厂家有自己的一套私有的 AT 命令集,每一个 AT 模块厂家实现的 AT 指令集解析器也不一样(解析器实现的 AT 标准功能也参差不齐)。
2. AT 模块的应用框图
既然是指令集,那么必然会有指令集的解析处理,通常,我们把 AT 模块端的解析处理程序称为 AT Server,而将控制 AT 模块的处理器端的解析处理程序称为 AT Client。由 AT Client 发起命令请求,AT Server 回应处理结果。另外 AT Server 通过 URC(Unsolicited result code) 来主动给 AT Client 发送数据。
应用框图如下所示:
3. 一些约定
AT 命令的常用格式:
AT+CMD=<xxx>[,<xxx>,<xxx>]
AT 指令以 AT
开始,以 \r
或者 \r\n
结尾,参数之间使用 ,
隔开,字符串参数使用双引号 ""
包裹,整形参数不适用双引号。
<CR>
:回车符<LF>
:换行符<xxx>
尖括号中的名称xxx
在 AT 里是一个语法元素,要求必须指定。尖括号本身不会出现在命令行里。[xxx]
中括号中的名称xxx
在 AT 里是一个语法元素,表示可选择指定。中括号本身不出现在命令行里。
4. 四类 AT 命令
- Test 命令:
AT+<x>=?
测试指令类似于命令行里的help
指令,用于提供该命令的使用信息,以及命令参数的取值范围。 - Read 命令:
AT+<x>?
用于查询该指令对应功能的当前值。 - Set 命令:
AT+<x>=<...>
设置用户指定的参数到对应的功能里。 - Execute 命令:
AT+<x>
执行相关操作。 \r\nOK\r\n
如果 AT 指令被 AT Server 识别,并正确执行,则返回该结果。
“ 标准中的 V1 模式下响应结果代码的方式。V0 模式下返回0\r
。
”\r\nERROR\r\n
“ 标准中的 V1 模式下响应结果代码的方式。V0 模式下返回4\r
。
”
5. 数据模式与指令模式
在收到 +++
,并且接下来 1s 内未收到其他数据的话,将从数据模式切换到指令模式。
数据模式,可以透传数据,client 发什么,server 就原封不动发出去。指令模式时,AT Server 需要解析 AT 指令,并作出响应。
6. 乐鑫中数据透传发送与退出透传发送
- 模块透传发送数据
首先设置数传模式为透传模式,指令AT+CIPMODE=1
。1:透传模式;0:普通模式。他们的主要区别是在透传模式可以在AT+CIPSEND
指令后一直发送数据(直到退出透传发送),而普通模式下每次发送数据必须使用AT+CIPSEND=x
来指定数据长度。
AT+CIPMODE=1
OK
AT+CIPSEND
OK
>
这个时候就可以发送数据直达模块了。 - 模块退出透传发送
发送+++
后停顿 1 秒。使用串口工具一次性发送+++
而不是手动一个个发送,否则会导致误检测成数据。
这是 AT 指令的一个标准约定。
如果此时想切换成 普通数传模式,发送AT+CIPMODE=0
指令。
7. 少有人关注的 AT 解析器
互联网上很多 xxx AT 指令使用教程,为何少有人关注 AT 解析器呢?
情况是这样的,绝大部分开发者是拿 AT 固件来开发产品的,只有很少一部分人是开发 AT 固件的。AT 固件通常是由芯片原厂、模组厂商来提供的,并且大多模组厂商也仅基于芯片原厂提供的 AT 解析器自定义 AT 指令。所以设计 AT 解析器的人就更少了,由于芯片原厂通常又不会提供 SDK 源码到互联网上,因此也基本上看不到 AT 解析器分析的文章。所以,互联网上关于 AT 的文章大都是某某模块都 AT 指令如何使用、怎么使用 MCU 控制 AT 指令模块。
总结:用 AT 固件都多,开发 AT 固件的少,设计 AT 解析器的人更少。
7.1 AT 指令共性的内容
- 遵循 AT 规范,AT 开头,CRLF 结尾(考虑到有些平台只用 LF 的情况,CRLF 结尾还需要容错);
- 有五类 AT 指令(TEST, GET, SET, EXEC),这里不带加号算作是 basic 指令;
- 字符串类型使用双引号("string")括起来;
- 整数类型不实使用双引号;
- 特殊字符需要转译;
- 等号后面必须有一个参数(当然你的解析器也可以容忍等号后面无参数,作为默认参数填充,这样的话跟执行命令又有什么不同呢);
- 支持省略参数。
以上这些都是需要基于 AT 解析器实现。
7.2 AT 指令差异的内容
- 参数数量不定
- 参数类型不定
- 是否有 省略参数
- 参数内容不同
- 是否使用来非 ascii 文本
- 是否使用来特殊符号
- 各种可能性的 AT 指令格式错误(人为原因)
- 是否有需要 转译 的字符,转译规则是怎么样的
由于这些都是跟用户输入紧密相关的,解析器事先并不知道,要想解析这些情况下的文本,我们需要先定好规则,告诉解析器支持什么、不支持什么、特殊特性如何支持等,然后用户按照既定的规则输入正确的指令,同时解析器也应该能检测到错误格式的指令并报告错误。
以上 4 条里,最麻烦的就是第四条——用户可能使用任何可打印文本,另外最复杂的还是处理 待转译的字符。
7.3 转译字符语法
乐鑫给出里下面几个需要转译的字符:
- 反斜杠本身
\
,转译用法\\
- 逗号
,
,转译用法\,
- 双引号
"
,转译用法\"
\<any>
,意思是使用\
后面的所有字符<any>
替代这里的\
用 AT+CWSAP=<ssid>,<pwd>,<channel>,<ecn>
指令举例,改指令用于启动一个 AP 热点,举例如下:
AT+CWJAP="ssid_\\\"\,\"\<any>\<\"\,\\\123中文>", "12345678",6,0
上面这条指令会启动一个 AP 热点,ssid 名称将是 ssid_\","<any><",\123中文>
,密码是 12345678
,信道是 6,加密方式是 open。有硬件条件的用户可以验证下。
7.4 指令和数据混合传输
除了对特殊格式的 AT 指令解析外,还有一个难点,就是使用 AT 串口进行数据传输(后面简称数传)。AT 指令模块串口的另外一端通常连接着一个 MCU,MCU 通过 AT 串口发送数据给 Wi-Fi 模块,Wi-Fi 模块再发送到网络上;Wi-Fi 模块收到数据后,也是通过 AT 串口发送数据到 MCU。通常,还不仅仅存在一路数据传输,还会有多路数据传输(比如两路 TCP),这个时候怎么管控他们使用 AT 串口呢,以及什么时候发送数据,又什么时候发送 AT 指令呢?
在 MCU 通过 AT 串口给 Wi-Fi 模块发送数据的时候,乐鑫有两种数传模式:normal 模式 和 passthrough 透传模式。透传模式只支持单个连接。
- 在 normal 模式下,MCU 需要先告诉对端 Wi-Fi 模块我要发多少数据,然后再发送数据;
在 normal 模式下 MCU 使用AT+CIPSEND=<len>
指令,告诉 Wi-Fi 模块我要发 len 字节数据,请进入 数据传输模式,我这个指令后就发数据了。 - 在 透传 模式下,每 20ms 或者每 2048 字节发送一次,哪个方式先到用哪个方式。
在透传模式下 MCU 使用AT+CIPSEND
执行指令,告诉 Wi-Fi 模块我要发数据了,请进入 数据透传模式,我这个指令后就发数据了。
AT 标准规定从数据透传模式切换到 AT 指令模式需要单独发送一包+++
的数据,并在紧接着的 1s 内不发送任何内容,这样 AT 解析器就会从数据透传模式切换到 AT 指令模式