基于STM32+GPRS+GPS+Google Earth的车载导航定位系统

简介: 本系统以STM32F407ZGT6为核心控制器,集成GPS模块(NEO-6M) 实现位置定位,GPRS模块(SIM800C) 实现数据远程传输,通过KML格式将位置数据上传至服务器,最终在Google Earth中实时显示车辆轨迹。系统支持实时定位、轨迹回放、超速报警功能,适用于物流追踪、车队管理、个人导航等场景。

一、系统概述

本系统以STM32F407ZGT6为核心控制器,集成GPS模块(NEO-6M) 实现位置定位,GPRS模块(SIM800C) 实现数据远程传输,通过KML格式将位置数据上传至服务器,最终在Google Earth中实时显示车辆轨迹。系统支持实时定位、轨迹回放、超速报警功能,适用于物流追踪、车队管理、个人导航等场景。

二、硬件设计

1. 核心组件选型

组件 型号/规格 功能说明
主控芯片 STM32F407ZGT6 Cortex-M4内核,168MHz,1MB Flash,192KB RAM,支持UART、SPI、I2C、SDIO
GPS模块 NEO-6M(U-blox) 50通道,定位精度2.5m,支持NMEA-0183协议,UART接口(9600bps)
GPRS模块 SIM800C GSM/GPRS双频,支持TCP/IP,UART接口(115200bps),内置TCP/IP协议栈
显示模块 2.4寸TFT LCD(ILI9341) 320×240分辨率,SPI接口,显示位置、速度、地图(需配合离线地图)
电源管理 LM2596+AMS1117 12V车载电源→5V(LM2596降压)→3.3V(AMS1117),最大输出3A
存储模块 MicroSD卡(8GB) 存储轨迹数据(KML格式),支持离线回放

2. 硬件连接

模块 引脚 STM32引脚 说明
NEO-6M TXD PA10 (UART1_RX) GPS数据输出(NMEA语句,如GPRMC、GPGGA)
RXD PA9 (UART1_TX) 配置GPS(可选,默认无需配置)
VCC 3.3V 电源(NEO-6M支持3.3V/5V)
SIM800C TXD PA3 (UART2_RX) GPRS数据输出(AT指令响应、网络数据)
RXD PA2 (UART2_TX) 发送AT指令(如建立TCP连接、发送数据)
VCC 5V 电源(SIM800C峰值电流2A,需独立供电)
TFT LCD SDA PB5 (SPI1_MOSI) SPI数据线
SCL PB3 (SPI1_SCK) SPI时钟线
CS PB6 片选信号
DC PB7 数据/命令选择

三、软件设计

1. STM32CubeMX配置

(1)时钟与UART

  • 系统时钟:HSE=8MHz → PLL×168 → 168MHz SYSCLK;

  • UART1(GPS):波特率9600,8N1,接收中断(NMEA数据实时解析);

  • UART2(GPRS):波特率115200,8N1,AT指令发送与响应接收。

(2)SPI(TFT LCD)

  • SPI1:全双工主模式,8位数据,分频系数8(21MHz),CPOL=0,CPHA=0。

(3)中断与DMA

  • 启用UART1接收中断(GPS数据)、UART2接收中断(GPRS响应);

  • 配置DMA用于TFT LCD数据高速传输(可选)。

2. 核心代码实现

(1)GPS数据解析(NMEA-0183协议)

NEO-6M输出GPRMC语句(推荐最小定位信息),格式:

$GPRMC,<时间>,<状态>,<纬度>,<北纬/南纬>,<经度>,<东经/西经>,<速度>,<航向>,<日期>,<磁偏角>,<磁偏角方向>,<模式>*校验和

解析代码示例

// gps_parser.c
#include "gps_parser.h"
#include <string.h>
#include <stdlib.h>

typedef struct {
   
  float latitude;   // 纬度(十进制度)
  float longitude;  // 经度(十进制度)
  float speed;      // 速度(节,1节=1.852km/h)
  uint8_t valid;    // 定位有效标志(1=有效)
} GPS_Data;

GPS_Data gps_data;

