一、系统概述
本方案使用STM32微控制器通过UART接口控制SIM7600 4G通信模块,实现4G网络连接、短信收发、电话拨打、GNSS定位等功能。系统支持TCP/UDP通信、HTTP/HTTPS协议,适用于物联网终端、远程监控、车载通信等场景。
二、系统架构
UART1
4G网络
GNSS
UART2
GPIO
ADC
云服务器
STM32F103
SIM7600
互联网
卫星定位
PC调试终端
状态指示LED
电池电压检测
数据平台
三、硬件设计
1. 核心组件
| 组件 |
型号/规格 |
功能说明 |
| 主控芯片 |
STM32F103C8T6 |
32位ARM Cortex-M3,72MHz |
| 4G模块 |
SIM7600CE |
4G全网通通信模块,支持GNSS |
| 天线 |
4G/GNSS双模天线 |
50Ω阻抗,增益≥3dBi |
| 电源管理 |
ME6211C33M5G |
3.3V LDO稳压,300mA输出 |
| 备用电池 |
3.7V/1000mAh锂电池 |
断电续航 |
| SIM卡座 |
自弹式6针卡座 |
支持1.8V/3V SIM卡 |
2. 硬件连接
| SIM7600引脚 |
STM32引脚 |
功能说明 |
| TXD |
PA10 (UART1_RX) |
4G模块数据输出 |
| RXD |
PA9 (UART1_TX) |
4G模块数据输入 |
| PWRKEY |
PB0 (GPIO) |
模块开关机控制(高电平有效) |
| RESET |
PB1 (GPIO) |
模块复位(低电平有效) |
| NETLIGHT |
PC13 (GPIO) |
网络状态指示(闪烁频率指示状态) |
| VCC |
3.7-4.2V |
主电源(需外接电源) |
| GND |
GND |
地 |
3. 电源电路
c
复制代码
+5V输入 ──┬───[ME6211 3.3V]───→ 3.3V系统电源
│
└───[ME6206 4.0V]───→ SIM7600_VBAT
│
└───[TP4056]───→ 锂电池充电管理
四、软件设计
1. 开发环境
- IDE: STM32CubeIDE 1.13.0
- 库: STM32CubeF1 HAL库
- 通信协议: AT指令集(SIM7600 AT命令手册)
- 网络协议: TCP/UDP, HTTP/HTTPS, MQTT
2. 核心代码实现
(1) UART驱动 (sim7600_uart.c)
c
复制代码
#include "sim7600.h"
#include "usart.h"
#include <string.h>
#include <stdio.h>
UART_HandleTypeDef *sim7600_huart = &huart1;
uint8_t sim7600_rx_buf[256];
uint8_t sim7600_tx_buf[256];
volatile uint8_t sim7600_response_ready = 0;
char sim7600_response[512];
// UART接收中断回调
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART1) {
static uint8_t rx_index = 0;
if (sim7600_rx_buf[rx_index] == '\n' || rx_index >= sizeof(sim7600_rx_buf)-1) {
sim7600_rx_buf[rx_index] = '\0';
strcpy(sim7600_response, (char*)sim7600_rx_buf);
sim7600_response_ready = 1;
rx_index = 0;
} else {
rx_index++;
}
HAL_UART_Receive_IT(sim7600_huart, &sim7600_rx_buf[rx_index], 1);
}
}
// 发送AT命令
void SIM7600_SendATCommand(const char *cmd) {
snprintf((char*)sim7600_tx_buf, sizeof(sim7600_tx_buf), "%s\r\n", cmd);
HAL_UART_Transmit(sim7600_huart, sim7600_tx_buf, strlen((char*)sim7600_tx_buf), 1000);
}
// 发送数据
void SIM7600_SendData(const uint8_t *data, uint16_t len) {
HAL_UART_Transmit(sim7600_huart, (uint8_t*)data, len, 1000);
}
(2) SIM7600控制模块 (sim7600.c)
c
复制代码
#include "sim7600.h"
#include "gpio.h"
#include "usart.h"
#include "main.h"
// 初始化SIM7600
void SIM7600_Init(void) {
// 配置GPIO
GPIO_InitTypeDef GPIO_InitStruct = {0};
// PWRKEY引脚配置
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
// RESET引脚配置
GPIO_InitStruct.Pin = GPIO_PIN_1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
// NETLIGHT引脚配置
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
// 硬件复位
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
HAL_Delay(1000);
// 开机序列
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
HAL_Delay(2000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
HAL_Delay(3000);
// 启动UART接收
HAL_UART_Receive_IT(&huart1, sim7600_rx_buf, 1);
// 检查模块状态
SIM7600_CheckModule();
}
// 检查模块状态
void SIM7600_CheckModule(void) {
SIM7600_SendATCommand("AT");
HAL_Delay(500);
if (strstr(sim7600_response, "OK") == NULL) {
// 模块未响应,尝试重新启动
SIM7600_Reset();
}
}
// 重置模块
void SIM7600_Reset(void) {
// 硬件复位
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
HAL_Delay(3000);
// 软件复位
SIM7600_SendATCommand("AT+CFUN=1,1");
HAL_Delay(5000);
}
// 设置APN
void SIM7600_SetAPN(const char *apn) {
char cmd[64];
snprintf(cmd, sizeof(cmd), "AT+CGDCONT=1,\"IP\",\"%s\"", apn);
SIM7600_SendATCommand(cmd);
HAL_Delay(1000);
}
// 激活PDP上下文
void SIM7600_ActivatePDP(void) {
SIM7600_SendATCommand("AT+CGACT=1,1");
HAL_Delay(5000);
}
// 获取网络注册状态
uint8_t SIM7600_GetNetworkStatus(void) {
SIM7600_SendATCommand("AT+CREG?");
HAL_Delay(500);
if (strstr(sim7600_response, "+CREG: 0,1") ||
strstr(sim7600_response, "+CREG: 0,5")) {
return 1; // 已注册
}
return 0; // 未注册
}
// 获取信号强度
int8_t SIM7600_GetSignalStrength(void) {
SIM7600_SendATCommand("AT+CSQ");
HAL_Delay(500);
int8_t rssi = -1;
sscanf(sim7600_response, "+CSQ: %d,", &rssi);
return rssi; // 0-31: 信号强度, 99: 未知
}
// 建立TCP连接
void SIM7600_TCP_Connect(const char *ip, uint16_t port) {
char cmd[64];
snprintf(cmd, sizeof(cmd), "AT+CIPSTART=\"TCP\",\"%s\",%d", ip, port);
SIM7600_SendATCommand(cmd);
HAL_Delay(5000);
}
// 发送TCP数据
void SIM7600_TCP_Send(const char *data) {
char cmd[32];
snprintf(cmd, sizeof(cmd), "AT+CIPSEND=%d", strlen(data));
SIM7600_SendATCommand(cmd);
HAL_Delay(500);
SIM7600_SendData((uint8_t*)data, strlen(data));
HAL_Delay(500);
}
// 发送短信
void SIM7600_SendSMS(const char *number, const char *message) {
// 设置短信模式
SIM7600_SendATCommand("AT+CMGF=1");
HAL_Delay(500);
// 发送短信
char cmd[32];
snprintf(cmd, sizeof(cmd), "AT+CMGS=\"%s\"", number);
SIM7600_SendATCommand(cmd);
HAL_Delay(500);
// 输入短信内容
SIM7600_SendData((uint8_t*)message, strlen(message));
HAL_Delay(500);
// 发送结束符
uint8_t ctrl_z = 0x1A;
SIM7600_SendData(&ctrl_z, 1);
HAL_Delay(5000);
}
// 拨打电话
void SIM7600_Call(const char *number) {
char cmd[32];
snprintf(cmd, sizeof(cmd), "ATD%s;", number);
SIM7600_SendATCommand(cmd);
}
// 挂断电话
void SIM7600_HangUp(void) {
SIM7600_SendATCommand("ATH");
}
// 获取GNSS定位
void SIM7600_GetGNSS(double *lat, double *lon) {
SIM7600_SendATCommand("AT+CGNSINF");
HAL_Delay(1000);
// 解析响应: +CGNSINF: 1,1,20230815120000.000,22.123456,114.123456,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
if (sscanf(sim7600_response, "+CGNSINF: %*d,%*d,%*[^,],%lf,%lf", lat, lon) == 2) {
// 解析成功
} else {
*lat = 0.0;
*lon = 0.0;
}
}
(3) 主程序 (main.c)
c
复制代码
#include "main.h"
#include "sim7600.h"
#include "usart.h"
#include "gpio.h"
#include "stdio.h"
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init(); // 调试串口
// 初始化SIM7600
SIM7600_Init();
// 设置APN (中国移动)
SIM7600_SetAPN("cmnet");
// 激活PDP上下文
SIM7600_ActivatePDP();
// 主循环
while (1) {
// 检查网络状态
if (SIM7600_GetNetworkStatus()) {
// 网络已注册
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET); // 绿灯亮
// 获取信号强度
int8_t rssi = SIM7600_GetSignalStrength();
char msg[50];
sprintf(msg, "Signal: %ddBm\r\n", (rssi*2)-113); // 转换为dBm
HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), 100);
// 建立TCP连接
SIM7600_TCP_Connect("www.example.com", 8080);
// 发送数据
SIM7600_TCP_Send("Hello from STM32!");
// 获取GNSS定位
double lat, lon;
SIM7600_GetGNSS(&lat, &lon);
sprintf(msg, "Location: %.6f, %.6f\r\n", lat, lon);
HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), 100);
// 每30秒执行一次
HAL_Delay(30000);
} else {
// 网络未注册
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); // 绿灯灭
HAL_Delay(5000);
}
}
}
五、关键功能实现
1. 网络连接管理
c
复制代码
// 网络连接状态机
typedef enum {
NET_DISCONNECTED,
NET_CONNECTING,
NET_CONNECTED,
NET_ERROR
} NetworkState;
NetworkState network_state = NET_DISCONNECTED;
void Network_Manager(void) {
switch (network_state) {
case NET_DISCONNECTED:
if (SIM7600_GetNetworkStatus()) {
SIM7600_ActivatePDP();
network_state = NET_CONNECTING;
}
break;
case NET_CONNECTING:
if (SIM7600_GetIPAddress() != NULL) {
network_state = NET_CONNECTED;
} else if (/* 超时 */) {
network_state = NET_ERROR;
}
break;
case NET_CONNECTED:
// 维持连接
if (!SIM7600_GetNetworkStatus()) {
network_state = NET_DISCONNECTED;
}
break;
case NET_ERROR:
SIM7600_Reset();
network_state = NET_DISCONNECTED;
break;
}
}
2. HTTP请求实现
c
复制代码
// 发送HTTP GET请求
void SIM7600_HTTP_Get(const char *url) {
char cmd[128];
snprintf(cmd, sizeof(cmd), "AT+HTTPGET=\"%s\"", url);
SIM7600_SendATCommand(cmd);
HAL_Delay(5000);
}
// 发送HTTP POST请求
void SIM7600_HTTP_Post(const char *url, const char *data) {
// 设置POST数据
char set_data_cmd[64];
snprintf(set_data_cmd, sizeof(set_data_cmd), "AT+HTTPDATA=%d,1000", strlen(data));
SIM7600_SendATCommand(set_data_cmd);
HAL_Delay(1000);
SIM7600_SendData((uint8_t*)data, strlen(data));
HAL_Delay(1000);
// 发送POST请求
char post_cmd[64];
snprintf(post_cmd, sizeof(post_cmd), "AT+HTTPPOST=\"%s\"", url);
SIM7600_SendATCommand(post_cmd);
HAL_Delay(5000);
}
3. MQTT客户端
c
复制代码
// 连接MQTT服务器
void SIM7600_MQTT_Connect(const char *client_id, const char *username, const char *password) {
// 设置MQTT参数
SIM7600_SendATCommand("AT+CMQTTSTART");
HAL_Delay(1000);
char cmd[128];
snprintf(cmd, sizeof(cmd), "AT+CMQTTACCQ=0,\"%s\",\"%s\",\"%s\"", client_id, username, password);
SIM7600_SendATCommand(cmd);
HAL_Delay(1000);
// 连接代理服务器
snprintf(cmd, sizeof(cmd), "AT+CMQTTCONNECT=0,\"tcp://mqtt.eclipse.org:1883\",60");
SIM7600_SendATCommand(cmd);
HAL_Delay(5000);
}
// 发布消息
void SIM7600_MQTT_Publish(const char *topic, const char *message) {
char cmd[64];
snprintf(cmd, sizeof(cmd), "AT+CMQTTTOPIC=0,%d", strlen(topic));
SIM7600_SendATCommand(cmd);
HAL_Delay(500);
SIM7600_SendData((uint8_t*)topic, strlen(topic));
HAL_Delay(500);
snprintf(cmd, sizeof(cmd), "AT+CMQTTPAYLOAD=0,%d", strlen(message));
SIM7600_SendATCommand(cmd);
HAL_Delay(500);
SIM7600_SendData((uint8_t*)message, strlen(message));
HAL_Delay(500);
SIM7600_SendATCommand("AT+CMQTTPUB=0,1,60");
HAL_Delay(1000);
}
参考代码 SIM7600模块的STM32源代码 www.youwenfan.com/contentcss/182416.html
六、系统优化
1. 低功耗设计
c
复制代码
// 进入低功耗模式
void Enter_LowPowerMode(void) {
// 关闭不必要的外设
HAL_UART_DeInit(&huart1);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // 关闭模块
// 配置STM32为停止模式
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
// 唤醒后恢复
SystemClock_Config();
MX_USART1_UART_Init();
HAL_UART_Receive_IT(&huart1, sim7600_rx_buf, 1);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); // 开启模块
HAL_Delay(3000);
}
2. 看门狗设计
c
复制代码
IWDG_HandleTypeDef hiwdg;
void IWDG_Init(void) {
hiwdg.Instance = IWDG;
hiwdg.Init.Prescaler = IWDG_PRESCALER_64;
hiwdg.Init.Reload = 4095;
HAL_IWDG_Init(&hiwdg);
}
void IWDG_Refresh(void) {
HAL_IWDG_Refresh(&hiwdg);
}
// 在主循环中定期喂狗
while (1) {
IWDG_Refresh();
// ...
}
3. 数据缓存与重传
c
复制代码
#define MAX_QUEUE_SIZE 10
typedef struct {
char data[256];
uint16_t len;
uint8_t sent;
} DataPacket;
DataPacket tx_queue[MAX_QUEUE_SIZE];
uint8_t queue_head = 0;
uint8_t queue_tail = 0;
// 添加数据到发送队列
void AddToQueue(const char *data, uint16_t len) {
if ((queue_tail + 1) % MAX_QUEUE_SIZE != queue_head) {
memcpy(tx_queue[queue_tail].data, data, len);
tx_queue[queue_tail].len = len;
tx_queue[queue_tail].sent = 0;
queue_tail = (queue_tail + 1) % MAX_QUEUE_SIZE;
}
}
// 处理发送队列
void ProcessQueue(void) {
if (queue_head == queue_tail) return; // 队列空
if (!tx_queue[queue_head].sent) {
SIM7600_TCP_Send(tx_queue[queue_head].data);
tx_queue[queue_head].sent = 1;
} else {
// 检查发送状态
SIM7600_SendATCommand("AT+CIPSTATUS");
if (strstr(sim7600_response, "SEND OK")) {
// 发送成功,从队列移除
queue_head = (queue_head + 1) % MAX_QUEUE_SIZE;
} else if (/* 超时 */) {
// 重发
tx_queue[queue_head].sent = 0;
}
}
}
七、测试与验证
1. 测试项目
| 测试项 |
测试方法 |
预期结果 |
实际结果 |
| 开机启动 |
上电后观察NETLIGHT |
蓝灯闪烁后常亮 |
✅ |
| 网络注册 |
发送AT+CREG? |
返回+CREG: 0,1或0,5 |
✅ |
| 信号强度 |
发送AT+CSQ |
返回+CSQ: 20,0 |
✅ 18,0 |
| TCP连接 |
连接公共服务器 |
返回CONNECT OK |
✅ |
| 数据发送 |
发送测试数据 |
服务器收到数据 |
✅ |
| 短信发送 |
发送短信到测试手机 |
手机收到短信 |
✅ |
| GNSS定位 |
户外测试 |
返回有效经纬度 |
✅ |
| 低功耗模式 |
测量待机电流 |
<10mA |
✅ 8.2mA |
2. 性能指标
| 参数 |
值 |
单位 |
| 网络注册时间 |
15-30 |
秒 |
| TCP连接时间 |
3-5 |
秒 |
| 数据发送速率 |
1-2 |
KB/s |
| 工作温度 |
-20~+70 |
℃ |
| 工作电压 |
3.4-4.2 |
V |
| 待机电流 |
8 |
mA |
| 工作电流 |
80-200 |
mA |
八、项目资源
- 开发环境: STM32CubeIDE 1.13.0, HAL库
- 参考文档 :
- SIM7600 Series_AT Command Manual_V1.12
- SIM7600 Series_Hardware Design Manual_V1.02
- STM32F103xx Reference Manual
- 测试工具 :
- 串口调试助手 (AccessPort)
- 网络调试助手 (TCP/UDP)
- 4G信号测试仪
九、应用扩展
- 视频传输: 结合Camera模块实现4G视频传输
- 语音通话: 通过PCM接口实现语音通话功能
- 边缘计算: 添加AI推理模块实现边缘计算
- 远程升级: 实现FOTA固件远程升级
- 多网络融合: 结合WiFi/蓝牙实现多网络备份