1. 模块上电与开机流程
任务说明
本案例面向LTE Cat1模块(以合宙Air724UG为例,兼容Cat4模块的AT指令集),实现从模块上电到网络注册的完整时序控制。需要完成:正确施加开机脉冲、等待模块就绪、通过AT指令查询网络注册状态,并读取IMEI与固件版本号。最终通过串口输出可验证的模块信息。
硬件连接与上电时序
模块供电采用VBAT(3.8V~4.2V),PWRKEY引脚需拉低至少500ms后释放触发开机。本案例使用MCU的GPIO控制PWRKEY,串口1连接模块的UART_TX/UART_RX,波特率自适应(Air724UG默认115200)。
核心代码实现
以下代码在MCU端完成开机时序控制与AT指令交互。使用阻塞式串口收发,便于演示完整流程。
// main.c — LTE Cat1模块上电与开机流程
#include <stdio.h>
#include <string.h>
#include "stm32f1xx_hal.h"
// 串口句柄(由HAL初始化)
extern UART_HandleTypeDef huart1;
// 模块控制引脚
#define PWRKEY_PIN GPIO_PIN_0
#define PWRKEY_PORT GPIOA
// 缓冲区
static char rx_buf[256];
static uint8_t rx_idx = 0;
// 发送AT指令并等待响应(含超时)
uint8_t AT_Send(const char* cmd, char* resp, uint32_t timeout_ms) {
HAL_UART_Transmit(&huart1, (uint8_t*)cmd, strlen(cmd), 1000);
uint32_t start = HAL_GetTick();
rx_idx = 0;
memset(rx_buf, 0, sizeof(rx_buf));
while (HAL_GetTick() - start < timeout_ms) {
uint8_t ch;
if (HAL_UART_Receive(&huart1, &ch, 1, 100) == HAL_OK) {
if (rx_idx < sizeof(rx_buf) - 1) {
rx_buf[rx_idx++] = ch;
rx_buf[rx_idx] = '\0';
}
// 检测到OK或ERROR即返回
if (strstr(rx_buf, "OK") || strstr(rx_buf, "ERROR")) {
strcpy(resp, rx_buf);
return 1;
}
}
}
strcpy(resp, rx_buf);
return 0; // 超时
}
// 模块开机时序
void Module_PowerOn(void) {
// 1. 确保PWRKEY为高(默认关闭)
HAL_GPIO_WritePin(PWRKEY_PORT, PWRKEY_PIN, GPIO_PIN_SET);
HAL_Delay(100); // VBAT稳定
// 2. 拉低PWRKEY 600ms
HAL_GPIO_WritePin(PWRKEY_PORT, PWRKEY_PIN, GPIO_PIN_RESET);
HAL_Delay(600);
HAL_GPIO_WritePin(PWRKEY_PORT, PWRKEY_PIN, GPIO_PIN_SET);
// 3. 等待模块主动上报就绪(最长10s)
char resp[128];
uint32_t start = HAL_GetTick();
while (HAL_GetTick() - start < 10000) {
if (AT_Send("AT\r\n", resp, 500)) {
if (strstr(resp, "OK")) {
printf("[开机] 模块就绪,响应: %s\r\n", resp);
return;
}
}
HAL_Delay(200);
}
printf("[错误] 模块未响应\r\n");
}
// 查询IMEI与固件版本
void Query_ModuleInfo(void) {
char resp[256];
// 查询IMEI
if (AT_Send("AT+CGSN\r\n", resp, 2000)) {
// 提取15位IMEI
char* p = strstr(resp, "\r\n");
if (p) {
p += 2;
char imei[16] = {0};
strncpy(imei, p, 15);
printf("IMEI: %s\r\n", imei);
}
}
// 查询固件版本
if (AT_Send("AT+CGMR\r\n", resp, 2000)) {
char* p = strstr(resp, "\r\n");
if (p) {
p += 2;
char ver[64] = {0};
int len = 0;
while (p[len] != '\r' && p[len] != '\0' && len < 63) {
ver[len] = p[len];
len++;
}
ver[len] = '\0';
printf("固件版本: %s\r\n", ver);
}
}
}
// 主函数
int main(void) {
HAL_Init();
// ... 系统时钟、GPIO、UART初始化(略,由CubeMX生成)
printf("=== LTE Cat1 模块上电开机流程 ===\r\n");
// 1. 上电开机
Module_PowerOn();
// 2. 等待网络注册(CREG=1或5表示已注册)
char resp[128];
uint8_t registered = 0;
for (int i = 0; i < 20; i++) { // 最多等待20秒
if (AT_Send("AT+CREG?\r\n", resp, 1000)) {
if (strstr(resp, "+CREG: 0,1") || strstr(resp, "+CREG: 0,5")) {
printf("[网络] 注册成功\r\n");
registered = 1;
break;
}
}
HAL_Delay(1000);
}
if (!registered) {
printf("[警告] 网络注册超时,请检查SIM卡与信号\r\n");
}
// 3. 输出模块信息
Query_ModuleInfo();
while (1) {
// 主循环
}
}
编译与烧录
使用STM32CubeIDE创建工程,将上述代码填入main.c。需在CubeMX中配置:USART1(115200, 8N1)、PA0为推挽输出、系统时钟72MHz。编译后通过ST-Link烧录至开发板。
验证方法与判定标准
测试准备:插入有效SIM卡,连接天线,模块VBAT接3.8V电源(限流1A以上)。
执行步骤:
- 打开串口助手(115200),观察MCU串口输出;
- 复位MCU,记录开机日志;
- 观察模块状态LED(若硬件引出)。
通过标准:
- 串口输出包含“模块就绪”,且响应中含“OK”;
- 20秒内输出“网络注册成功”;
- IMEI输出为15位数字,与模块标签一致;
- 固件版本输出非空字符串(如“AirM2M_720U_V1003”)。
预期输出示例(与代码逻辑一致,非实测值):
=== LTE Cat1 模块上电开机流程 ===
[开机] 模块就绪,响应: AT
OK
[网络] 注册成功
IMEI: 869710030001234
固件版本: AirM2M_720U_V1003
若串口无输出,检查PWRKEY时序是否满足≥500ms低电平;若网络注册失败,确认SIM卡接触与天线连接。