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。
我的经验:rssi 值在 20 以上(约 -80 dBm)才算可用。如果低于 15,抓包时丢包率会明显上升。我曾经在一个地下室项目里,rssi 只有 8,抓包数据基本没法用,最后加了外置天线才解决。

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 可以手动触发附着。

注意:AT+CGATT=1 执行需要时间,通常 3-10 秒。我曾经在代码里发了这条指令后立刻发 AT+CGATT? 查询,结果还是 0。后来加了 5 秒延时才稳定。所以发完设置指令后,一定要等模组返回 OK,再等几秒再查。

3.4 AT 指令的交互流程

AT 指令的交互流程,说白了就是「一问一答」。但实际项目中,这个流程比想象中复杂。我画了一张流程图,帮你理清整个交互过程:

AT 指令交互流程图 AT 指令交互流程 主机(MCU/PC) 蜂窝模组 AT+CSQ\r\n 模组解析指令、执行操作 +CSQ: 28,99 OK 主机解析响应数据 OK? 是 继续下一条指令 否 重试或异常处理

整个流程其实就五步:

  1. 主机发指令:MCU 或 PC 通过串口发送 AT 指令,必须以 \r\n 结尾。
  2. 模组接收并解析:模组收到指令后,先检查格式对不对。格式错了直接回 ERROR。
  3. 模组执行操作:比如查信号、读注册状态、附着网络。这个步骤可能需要几毫秒到几秒。
  4. 模组返回响应:先返回数据行(如果有),再返回结果码(OK 或 ERROR)。
  5. 主机解析响应:主机收到响应后,判断结果码。如果是 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 秒内没收到响应,就认为指令超时,重新发送。

避坑指南:我曾经在项目里犯过一个低级错误——发完 AT+CGATT=1 后,没等 OK 就直接发 AT+CGATT? 查询。结果查到的 state 还是 0。后来加了 3 秒延时才稳定。记住:设置指令和查询指令之间,一定要留足时间。

3.6 常见问题与排查思路

做 AT 指令调试,最常遇到三个问题:

现象 可能原因 排查方法
发 AT 没响应 串口参数不对、模组没上电、接线错误 检查波特率(常用 115200/9600)、检查电源、用示波器看 TX/RX 波形
返回 ERROR 指令格式错误、参数超出范围、模组不支持该指令 检查指令拼写、用 AT+<命令名>=? 查参数范围
返回 OK 但数据不对 模组状态异常、SIM 卡问题、网络问题 依次查 AT+CSQ、AT+CREG、AT+CGATT,定位到具体哪一步异常