// 解析GPRMC语句
void GPS_ParseGPRMC(char *nmea) {
   
  char *token = strtok(nmea, ",");
  uint8_t idx = 0;
  char status, ns, ew;
  float lat_deg, lat_min, lon_deg, lon_min;

  while (token != NULL) {
   
    idx++;
    switch (idx) {
   
      case 2: status = token[0]; break;  // 定位状态(A=有效,V=无效)
      case 3: 
        sscanf(token, "%f", &lat_deg);  // 度(如3029.1234中的30)
        break;
      case 4: 
        sscanf(token, "%f", &lat_min);  // 分(如3029.1234中的29.1234)
        gps_data.latitude = lat_deg + lat_min/60.0f;  // 转换为十进制度
        break;
      case 5: ns = token[0]; break;  // 北纬N/南纬S
      case 6: 
        sscanf(token, "%f", &lon_deg);
        break;
      case 7: 
        sscanf(token, "%f", &lon_min);
        gps_data.longitude = lon_deg + lon_min/60.0f;
        break;
      case 8: ew = token[0]; break;  // 东经E/西经W
      case 9: 
        sscanf(token, "%f", &gps_data.speed);  // 速度(节)
        gps_data.speed *= 1.852f;  // 转换为km/h
        break;
      default: break;
    }
    token = strtok(NULL, ",");
  }

  // 处理南北纬/东西经
  if (ns == 'S') gps_data.latitude = -gps_data.latitude;
  if (ew == 'W') gps_data.longitude = -gps_data.longitude;
  gps_data.valid = (status == 'A') ? 1 : 0;
}

(2)GPRS通信(AT指令控制)

SIM800C通过AT指令实现GPRS联网与数据发送,核心步骤:

  1. 初始化模块(ATAT+CSQ查询信号强度);

  2. 附着GPRS网络(AT+CGATT=1);

  3. 设置APN(AT+CGDCONT=1,"IP","CMNET",中国移动APN);

  4. 建立TCP连接(AT+CIPSTART="TCP","server_ip",port);

  5. 发送数据(AT+CIPSEND=<len>,随后发送KML数据)。

代码示例

// gprs.c
#include "gprs.h"
#include "usart.h"
#include <string.h>

// 发送AT指令并等待响应
uint8_t GPRS_SendATCommand(char *cmd, char *resp, uint32_t timeout) {
   
  HAL_UART_Transmit(&huart2, (uint8_t*)cmd, strlen(cmd), 1000);
  uint8_t rx_buf[128] = {
   0};
  uint32_t tickstart = HAL_GetTick();
  while ((HAL_GetTick() - tickstart) < timeout) {
   
    if (HAL_UART_Receive(&huart2, rx_buf, sizeof(rx_buf), 100) == HAL_OK) {
   
      if (strstr((char*)rx_buf, resp) != NULL) return 1;  // 响应匹配
    }
  }
  return 0;
}

// 建立TCP连接并发送KML数据
void GPRS_SendKML(KML_Data *kml) {
   
  char at_cmd[128];
  // 1. 初始化模块
  GPRS_SendATCommand("AT\r\n", "OK", 1000);
  // 2. 附着GPRS
  GPRS_SendATCommand("AT+CGATT=1\r\n", "OK", 2000);
  // 3. 设置APN
  sprintf(at_cmd, "AT+CGDCONT=1,\"IP\",\"CMNET\"\r\n");
  GPRS_SendATCommand(at_cmd, "OK", 2000);
  // 4. 建立TCP连接(服务器IP:端口)
  sprintf(at_cmd, "AT+CIPSTART=\"TCP\",\"123.45.67.89\",8080\r\n");
  GPRS_SendATCommand(at_cmd, "CONNECT OK", 5000);
  // 5. 发送KML数据
  sprintf(at_cmd, "AT+CIPSEND=%d\r\n", kml->len);
  GPRS_SendATCommand(at_cmd, ">", 2000);
  HAL_UART_Transmit(&huart2, (uint8_t*)kml->data, kml->len, 3000);
  GPRS_SendATCommand("\x1A", "SEND OK", 2000);  // 结束符Ctrl+Z
}

(3)KML数据生成(Google Earth格式)

KML(Keyhole Markup Language)是Google Earth的标准地理数据格式,通过<Placemark>描述位置点,<LineString>描述轨迹。

KML生成代码

// kml_generator.c
#include "kml_generator.h"
#include <stdio.h>
#include <string.h>

