SIM7600模块STM32控制程序

一、系统概述

本方案使用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信号测试仪

九、应用扩展

  1. 视频传输: 结合Camera模块实现4G视频传输
  2. 语音通话: 通过PCM接口实现语音通话功能
  3. 边缘计算: 添加AI推理模块实现边缘计算
  4. 远程升级: 实现FOTA固件远程升级
  5. 多网络融合: 结合WiFi/蓝牙实现多网络备份
相关推荐
是翔仔呐2 小时前
第13章 超声波测距传感器驱动:HC-SR04底层原理与C语言实现
c语言·开发语言·单片机·嵌入式硬件·gitee
小飞菜涅2 小时前
fast-lio2复现
嵌入式硬件·学习·ubuntu
青山_FPGA2 小时前
AT24CM01芯片的时序是如何进行控制的?
嵌入式硬件·fpga开发·lattice
鲨辣椒100863 小时前
51单片机核心钉子户——温度采集模块
单片机·嵌入式硬件·51单片机
xiangw@GZ4 小时前
CapSense底层逻辑:硬件设计规范
单片机·嵌入式硬件·设计规范
Nice__J4 小时前
Mcu架构以及原理——3.存储器架构
单片机·嵌入式硬件·架构
weiyvyy4 小时前
嵌入式硬件接口的定义与作用
单片机·嵌入式硬件·信息与通信·信息化系统
senijusene4 小时前
依赖51 单片机的 Modbus 协议温度采集与外设控制系统的实现
c语言·单片机·嵌入式硬件·51单片机·keil
JSMSEMI114 小时前
JSM1040T 1Mbps高速具有总线唤醒功能的CAN总线收发器
单片机·嵌入式硬件