打印
[应用相关]

基于STM32的GPS定位

[复制链接]
1513|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2024-3-8 10:40 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
GPS 代表全球定位系统,用于检测地球上任何位置的纬度和经度,具有精确的 UTC 时间(协调世界时)。该设备每秒从卫星接收坐标,包括时间和日期。GPS 提供了很高的准确性,并且还提供了位置坐标以外的其他数据。

我们都知道 GPS 是一种非常有用的设备,在手机和其他便携式设备中非常普遍用于跟踪位置。它在各个领域都有非常广泛的应用,从在家里叫出租车到跟踪飞机的高度。以下是我们之前构建的一些有用的GPS 相关项目。

在本教程中,我们将GPS 模块与 STM32F103C8 微控制器连接,以查找位置坐标并将其显示在16x2 LCD 显示器上。

所需组件
STM32F103C8 微控制器
GPS模块
16x2 液晶显示屏
面包板
连接线
GPS模块
这是一个 GY-NEO6MV2 XM37-1612 GPS 模块。这个GPS模块有四个引脚+5V,GND,TXD和RXD。它使用串行引脚进行通信,可以轻松连接到 STM32F103C8 的串行端口。



GPS 模块 以 NMEA 格式发送数据(见下图)。NMEA 格式由几个句子组成,其中我们只需要一个句子。这句话从 $GPGGA开始 ,包含了坐标、时间等有用的信息。这个 GPGGA 被称为 全球定位系统固定数据。

下面是一个示例 $GPGGA 字符串及其描述:

$GPGGA,104534.000,7791.0381,N,06727.4434,E,1,08,0.9,510.4,M,43.9,M,,*47

$GPGGA,HHMMSS.SSS,latitude,N,longitude,E,FQ,NOS,HDP,altitude,M,height,M,,checksum data

但在本教程中,我们使用的是TinyGPSPlus GPS 库,它从 NMEA 语句中提取所有必需的信息,我们只需要编写一行简单的代码来获取纬度和经度,我们将在本教程后面看到.

STM32F103C8的引脚
STM32F103C8 (BLUE PILL) USART 串​​行通信端口如下图所示。这些是蓝色的,具有(PA9-TX1、PA10-RX1、PA2-TX2、PA3-RX2、PB10-TX3、PB11-RX3)。它有三个这样的沟通渠道。



电路图和连接



GPS模块与STM32F103C8电路连接



16x2 LCD 和 STM32F103C8 之间的连接



整个设置如下所示:



为 GPS 模块接口编程 STM32F103C8

本项目末尾给出了使用 STM32 使用 GPS 模块查找位置的完整程序。STM32F103C8 可以使用 Arduino IDE 进行编程,只需通过 USB 端口将其连接到 PC。确保在上传代码时移除引脚 TX 和 RX,并在上传后连接。
要将 GPS 与 STM32 连接,首先我们必须从 GitHub 链接TinyGPSPlus下载一个库。下载库后,可以通过Sketch -> Include Library -> Add .zip Library 将其包含在 Arduino IDE 中。相同的库可用于将GPS 与 Arduino 连接。
所以首先包括必要的库文件并为 16x2 LCD 定义引脚:
#include <LiquidCrystal.h>
#include <TinyGPS++.h>
const int rs = PB11, en = PB10, d4 = PB0, d5 = PB1, d6 = PC13, d7 = PC14;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);


然后创建一个名为gps的对象,属于 TinyGPSPlus 类。
TinyGPSPlus gps;

接下来在无效设置中,使用Serial1.begin(9600)开始与 GPS 模块的串行通信。Serial1用作STM32F103C8的Serial 1端口(引脚-PA9、PA10)。

Serial1.begin(9600);

然后显示欢迎消息一段时间。

lcd.begin(16,2);
lcd.print("Circuit Digest");
lcd.setCursor(0,1);
lcd.print("STM32 with GPS");
delay(4000);
lcd.clear();
接下来在void loop() 中,我们从 GPS 接收纬度和经度,并检查接收到的数据是否有效,并在串口监视器和 LCD 中显示信息。
检查可用的位置数据是否有效
loc_valid = gps.location.isValid();
接收纬度数据
lat_val = gps.location.lat();
接收经度数据
lng_val = gps.location.lng();
如果接收到无效数据,它会在串行监视器中显示“*****”,并在 LCD 中显示“waiting”。