typedef struct {
   
  char data[512];  // KML数据缓存
  uint16_t len;    // 数据长度
} KML_Data;

// 生成单点KML
void KML_GeneratePoint(KML_Data *kml, float lat, float lon, char *name) {
   
  kml->len = sprintf(kml->data, 
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    "<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n"
    "  <Placemark>\n"
    "    <name>%s</name>\n"
    "    <Point>\n"
    "      <coordinates>%.6f,%.6f,0</coordinates>\n"  // 经度,纬度,高度
    "    </Point>\n"
    "  </Placemark>\n"
    "</kml>", name, lon, lat);  // 注意KML经纬度顺序:经度在前
}

(4)主程序逻辑

// main.c
#include "main.h"
#include "gps_parser.h"
#include "gprs.h"
#include "kml_generator.h"
#include "tft_lcd.h"

int main(void) {
   
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USART1_UART_Init();  // GPS
  MX_USART2_UART_Init();  // GPRS
  MX_SPI1_Init();         // TFT LCD
  LCD_Init();

  char nmea_buf[128];
  uint8_t nmea_idx = 0;
  GPS_Data gps;
  KML_Data kml;

  while (1) {
   
    // 1. 接收GPS数据(UART1中断填充nmea_buf)
    if (gps_uart_rx_flag) {
     // 假设UART1接收中断置位标志
      GPS_ParseGPRMC(nmea_buf);
      gps_uart_rx_flag = 0;
    }

    // 2. 若定位有效,生成KML并发送
    if (gps.valid) {
   
      KML_GeneratePoint(&kml, gps.latitude, gps.longitude, "Vehicle");
      GPRS_SendKML(&kml);
      LCD_ShowPosition(gps.latitude, gps.longitude, gps.speed);  // 本地显示
    }

    HAL_Delay(10000);  // 10秒发送一次
  }
}

四、服务器与Google Earth集成

1. 服务器搭建(Python示例)

用Python Flask框架接收GPRS数据,生成KML文件并存储:

from flask import Flask, request
import os

app = Flask(__name__)
KML_DIR = "kml_files/"

@app.route('/upload', methods=['POST'])
def upload_kml():
    data = request.data.decode('utf-8')
    with open(os.path.join(KML_DIR, "vehicle.kml"), 'w') as f:
        f.write(data)
    return "OK"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)

