单片机发送AT命令是嵌入式开发中常见的通信方式,主要用于与模块(如GSM/GPRS、WiFi、蓝牙等)进行交互,实现数据传输、网络连接等功能,AT命令集是一种标准的指令集,通过串口(UART)等接口发送,模块接收到指令后会返回响应信息,开发者通过解析响应来判断指令执行结果,以下从硬件连接、指令格式、发送流程、常见问题及代码示例等方面详细说明。

硬件连接与基础准备
单片机与模块之间的通信通常采用串口(UART),连接时需注意引脚对应关系:单片机的TX引脚连接模块的RX引脚,单片机的RX引脚连接模块的TX引脚,GND引脚共地,部分模块还需要提供电源(如VCC)和复位(RESET)引脚,确保电压匹配(如模块为3.3V时,单片机IO口需电平转换),硬件连接完成后,需通过串口调试助手(如PuTTY、SSCOM)测试模块是否能正常响应AT指令,确认模块工作状态正常。
AT命令基础格式
AT命令以“AT”或“AT+”开头,以回车符(\r,0x0D)部分指令可能需要换行符(\n,0x0A),指令不区分大小写,但需严格遵循语法规则。
- 测试指令:AT\r\n(模块返回OK)
- 查询指令:AT+CMD?\r\n(返回参数信息)
- 设置指令:AT+CMD=参数\r\n(设置成功返回OK,失败返回ERROR)
部分指令支持扩展参数,如AT+CSQ用于信号质量查询,返回格式为+CSQ:
单片机发送AT命令的流程
-
初始化串口:配置单片机串口参数(波特率、数据位、停止位、校验位),需与模块设置一致(常见波特率9600、115200),STM32 HAL库初始化代码:
(图片来源网络,侵删)UART_HandleTypeDef huart1; huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; HAL_UART_Init(&huart1);
-
发送指令函数:封装串口发送函数,确保指令以正确格式发送。
void send_AT_command(char *cmd) { HAL_UART_Transmit(&huart1, (uint8_t *)cmd, strlen(cmd), HAL_MAX_DELAY); }发送“AT”指令时,需传入字符串“AT\r\n”。
-
接收响应数据:通过串口中断或DMA接收模块返回的数据,需设置超时机制(如5秒),避免程序卡死。
uint8_t rx_buffer[256]; uint16_t rx_len = 0; HAL_UART_Receive_IT(&huart1, rx_buffer, 1); // 启动中断接收
在中断服务函数中累积接收数据,直到检测到回车符或超时。
(图片来源网络,侵删) -
解析响应结果:根据模块返回的字符串判断指令执行状态。
- 响应“OK”:指令成功
- 响应“ERROR”:指令失败
- 响应“+CMD: ...”:查询结果
常见AT指令及场景应用
以下为部分常用AT指令及其功能说明:
| 指令 | 功能描述 | 示例响应 |
|---|---|---|
| AT | 测试模块连接 | OK |
| AT+CSQ | 查询信号质量 | +CSQ: 15,0 |
| AT+CREG? | 查询网络注册状态 | +CREG: 1,1 (已注册) |
| AT+CMGF=1 | 设置短信为文本模式 | OK |
| AT+CMGS=13800138000 | 发送短信(需输入短信内容后Ctrl+Z) | > ... (等待输入) +CMGS: xx OK |
发送短信的完整流程:
- 设置短信模式:AT+CMGF=1\r\n
- 输入接收号码和内容:AT+CMGS="13800138000"\r\nHello\r\n(需等待模块返回“>”提示符)
- 发送结束符:Ctrl+Z(0x1A),模块返回+CMGS: xx和OK。
常见问题及解决方法
-
模块无响应
- 原因:串口参数不匹配、硬件连接错误、模块未上电或未插卡。
- 解决:检查波特率、TX/RX连接是否正确,确认模块电源指示灯正常,插入SIM卡并等待网络注册。
-
指令返回ERROR
- 原因:指令语法错误、模块不支持该指令、模块处于忙状态。
- 解决:核对指令格式(如是否缺少参数、回车符),尝试AT+IPR=115200设置波特率,或发送AT+CFUN=1重启模块。
代码示例(基于STM32 HAL库)
#include "stm32f1xx_hal.h"
UART_HandleTypeDef huart1;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
char *at_cmd = "AT\r\n";
uint8_t rx_data[64];
uint16_t rx_index = 0;
// 发送AT指令
HAL_UART_Transmit(&huart1, (uint8_t *)at_cmd, strlen(at_cmd), 100);
// 接收响应(超时5秒)
HAL_StatusTypeDef status = HAL_UART_Receive(&huart1, rx_data, 1, 5000);
while (status == HAL_OK) {
if (rx_data[0] == '\r' || rx_data[0] == '\n') {
rx_data[rx_index] = '\0';
if (strstr((char *)rx_data, "OK")) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); // LED亮,表示成功
break;
}
rx_index = 0;
} else {
rx_index++;
}
status = HAL_UART_Receive(&huart1, rx_data, 1, 5000);
}
while (1);
}
相关问答FAQs
问题1:为什么单片机发送AT指令后模块没有响应?
解答:可能原因包括:① 串口波特率、数据位等参数与模块设置不一致;② 硬件连接错误(如TX与RX交叉接反);③ 模块未正常启动(如电源电压不足、未插SIM卡);④ 指令末尾缺少回车符\r\n,建议先用串口调试助手单独测试模块,确认模块正常后再连接单片机。
问题2:如何确保AT指令发送的可靠性?
解答:可通过以下方式提高可靠性:① 添加指令重试机制(如连续发送3次,间隔1秒);② 实现超时检测,避免程序卡死;③ 对响应数据进行校验(如检查是否包含“OK”或“ERROR”);④ 在关键指令(如拨打电话、发送短信)后添加延时,等待模块处理完成,发送短信后需等待模块返回+CMGS响应,再执行下一条指令。