if (!loc_valid)
{
lcd.print("Waiting");
Serial.print("Latitude : ");
Serial.println("*****");
Serial.print("Longitude : ");
Serial.println("*****");
delay(4000);
lcd.clear();
}
如果收到有效数据,纬度和经度将显示在串行监视器和 LCD 显示屏上。
lcd.clear();
Serial.println("GPS READING: ");
Serial.print("Latitude : ");
Serial.println(lat_val, 6);
lcd.setCursor(0,0);
lcd.print("LAT:");
lcd.print(lat_val,6);
Serial.print("Longitude : ");
Serial.println(lng_val, 6);
lcd.setCursor(0,1);
lcd.print("LONG:");
lcd.print(lng_val,6);
delay(4000);
以下函数提供读取数据的延迟。它一直在串口上寻找数据。
static void GPSDelay(unsigned long ms)
{
unsigned long start = millis();
do
{
while (Serial1.available())
gps.encode(Serial1.read());
} while (millis() - start < ms);
}


使用 GPS 和 STM32 查找经纬度
建立设置并上传代码后,确保将 GPS 模块放置在空旷区域以快速接收信号。有时需要几分钟才能收到信号,因此请稍等片刻。当 GPS 模块开始接收信号时,LED 将开始闪烁,并且位置坐标将显示在 LCD 显示屏上。




您可以使用谷歌地图验证位置的纬度和经度。只需在打开 GPS 的情况下转到 Google 地图,然后单击蓝点。它将显示带有纬度和经度的地址,如下图所示




下面给出了完整的代码:

代码

#include <LiquidCrystal.h>     //Library for using LCD display functions                     

#include <TinyGPS++.h>         //Library for using GPS functions

const int rs = PB11, en = PB10, d4 = PB0, d5 = PB1, d6 = PC13, d7 = PC14;  //LCD pins connected with STM32

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

TinyGPSPlus gps;               //Object gps for class TinyGPSPlus

void setup()

{

  Serial1.begin(9600);         //Begins Serial comunication at Serial Port 1 at 9600 baudrate

  lcd.begin(16,2);             //Sets display in 16x2 Mode

  lcd.print("Circuit Digest");

  lcd.setCursor(0,1);

  lcd.print("STM32 with GPS");

  delay(4000);

  lcd.clear();      

}

void loop()

{

  GPSDelay(1000);

  unsigned long start;

  double lat_val, lng_val;

  bool loc_valid;

  lat_val = gps.location.lat();        //Gets the latitude

  loc_valid = gps.location.isValid();

  lng_val = gps.location.lng();        //Gets the longitude



  if (!loc_valid)                     //Excecutes when invalid data is received from GPS

  {

    lcd.print("Waiting");

    Serial.print("Latitude : ");

    Serial.println("*****");

    Serial.print("Longitude : ");

    Serial.println("*****");

    delay(4000);

    lcd.clear();

  }

  else                              //Excutes when valid data is received from GPS

  {

    lcd.clear();



    Serial.println("GPS READING: ");



    Serial.print("Latitude : ");

    Serial.println(lat_val, 6);   //Prints latitude at Serial Monitor



    lcd.setCursor(0,0);

    lcd.print("LAT:");

    lcd.print(lat_val,6);         //Prints latitude at LCD display

    Serial.print("Longitude : ");

    Serial.println(lng_val, 6);   //Prints longitude at Serial monitor

    lcd.setCursor(0,1);

    lcd.print("LONG:");

    lcd.print(lng_val,6);          //Prints longitude at LCD display

    delay(4000);

  }

}

static void GPSDelay(unsigned long ms)          //Delay for receiving data from GPS

{

  unsigned long start = millis();

  do

  {

    while (Serial1.available())

    gps.encode(Serial1.read());

  } while (millis() - start < ms);

}

————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/Menelaus36/article/details/136175145

使用特权

评论回复
沙发
zhuomuniao110| | 2024-3-10 17:57 | 只看该作者
原来是驱动模块啊,以为出了支持GPS的32单片机了呢。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2028

主题

15903

帖子

13

粉丝