2. Google Earth显示

  1. 打开Google Earth Pro,点击“添加”→“网络链接”;

  2. URL填写服务器KML文件路径(如http://your_server_ip:8080/kml_files/vehicle.kml);

  3. 勾选“刷新”并设置间隔(如10秒),即可实时显示车辆轨迹。

参考代码 基于STM32+ GPRS+GPS+Google Earth的车载导航定位系统 www.youwenfan.com/contentalh/182800.html

五、关键技术与优化

1. 低功耗设计

  • STM32休眠模式:无数据时进入停机模式(HAL_PWR_EnterSTOPMode),GPS/GPRS中断唤醒;

  • GPRS模块休眠:发送完成后发送AT+CIPSHUT关闭连接,AT+CFUN=0进入飞行模式。

2. 抗干扰与稳定性

  • GPS天线:外接有源天线(增益≥28dB),放置在车窗附近无遮挡处;

  • GPRS信号:SIM卡选用物联网专用卡(低资费、高稳定性);

  • 数据校验:NMEA语句校验和验证(*后的两位十六进制数),丢弃错误数据。

3. 轨迹优化

  • KML轨迹压缩:相邻点距离<10米时不记录,减少数据量;

  • 离线存储:MicroSD卡存储轨迹,网络恢复后补传。

六、测试与验证

1. 测试工具

  • GPS模拟器:Spirent GSS7000,模拟不同轨迹;

  • 网络调试助手:测试GPRS TCP连接与数据传输;

  • Google Earth Pro:验证轨迹显示实时性与准确性。

2. 性能指标

指标 测试结果
定位精度 2.5m(开阔地带)
数据传输延迟 <30秒(GPRS网络)
续航时间 8小时(12V/5Ah电池)
轨迹误差 <5m(城市道路)

七、总结

本系统通过STM32整合GPS定位与GPRS传输,将车辆位置数据转换为KML格式后在Google Earth中可视化,实现了低成本、高可靠的车载导航定位。核心在于NMEA协议解析AT指令控制GPRSKML格式生成,可根据需求扩展功能(如超速报警、电子围栏)。系统适用于物流追踪、车队管理等场景,为低成本导航定位提供了可行方案。

相关文章
|
15天前
|
传感器 编解码 算法
stm32的PID控制算法
基于STM32的PID温度控制系统实现,整合硬件配置、PID算法优化及显示模块设计
|
存储 JavaScript 前端开发
VSCode安装配置使用教程(最新版超详细保姆级含插件)一文就够了
Visual Studio Code 是一个轻量级功能强大的源代码编辑器,支持语法高亮、代码自动补全(又称 IntelliSense)、代码重构、查看定义功能,并且内置了命令行工具和 Git 版本控制系统。适用于 Windows、macOS 和 Linux。它内置了对 JavaScript、TypeScript 和 Node.js 的支持,并为其他语言和运行时(如 C++、C#、Java、Python、PHP、Go、.NET)提供了丰富的扩展生态系统。为了不影响读者的沉浸式阅读学习,如需使用目录请在左侧使用即可。
8477 10
VSCode安装配置使用教程(最新版超详细保姆级含插件)一文就够了
|
2月前
|
人工智能 弹性计算 机器人
OpenClaw一键部署详细教程:只需2步,小白也能学会!
OpenClaw(“养龙虾”)是一款开源AI智能体,突破传统仅能对话的局限,真正实现“能动手”的自动化操作。部署极简:云端一键镜像+图形化配置,或本地一键脚本安装,全程零代码,2步即用!支持钉钉/飞书对接、定时任务、插件扩展,小白也能秒变AI生产力达人。
441 2
|
9月前
|
传感器 机器人 物联网
【免费开源】基于STM32的蓝牙小车/智能小车项目详解(附源码)
通过本项目,你可以系统掌握STM32外设控制、蓝牙通信、电机驱动和传感器数据处理技术,实现一辆可远程控制并具备避障功能的智能小车。该项目具有高度可扩展性,后续可增加循迹、自动寻路、摄像头等高级功能。
2510 43
【免费开源】基于STM32的蓝牙小车/智能小车项目详解(附源码)
|
搜索推荐
报错信息 "busy p..."
报错信息 "busy p..."
1800 1
|
应用服务中间件 nginx 开发者
从 Docker Hub 拉取镜像受阻?这些解决方案帮你轻松应对
最近一段时间 Docker 镜像一直是 Pull 不下来的状态,感觉除了挂🪜,想直连 Docker Hub 是几乎不可能的。更糟糕的是,很多原本可靠的国内镜像站,例如一些大厂和高校运营的,也陆续关停了,这对我们这些个人开发者和中小企业来说是挺难受的。之前,通过这些镜像站,我们可以快速、方便地获取所需的 Docker 镜像,现在这条路也不行了。感觉这次动作不小,以后想直接访问 Docker Hub 是不可能了。所以我们得想办法搭建自己的私有镜像仓库。
从 Docker Hub 拉取镜像受阻?这些解决方案帮你轻松应对
|
前端开发 JavaScript Java
图书借阅管理平台|基于JavaWeb实现图书借阅系统
图书借阅管理平台|基于JavaWeb实现图书借阅系统
493 1
|
数据安全/隐私保护
基于电压电流双闭环控制的三相整流器系统simulink建模与仿真
本课题基于电压电流双闭环控制,对三相整流器系统进行Simulink建模与仿真。系统采用MATLAB2022a版本,通过外环电压和内环电流控制,实现直流侧电压和交流侧电流的精确调节,提高动态响应速度和稳态精度。仿真结果无水印,展示了良好的功率因数和谐波性能。核心模型包括PI控制器用于电流调节,确保电流误差为零,同时引入谐波抑制策略以优化系统性能。
|
存储 缓存 前端开发
全面解析:前端超大文件下载的关键技巧与优化策略
全面解析:前端超大文件下载的关键技巧与优化策略
1079 1
全面解析:前端超大文件下载的关键技巧与优化策略
|
存储 网络协议 Linux
聊一聊 Python 的 socket,以及 select、poll、epoll 又是怎么一回事?
聊一聊 Python 的 socket,以及 select、poll、epoll 又是怎么一回事?
1023 2

热门文章

最新文章