3、AT指令集核心:常用AT指令详解与超时处理

AT指令,说白了就是咱们工程师跟模组对话的“黑话”。模组能不能上网、信号好不好、有没有注册上网络,全得靠这几条指令来问。我刚开始做蜂窝项目那会儿,总觉得AT指令就是发几条字符串,没啥技术含量。直到有一次产品在客户现场死活连不上网,我拿着串口工具一条一条地试,才发现自己对这几个指令的理解太浅了。

今天咱们就把最常用的四条指令掰开揉碎讲清楚。你想想看,这四条指令搞明白了,模组80%的网络状态问题你都能自己搞定。

3.1 AT+CSQ:信号质量的“体温计”

这条指令,我习惯叫它“信号体温计”。你发一条AT+CSQ,模组就会告诉你当前的信号强度。

AT+CSQ
+CSQ: 19,99

OK

返回的格式是+CSQ: <rssi>, <ber>。第一个值是接收信号强度指示(RSSI),范围0-31,数值越大信号越强。第二个值是误码率(BER),99表示不报告。

RSSI值对照表(我常用的判断标准)

RSSI值 信号强度 实际体验
0-9 极差 基本没法用,掉线频繁
10-14 弱 能连上,但速率不稳定
15-19 中等 日常可用,大部分场景够用
20-25 良好 速率稳定,体验不错
26-31 极好 信号满格,接近理论速率
99 无效 模组没检测到信号,检查天线

我的经验:RSSI值低于10的时候,别急着怀疑模组坏了。先看看天线有没有拧紧,或者换个位置试试。我在一个工厂项目里遇到过,RSSI一直是0,折腾了半天发现是天线座虚焊了。

3.2 AT+CREG:网络注册的“身份证”

信号好不代表能上网。你得确认模组有没有注册到运营商的网络。这时候就用AT+CREG。

AT+CREG?
+CREG: 0,1

OK

返回格式+CREG: <n>, <stat>。n是设置,一般用0或1。stat才是关键:

stat值 含义 说明
0 未注册 模组正在找网,或者根本找不到
1 已注册,本地网 正常状态,可以上网
2 未注册,正在搜索 模组在努力找网,等一会儿再查
3 注册被拒绝 运营商不让你入网,检查SIM卡和资费
4 未知 一般不会出现,出现了就重启模组
5 已注册,漫游 在外地或者用了别家运营商的信号

注意:stat=3(注册被拒绝)是个大坑。我曾经有个客户,SIM卡插上去一直返回3,换了三张卡都不行。最后发现是SIM卡的APN没开通物联网业务。所以遇到stat=3,先找运营商确认卡的状态。

3.3 AT+CGATT:PS域的“开关”

注册上网络了,但你还得确认PS域(分组交换域)是不是附着上了。说白了,就是模组有没有准备好走数据流量。

AT+CGATT?
+CGATT: 1

OK

返回1表示已附着,0表示未附着。如果返回0,就算信号再好、注册状态再正常,你也发不了数据。

为什么会这样?我遇到过一种情况:模组刚上电,CSQ显示20,CREG也返回1,但CGATT就是0。等了大概10秒钟再查,变成1了。嗯,这里要注意——模组启动有个过程,别一上电就急着发数据。

建议:在代码里加一个循环,每隔2秒查一次CGATT,直到返回1或者超时。超时时间我一般设30秒,够用了。

3.4 AT+CGDCONT:PDP上下文的“配置单”

最后一步,配置PDP上下文。你可以把它理解成模组上网的“配置单”——用什么协议、连哪个APN、需不需要用户名密码。

AT+CGDCONT=1,"IP","CMNET"

OK

参数说明:

  • cid(1):上下文ID,一般用1就行
  • PDP类型("IP"):IPv4就用IP,IPv4/v6双栈用IPV4V6
  • APN("CMNET"):接入点名称,移动是CMNET,联通是3GNET,电信是CTNET

查一下当前配置:

AT+CGDCONT?
+CGDCONT: 1,"IP","CMNET","0.0.0.0",0,0,0,0

OK

关键点:APN必须跟SIM卡匹配。我见过有人用移动的卡配了联通的APN,结果CGATT死活上不去。APN错了,模组就不知道从哪个门出去上网。

3.5 指令超时处理:别让模组“卡死”你

AT指令不是发出去就一定有回应的。模组有时候忙不过来,或者信号不好,指令就卡住了。如果不做超时处理,你的程序可能永远等在那条指令上。

我个人的做法是这样的:

  1. 每条指令都设超时:普通指令设3秒,网络相关指令(如AT+CGATT)设10-15秒
  2. 超时后先发“中断”:发一个0x1B(ESC字符),让模组退出当前状态
  3. 再发AT测试:发一条AT,看模组还活着没
  4. 连续超时则重启:如果3次AT都没回应,直接硬件复位
// 伪代码示例
bool sendATCommand(const char* cmd, int timeout_ms) {
    // 清空接收缓冲区
    // 发送指令
    // 等待响应,同时计时
    while (time_elapsed < timeout_ms) {
        if (收到 "OK" 或 "ERROR") {
            return true;
        }
        delay(100);
    }
    // 超时处理
    sendByte(0x1B);  // 发送ESC中断
    delay(500);
    // 发AT测试模组状态
    if (!sendATCommand("AT", 2000)) {
        // 模组可能挂了,执行硬件复位
        hardwareReset();
    }
    return false;
}

血的教训:有一次我在做远程升级功能,模组正在下载固件,这时候我发了一条AT+CSQ。结果模组没理我,程序就卡在等待响应的循环里了。下载任务也断了,升级失败。从那以后,所有AT指令我都加了超时保护。

3.6 知识体系总览

下面这张图,把四条指令的关系和排查流程串起来了。你照着这个顺序查,90%的网络问题都能定位到。

LTE网络适配 - AT指令排查流程 模组上电启动 步骤1:AT+CSQ 检查信号强度(RSSI) RSSI ≥ 10 ? 否 检查天线/SIM 是 步骤2:AT+CREG? 检查网络注册状态 stat = 1 或 5 ? 否 检查SIM/运营商 步骤3:AT+CGATT? 检查PS域附着状态 步骤4:AT+CGDCONT 排查要点 1. 按顺序排查,不要跳步 2. 每条指令设超时保护

这张图从左到右、从上到下,就是标准的排查流程。先看信号,再看注册,然后确认PS域附着,最后配好APN。每一步都卡住了,就回到上一步找原因。

最后说一句:AT指令看着简单,但实际项目里坑不少。我建议你在开发阶段就把这些指令的返回值和超时处理都做成日志,出了问题翻日志比现场抓串口快得多。