3. AT 指令入门:格式、常用指令与交互流程
做蜂窝模组抓包分析,AT 指令是绕不开的第一道门槛。说白了,AT 指令就是电脑跟模组对话的「通用语言」。你发一条指令,模组回一个响应,一来一回,就能控制模组做各种事情——查信号、看注册状态、连网络,全得靠它。
我刚开始接触 AT 指令时,觉得这东西太简单了,不就是发个字符串嘛。后来在项目里踩过几次坑才明白,AT 指令的格式、时序、响应解析,每个细节都可能让你抓狂。今天咱们就把这块彻底讲透。
3.1 AT 指令的基本格式
AT 指令的格式其实很固定。我总结了一个通用模板:
AT<命令名>[=参数1,参数2,...]<回车换行>
注意几个关键点:
- AT 前缀:每条指令必须以 "AT" 或 "at" 开头,大小写都可以。但千万别写成 "At" 或 "aT",模组不认。
- 命令名:紧跟在 AT 后面,比如 CSQ、CREG、CGATT。命令名不区分大小写。
- 等号与参数:如果指令需要参数,用等号连接。多个参数用逗号分隔。
- 结尾符:必须用回车换行(\r\n)结束。很多新手在这里翻车——只发了回车没发换行,模组没反应。
举个例子,查信号强度的指令:
AT+CSQ\r\n
模组收到后,会回复类似这样的内容:
+CSQ: 28,99
OK
嗯,这里要注意:模组的响应也以 \r\n 结尾。而且响应分两部分——数据行和结果码。数据行告诉你具体数值,结果码(OK 或 ERROR)表示指令执行成功还是失败。
3.2 三种指令类型
AT 指令按功能分三种类型。我习惯用一张表来区分它们:
| 类型 | 格式 | 作用 | 示例 |
|---|---|---|---|
| 测试指令 | AT+<命令名>=? | 查询命令支持的参数范围 | AT+CSQ=? |
| 查询指令 | AT+<命令名>? | 查询当前参数值 | AT+CSQ? |
| 设置指令 | AT+<命令名>=<参数> | 设置参数值 | AT+CGATT=1 |
我在项目中遇到过一个问题:用查询指令 AT+CSQ? 查信号,模组返回了 +CSQ: 99,99。我当时以为信号满格,后来才发现 99 表示「未知或不可检测」。所以你看,光会发指令还不够,还得懂每个返回值的含义。
3.3 三条最常用的 AT 指令
做抓包分析,有三条指令你几乎天天要用。我按使用频率排个序:
3.3.1 AT+CSQ —— 查信号强度
这条指令用来获取当前小区的信号质量。响应格式:
+CSQ: <rssi>,<ber>
两个参数的含义:
- rssi:接收信号强度指示,范围 0-31,数值越大信号越强。0 表示 -113 dBm 以下,31 表示 -51 dBm 以上。99 表示不可检测。
- ber:误码率,范围 0-7,99 表示不可检测。这个值在实际项目中参考意义不大,我一般只看 rssi。
3.3.2 AT+CREG —— 查网络注册状态
这条指令告诉你模组有没有成功注册到网络。响应格式:
+CREG: <n>,<stat>[,<lac>,<ci>]
关键看第二个参数 stat:
| stat 值 | 含义 |
|---|---|
| 0 | 未注册,模组当前不在搜索网络 |
| 1 | 已注册,本地网(正常状态) |
| 2 | 未注册,模组正在搜索网络 |
| 3 | 注册被拒绝 |
| 5 | 已注册,漫游状态 |
你想想看,如果 stat 返回 3,说明 SIM 卡被网络侧拒绝了。这时候查 AT+CSQ 信号再好也没用。我遇到过好几次这种情况,最后发现是 SIM 卡欠费了。
3.3.3 AT+CGATT —— 查 GPRS 附着状态
这条指令检查模组是否附着到 GPRS/PS 域。说白了,就是能不能走数据流量。响应格式:
+CGATT: <state>
state 为 1 表示已附着,0 表示未附着。如果 state 是 0,你发 AT+CGATT=1 可以手动触发附着。
3.4 AT 指令的交互流程
AT 指令的交互流程,说白了就是「一问一答」。但实际项目中,这个流程比想象中复杂。我画了一张流程图,帮你理清整个交互过程:
整个流程其实就五步:
- 主机发指令:MCU 或 PC 通过串口发送 AT 指令,必须以 \r\n 结尾。
- 模组接收并解析:模组收到指令后,先检查格式对不对。格式错了直接回 ERROR。
- 模组执行操作:比如查信号、读注册状态、附着网络。这个步骤可能需要几毫秒到几秒。
- 模组返回响应:先返回数据行(如果有),再返回结果码(OK 或 ERROR)。
- 主机解析响应:主机收到响应后,判断结果码。如果是 OK,继续下一条指令;如果是 ERROR,需要重试或做异常处理。
核心要点:AT 指令交互是严格同步的。发一条,等一条,收到响应后才能发下一条。千万别一口气发多条指令,模组会乱掉。我见过有人用 for 循环连续发 10 条 AT,结果模组只响应了前两条,后面全丢了。
3.5 实际项目中的交互时序
在真实项目中,AT 指令的交互时序比上面那张图要复杂。我拿一个典型的模组初始化流程举例:
// 第一步:检查模组是否正常
发:AT\r\n
收:OK
// 第二步:关闭回显(可选)
发:ATE0\r\n
收:OK
// 第三步:查信号强度
发:AT+CSQ\r\n
收:+CSQ: 28,99
OK
// 第四步:查网络注册状态
发:AT+CREG?\r\n
收:+CREG: 0,1
OK
// 第五步:附着 GPRS
发:AT+CGATT=1\r\n
收:OK
// 等待 5 秒
发:AT+CGATT?\r\n
收:+CGATT: 1
OK
你看,每一步之间都有明确的先后顺序。而且有些指令(比如 AT+CGATT=1)执行时间较长,必须等模组返回 OK 后才能继续。我习惯在代码里加超时机制——如果 10 秒内没收到响应,就认为指令超时,重新发送。
3.6 常见问题与排查思路
做 AT 指令调试,最常遇到三个问题:
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 发 AT 没响应 | 串口参数不对、模组没上电、接线错误 | 检查波特率(常用 115200/9600)、检查电源、用示波器看 TX/RX 波形 |
| 返回 ERROR | 指令格式错误、参数超出范围、模组不支持该指令 | 检查指令拼写、用 AT+<命令名>=? 查参数范围 |
| 返回 OK 但数据不对 | 模组状态异常、SIM 卡问题、网络问题 | 依次查 AT+CSQ、AT+CREG、AT+CGATT,定位到具体哪一步异常 |