如何使用STM32F103C8的GPS模块获取位置坐标
2023-09-07 来源:elecfans
GPS代表全球定位系统,用于检测地球上任何位置的纬度和经度,具有精确的UTC时间(协调世界时)。该设备每秒接收来自卫星的坐标,包括时间和日期。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,,校验和数据
但是在本教程中,我们使用了一个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
#include
const int rs = PB11, en = PB10, d4 = PB0, d5 = PB1, d6 = PC13, d7 = PC14;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
然后创建一个名为TinyGPSPlus 类的gps对象。
TinyGPSPlus 全球定位系统;
接下来在void setup中,使用Serial1.begin(9600)开始与 GPS 模块的串行通信。Serial1 用作 STM32F103C8 的 Serial 1 端口(Pins-PA9、PA10)。
Serial1.开始(9600);
然后显示一段时间的欢迎信息。
lcd.开始(16,2);
lcd.print('电路文摘');
lcd.setCursor(0,1);
lcd.print('STM32 带 GPS');
延迟(4000);
lcd.clear();
接下来在void loop() 中,我们从 GPS 接收经纬度,并检查接收到的数据是否有效,并在串行监视器和 LCD 中显示信息。
检查可用的位置数据是否有效
loc_valid = gps.location.isValid();
接收纬度数据
lat_val = gps.location.lat();
接收经度数据
lng_val = gps.location.lng();
如果接收到无效数据,则串行监视器显示“*****”,LCD 显示“等待”。
if (!loc_valid)
{
lcd.print('Waiting');
Serial.print('纬度:');
Serial.println('*****');
Serial.print('经度:');
Serial.println('*****');
延迟(4000);
lcd.clear();
}
如果接收到有效数据,则纬度和经度将显示在串行监视器以及 LCD 显示屏上。
lcd.clear();
Serial.println('GPS 读数:');
Serial.print('纬度:');
Serial.println(lat_val, 6);
lcd.setCursor(0,0);
lcd.print('纬度:');
lcd.print(lat_val,6);
Serial.print('经度:');
Serial.println(lng_val, 6);
lcd.setCursor(0,1);
lcd.print('长:');
lcd.print(lng_val,6);
延迟(4000);
以下函数提供读取数据的延迟。它一直在寻找串行端口上的数据。
静态无效 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 显示屏上会显示位置坐标。
科技观察员 • 来源:circuitdigest • 作者:Pramoth Thangavel • 2022-09-08 15:03 • 5879次阅读
GPS代表全球定位系统,用于检测地球上任何位置的纬度和经度,具有精确的UTC时间(协调世界时)。该设备每秒接收来自卫星的坐标,包括时间和日期。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,,校验和数据
但是在本教程中,我们使用了一个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
#include
const int rs = PB11, en = PB10, d4 = PB0, d5 = PB1, d6 = PC13, d7 = PC14;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
然后创建一个名为TinyGPSPlus 类的gps对象。
TinyGPSPlus 全球定位系统;
接下来在void setup中,使用Serial1.begin(9600)开始与 GPS 模块的串行通信。Serial1 用作 STM32F103C8 的 Serial 1 端口(Pins-PA9、PA10)。
Serial1.开始(9600);
然后显示一段时间的欢迎信息。
lcd.开始(16,2);
lcd.print('电路文摘');
lcd.setCursor(0,1);
lcd.print('STM32 带 GPS');
延迟(4000);
lcd.clear();
接下来在void loop() 中,我们从 GPS 接收经纬度,并检查接收到的数据是否有效,并在串行监视器和 LCD 中显示信息。
检查可用的位置数据是否有效
loc_valid = gps.location.isValid();
接收纬度数据
lat_val = gps.location.lat();
接收经度数据
lng_val = gps.location.lng();
如果接收到无效数据,则串行监视器显示“*****”,LCD 显示“等待”。
if (!loc_valid)
{
lcd.print('Waiting');
Serial.print('纬度:');
Serial.println('*****');
Serial.print('经度:');
Serial.println('*****');
延迟(4000);
lcd.clear();
}
如果接收到有效数据,则纬度和经度将显示在串行监视器以及 LCD 显示屏上。
lcd.clear();
Serial.println('GPS 读数:');
Serial.print('纬度:');
Serial.println(lat_val, 6);
lcd.setCursor(0,0);
lcd.print('纬度:');
lcd.print(lat_val,6);
Serial.print('经度:');
Serial.println(lng_val, 6);
lcd.setCursor(0,1);
lcd.print('长:');
lcd.print(lng_val,6);
延迟(4000);
以下函数提供读取数据的延迟。它一直在寻找串行端口上的数据。
静态无效 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 //LCD显示函数库
#include //GPS函数库
const int rs = PB11, en = PB10, d4 = PB0, d5 = PB1, d6 = PC13, d7 = PC14; //LCD引脚与STM32
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
TinyGPSPlus 全球定位系统;//类TinyGPSPlus的对象gps
无效设置()
{
Serial1.begin(9600);//在串行端口 1 以 9600 波特率开始串行通信
lcd.begin(16,2); //设置显示为 16x2 模式
lcd.print('Circuit Digest');
lcd.setCursor(0,1);
lcd.print('STM32 带 GPS');
延迟(4000);
lcd.clear();
}
无效循环()
{
GPSDelay(1000);
无符号长开始;
双纬度,lng_val;
布尔 loc_valid;
lat_val = gps.location.lat(); //获取纬度
loc_valid = gps.location.isValid();
lng_val = gps.location.lng(); //获取经度
if (!loc_valid) //从 GPS 接收到无效数据时执行
{
lcd.print('Waiting');
Serial.print('纬度:');
Serial.println('*****');
Serial.print('经度:');
Serial.println('*****');
延迟(4000);
lcd.clear();
}
else //从 GPS 接收到有效数据时执行
{
lcd.clear();
Serial.println('GPS 读数:');
Serial.print('纬度:');
Serial.println(lat_val, 6); //在串行监视器打印纬度
lcd.setCursor(0,0);
lcd.print('纬度:');
lcd.print(lat_val,6); //在LCD显示屏上打印纬度
Serial.print('经度:');
Serial.println(lng_val, 6); //在串口监视器上打印经度
lcd.setCursor(0,1);
lcd.print('长:');
lcd.print(lng_val,6); //在液晶显示屏上打印经度
延迟(4000);
}
}
static void GPSDelay(unsigned long ms) //从 GPS 接收数据的延迟
{
unsigned long start = millis();
do
{
while (Serial1.available())
gps.encode(Serial1.read());
} while (millis() - start < ms);
}