如何将GPS模块与PIC微控制器连接以获取当前位置的纬度和经度

gps是全球定位系统的简称。它是一个提供准确的高度,纬度,经度,utc时间和更多信息的系统,这些信息来自2,3,4或更多卫星。要从gps读取数据,我们需要一些微控制器,我们已经将gps与arduino和raspberry pi连接在一起。
我们选择了由u-blox制造的g7020 gps模块。我们将从卫星接收特定位置的经度和纬度,并将在 16x2 字符 lcd 上显示相同的经度和纬度。因此,在这里我们将通过微芯片将gps与pic16f877a微控制器连接。
所需组件:
pic16f877a – pdip40 封装
面包板
皮基特-3
5v 适配器
液晶显示器 jhd162a
ublox-g7020 全球定位系统模块
用于连接外围设备的电线。
4.7k 电阻器
10k锅
20mhz 晶体
2 个 33pf 陶瓷电容器
电路图和说明:-
16x2字符lcd通过pic16f877a微控制器连接,其中rb0,rb1,rb2分别连接到lcd引脚rs,r / w和e.rb4,rb5,rb6和rb7通过lcd的4针d4,d5,d6,d7连接。液晶屏以4位模式或半字节模式连接。
一个 20mhz 的晶体振荡器,带有两个 33pf 的陶瓷电容器,连接在 osc1 和 osc2 引脚上。它将为微控制器提供恒定的20 mhz时钟频率。
ublox-g7020 gps模块,使用uart接收和传输数据。pic16f877a由芯片内部的一个usart驱动器组成,我们将通过usart从gps模块接收数据,因此将从微控制器rx引脚到gps的tx引脚和usart接收引脚通过gps的传输引脚连接进行交叉连接。
ublox-g7020 具有引脚的颜色代码。正极或5v引脚为红色,负极或gnd引脚为黑色,传输引脚为蓝色。
我已经在面包板上连接了所有这些。
从 gps 获取位置数据:
让我们看看如何使用 usart 连接 gps,并在 16x2 字符 lcd 中查看结果。
该模块将以 9600 波特率在多个字符串中传输数据。如果我们使用波特率为9600的uart终端,我们将看到gps接收的数据。
gps模块以nmea格式发送实时跟踪位置数据(请参见上面的屏幕截图)。nmea格式由几个句子组成,其中四个重要句子如下。
这是gps在9600波特率连接时接收的数据。
$gprmc,141848.00,a,2237.63306,n,08820.86316,e,0.553,,100418,,,a*73
$gpvtg,,t,,m,0.553,n,1.024,k,a*27
$gpgga,141848.00,2237.63306,n,08820.86316,e,1,03,2.56,1.9,m,-54.2,m,,*74
$gpgsa,a,2,06,02,05,,,,,,,,,,2.75,2.56,1.00*02
$gpgsv,1,1,04,02,59,316,30,05,43,188,25,06,44,022,23,25,03,324,*76
$gpgll,2237.63306,n,08820.86316,e,141848.00,a,a*65
当我们使用gps模块跟踪任何位置时,我们只需要坐标,我们可以在字符串中找到$gpgga。只有$gpgga(全球定位系统修复数据)字符串主要用于程序,其他字符串被忽略。
$gpgga,141848.00,2237.63306,n,08820.86316,e,1,03,2.56,1.9,m,-54.2,m,,*74
这句话是什么意思?
该行的含义是:-
1. 字符串始终以“$”符号开头
2. gpgga 代表 全球定位系统定位数据
3. “,”逗号表示两个值之间的分隔
4. 141848.00:格林威治标准时间为 14(小时):18(分钟):48(秒):00(毫秒)
5. 2237.63306,n:北纬22度(度)37(分)63306(秒)北纬
6. 08820.86316,e:东经088(度)20(分)86316(秒)
7. 1:修复数量0=无效数据,1=有效数据,2=dgps修复
8. 03 : 当前查看的卫星数量。
9. 1.0: hdop
10. 2.56,米:海拔高度(海拔高度,单位:米)
11. 1.9,m : 大地水准面高度
12. *74 : 校验和
因此,我们需要 5 号和 6 号来收集有关模块位置或模块位置的信息。
将gps与pic微控制器连接的步骤:-
设置微控制器的配置,包括振荡器配置。
设置lcd的所需端口,包括tris寄存器。
使用 usart 将 gps 模块连接到微控制器。
在连续接收模式下初始化系统 usart,波特率为 9600,lcd 具有 4 位模式。
根据纬度和经度的长度采用两个字符数组。
一次接收一个字符位,并检查它是否从 $ 开始。
如果 $ 接收,那么它是一个字符串,我们需要检查 gpgga、这 5 个字母和逗号。
如果是 gpgga,那么我们将跳过时间,并寻找纬度和经度,我们将纬度和经度存储在两个字符数组中,直到 n(北)和 e(东)未收到。
我们将在lcd中打印阵列。
清除阵列。
代码说明:
让我们逐行查看代码。前几行用于设置配置位,这些配置位在上一个教程中已经解释过,所以我现在跳过它们。本教程末尾给出了完整的代码。
这五行用于包括库头文件,lcd.h 和 eusart.h 分别用于 lcd 和 usart。xc.h 用于微控制器头文件。
#include
#include
#include
#include supporing_cfilelcd.h
#include supporing_cfileeusart1.h
在 void main() 函数中,system_init();函数用于初始化lcd和usart。
void main(void) {
trisb = 0x00; // setting as output
system_init();
lcd_init(); 和 eusart_intialize(); 从两个库 lcd.h 和 eusart.h 调用
void system_init(void){
lcd_init(); // this will initialise the lcd
eusart1_initialize(); // this will initialise the eusart
}
在 while 循环中,我们中断 gpgga 字符串以获取经度和纬度坐标。我们一次接收一位,并将其与 gpgga 字符串中存在的单个字符进行比较。
我们打破了我们将得到的代码:-
incomer_data=eusart1_read(); // check the string '$gpgga,'
/*------------------------------ step by step finding the gpgga line----------------------------*/
if(incomer_data=='$'){ // first statement of the gps data start with a $ sign
incomer_data=eusart1_read(); // if the first if become true then the next phase
if(incomer_data=='g'){
incomer_data=eusart1_read();
if(incomer_data=='p');{
incomer_data=eusart1_read();
if(incomer_data=='g');{
incomer_data=eusart1_read();
if(incomer_data=='g'){
incomer_data=eusart1_read();
if(incomer_data=='a'){
incomer_data=eusart1_read();
if(incomer_data==','){ // first , received
incomer_data=eusart1_read(); // at this stage final check in done, gpgga is found.
通过使用此代码,我们跳过了 utc 时间。
while (incomer_data != ','){ // skipping gmt time 
incomer_data=eusart1_read();
}
此代码用于将纬度和经度数据存储在字符数组中。
incomer_data=eusart1_read();
latitude[0] = incomer_data;                                
while(incomer_data != ','){
for(array_count=1;incomer_data!='n';array_count++){
incomer_data=eusart1_read();
latitude[array_count]=incomer_data; // store the latitude data
}
incomer_data=eusart1_read();
if(incomer_data==','){
for(array_count=0;incomer_data!='e';array_count++){
incomer_data=eusart1_read();
longitude[array_count]=incomer_data; // store the longitude data
}
}
最后,我们在lcd上打印了经度和纬度。
array_count=0;                                    
lcd_com(0x80); // lcd line one selection
while(array_count<12){ // array of latitude data is 11 digit
lcd_data(latitude[array_count]); // print the latitude data
array_count++;
}
array_count=0;
lcd_com(0xc0); // lcd line two selection
while(array_count<13){ // array of longitude data is 12 digit
lcd_data(longitude[array_count]); // print the longitude data
array_count++;
}                   
这就是我们如何将gps模块与pic微控制器连接以获取当前位置的纬度和经度。
/*
* file:   main.c
* author: sourav gupta
* by:- circuitdigest.com
* created on april 1, 2018, 2:26 pm
*/
// pic16f877a configuration bit settings
// 'c' source line config statements
// config
#pragma config fosc = hs        // oscillator selection bits (hs oscillator)
#pragma config wdte = off       // watchdog timer enable bit (wdt disabled)
#pragma config pwrte = off      // power-up timer enable bit (pwrt disabled)
#pragma config boren = on       // brown-out reset enable bit (bor enabled)
#pragma config lvp = off         // low-voltage (single-supply) in-circuit serial programming enable bit (rb3/pgm pin has pgm function; low-voltage programming enabled)
#pragma config cpd = off        // data eeprom memory code protection bit (data eeprom code protection off)
#pragma config wrt = off        // flash program memory write enable bits (write protection off; all program memory may be written to by eecon control)
#pragma config cp = off         // flash program memory code protection bit (code protection off)
#include
#include
#include
#include supporing_cfilelcd.h
#include supporing_cfileeusart1.h
/*
hardware related definition
*/
#define _xtal_freq 200000000 //crystal frequency, used in delay
/*
other specific definition
*/
void system_init(void);
unsigned char incomer_data = 0;
unsigned char longitude[13];
unsigned char latitude[13];
unsigned int array_count=0;
/* sample line received from the gps :-
[$gpgga,100156.000,2690.9416,n,07547.8441,e,1,08,1.0,442.8,m,-42.5,m,,0000*71]
1. string always starts with a ?$? sign
2. gpgga : global positioning system fix data
3. ?,? comma indicates the separation between two values
4. 100156.000 : gmt time as 10(hr):01(min):56(sec):000(ms)
5. 2650.9416,n: latitude 26(degree) 50(minutes) 9416(sec) north
6. 07547.8441,e: longitude 075(degree) 47(minutes) 8441(sec) east
7. 1 : fix quantity 0= invalid data, 1= valid data, 2=dgps fix
8. 08 :  number of satellites currently viewed.
9. 1.0: hdop
10. 442.8,m : altitude (height above sea level in meter)
11. -42.5,m : geoids height
12. __ , dgps data
13. 0000 : dgps data
14. *71 : checksum
*/
void main(void) {
trisb = 0x00; // setting as output
system_init(); // system getting ready and initialising the lcd and usart driver.
//lcd_scrollmessage(circuitdigest.com);
while(1){
incomer_data=eusart1_read(); // check the string '$gpgga,'
/*------------------------------ step by step finding the gpgga line----------------------------*/
if(incomer_data=='$'){ // first statement of the gps data start with a $ sign
incomer_data=eusart1_read(); // if the first if become true then the next phase
if(incomer_data=='g'){
incomer_data=eusart1_read();
if(incomer_data=='p');{
incomer_data=eusart1_read();
if(incomer_data=='g');{
incomer_data=eusart1_read();
if(incomer_data=='g'){
incomer_data=eusart1_read();
if(incomer_data=='a'){
incomer_data=eusart1_read();
if(incomer_data==','){ // first , received
incomer_data=eusart1_read(); // at this stage final check in done, gpgga is found.
while (incomer_data != ','){ // skipping gmt time
incomer_data=eusart1_read();
}
incomer_data=eusart1_read();
latitude[0] = incomer_data;
while(incomer_data != ','){
for(array_count=1;incomer_data!='n';array_count++){
incomer_data=eusart1_read();
latitude[array_count]=incomer_data; // store the latitude data
}
incomer_data=eusart1_read();
if(incomer_data==','){
for(array_count=0;incomer_data!='e';array_count++){
incomer_data=eusart1_read();
longitude[array_count]=incomer_data; // store the longitude data
}
}
array_count=0;
//lcd_com(0x80); // lcd line one selection
while(array_count<12){ // array of latitude data is 11 digit
lcd_data(latitude[array_count]); // print the latitude data
array_count++;
}
array_count=0;
lcd_com(0xc0); // lcd line two selection
while(array_count<13){ // array of longitude data is 12 digit
lcd_data(longitude[array_count]); // print the longitude data
array_count++;
}
//lcd_com(0x01); //clear lcd
}
}
}
}
}
}
}
}
for(array_count=0;array_count<=13;array_count++){
incomer_data=0;
latitude[array_count]=0;
longitude[array_count]=0;
}
array_count = 0;
}
}
/*
this function is for system initialisations.
*/
void system_init(void){
lcd_init(); // this will initialise the lcd
eusart1_initialize(); // this will initialise the eusart
}

纯电动车电池的能量密度高低有多重要?要读懂“电池能量密度”
华为将开发多设备无线充电技术
轻装上阵,智敬职场——latitude7000尽显精英本色
振动传感器选型及参数介绍
接近开关负载是什么意思
如何将GPS模块与PIC微控制器连接以获取当前位置的纬度和经度
专家:中国有权监管 苹果App Store涉嫌垄断,在中国还有这个机会吗
荣耀10青春版评测 不忘性能的颜值优品
拒绝“硬扛”:中国广电没有“杠”的实力
如何用更少的数据自动将文本分类,同时精确度还比原来的方法高
进口家电品牌国内市场萎缩 质量问题被接二连三召回
cps物联网技术的应用案例
受保护的限制器改善了高阻抗传感器的动态范围
新款iPad Pro保护套曝光该机采用了浴霸镜头模组设计
四六级英语听力网络传输红外发射系统方案
受惠高功率混合信号业务增长 恩智浦2016年营收增长56%
手机摄像头发展趋势以及弹片微针模组的性能测试
云WIFI技术的集团客户网应用案例
NCM811电池的热失控相关特性测试方案
GaN器件特性影响因素有哪些?