第1章:AT指令基础

1.1 AT指令的起源——从拨号到万物互联

AT指令,全称是Attention指令。说白了,就是“注意,我要发命令了”。

这东西最早是干嘛用的?上世纪80年代,有个叫Hayes的公司,做了一款智能调制解调器。那时候电脑要上网,得先通过电话线拨号。怎么拨?总不能手动拿电话机拨吧?于是Hayes搞了一套指令集,让电脑通过串口发几个字符,就能控制Modem拨号、挂断、设置参数。

我记得第一次接触AT指令,是在大学实验室里调试一个老掉牙的56K Modem。当时觉得这东西太神奇了——发个“ATD12345678”,它就真的开始拨号了。嗯,那种感觉就像你对着空气喊了一声,然后有人回应了你。

后来GSM模块、GPRS模块、3G/4G模块,一直到现在的NB-IoT模块,都继承了这个传统。AT指令成了通信模块的“通用语言”。你想想看,不管你是哪家芯片厂,只要支持AT指令,开发者就能用同一套逻辑去控制它。这就是标准化的力量。

核心要点:AT指令起源于Hayes Modem,现在是物联网模块的标准控制接口。你发的每一条AT指令,本质上都是在跟模块“对话”。

1.2 AT指令的基本格式——别小看这几个字符

AT指令的格式,其实特别简单。但越是简单的东西,越容易出错。我在项目中见过太多人因为少写一个回车,或者多写一个空格,折腾了半天。

基本格式就一句话:AT + 命令 + 参数 + 回车换行

举个例子:

AT+CSQ

这条指令的意思是:查询信号质量。AT是前缀,CSQ是命令,没有参数。最后一定要加回车换行(\r\n)。

再比如:

AT+NBAND=5

这条指令的意思是:设置NB-IoT频段为Band 5。AT是前缀,NBAND是命令,=5是参数。

这里有几个细节,我特别想强调:

  • AT必须大写。小写at在某些模块上不识别,别问我怎么知道的——我曾经在产线上因为这个原因排查了整整一个下午。
  • 命令和参数之间不能有空格。比如“AT+CSQ”是对的,“AT+CSQ ”(多了一个空格)在某些模块上会报错。
  • 回车换行是必须的。模块靠这个来判断一条指令结束了。你发“AT+CSQ”不加回车,模块会一直等着,以为你还没说完。

个人习惯:我写代码的时候,会在每条AT指令后面显式加上“\r\n”,而不是依赖串口工具的自动换行。这样移植到不同平台时,不会因为换行符的问题出幺蛾子。

1.3 AT指令的分类——三大类,搞清楚就够用了

AT指令看起来很多,其实分类很清晰。我个人把它分成三大类:

1.3.1 测试指令(Test Command)

格式:AT+<命令>=?

作用是查询这个命令支持哪些参数范围。比如:

AT+NBAND=?

返回结果可能是:

+NBAND: (1,2,3,5,8,12,13,17,18,19,20,25,26,28,66,70,85)

告诉你这个模块支持哪些NB-IoT频段。我在选型的时候,经常先用这条指令看看模块到底支持哪些频段,免得被数据手册忽悠了。

1.3.2 查询指令(Read Command)

格式:AT+<命令>?

作用是查询当前参数值。比如:

AT+NBAND?

返回:

+NBAND: 5

告诉你当前工作在Band 5。

1.3.3 设置指令(Set Command)

格式:AT+<命令>=<参数>

作用是设置参数。比如:

AT+NBAND=8

把频段设为Band 8。

还有一种叫执行指令(Execute Command),就是不带参数的设置指令,比如前面说的AT+CSQ。它没有问号,也没有等号,直接执行一个动作。

类型 格式 示例 说明
测试指令 AT+<命令>=? AT+NBAND=? 查询参数范围
查询指令 AT+<命令>? AT+NBAND? 查询当前值
设置指令 AT+<命令>=<参数> AT+NBAND=8 设置参数
执行指令 AT+<命令> AT+CSQ 执行动作

注意:不是所有命令都支持这四种格式。有些命令只支持设置和执行,不支持查询。具体要看模块的AT指令手册。我曾经踩过这个坑——想查询某个参数,发了查询指令,结果模块返回ERROR。后来翻手册才发现,这个参数只能设置,不能读回。

1.4 AT指令的响应格式——学会看返回,才算会调

发指令只是第一步,看懂模块的回复才是真本事。

AT指令的响应格式,一般长这样:

AT+CSQ

+CSQ: 19,99

OK

或者:

AT+NBAND=8

OK

如果出错了:

AT+NBAND=99

ERROR

响应分为三部分:

  • 回显:模块会把收到的指令原样返回(如果开启了回显功能)。这就是为什么你发“AT+CSQ”,回复里第一行就是“AT+CSQ”。
  • 结果行:以“+<命令>:”开头,后面跟着返回的数据。比如“+CSQ: 19,99”。
  • 最终结果码:OK表示成功,ERROR表示失败。

还有一种情况,模块会主动上报信息,这叫URC(Unsolicited Result Code)。比如NB-IoT模块入网成功时,可能会主动发:

+CSCON: 1

告诉你它已经连接到网络了。这种消息不是你发指令问来的,是模块自己主动说的。调试的时候,URC经常被忽略,但恰恰是这些主动上报的信息,能帮你定位很多问题。

避坑指南:我曾经在一个项目中,发现模块偶尔会丢数据。排查了很久,最后发现是URC消息和指令响应混在一起了。我的解析程序只处理了“+...:”格式的响应,没处理URC。结果URC一来,解析就乱了。从那以后,我写AT指令解析器时,一定会单独处理URC消息。

嗯,AT指令的基础就这些。别觉得简单,这些基础的东西,在实际项目中反复出现。你把它吃透了,后面调试NB-IoT模块的时候,会顺手很多。