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/蓝牙实现多网络备份
相关推荐
国科安芯7 小时前
航天器多路并联大功率电源系统设计与ASP4644均流特性分析
单片机·嵌入式硬件·fpga开发·安全性测试
茯苓gao9 小时前
嵌入式开发笔记:CANopen相关移位运算与通信协议术语详解
网络·嵌入式硬件·学习·信息与通信
梁朝辉12 小时前
STM32H750VBT6中ADCINP与INN什么区别
stm32·单片机·嵌入式硬件
省四收割者13 小时前
一文详解信号完整性(1)
python·嵌入式硬件·数学建模·信息与通信·信号处理·智能硬件
崇山峻岭之间14 小时前
单片机无感FOC驱动之ADC
单片机·嵌入式硬件
Ligocious14 小时前
1.点亮一颗小小的LED
单片机·嵌入式硬件
KaifuZeng18 小时前
通信与接口协议面试八、CAN通信
单片机·嵌入式硬件·面试·通信与接口协议
智源单片机设计19 小时前
基于单片机的直流电机双闭环调速系统设计
单片机·嵌入式硬件
kebidaixu19 小时前
两轮车换电 BMS 的模拟前端中颖 SH367306 AFE 芯片详解
stm32
kebidaixu20 小时前
两轮车换电 BMS 的模拟前端中颖 SH367306 AFE 芯片调试实录:四个关键问题与解决方案
stm32