GPS是全球定位系统的简称。它是一个提供准确的高度,纬度,经度,UTC时间以及许多其他信息的系统,这些信息取自2、3、4或更多颗卫星。要从GPS读取数据,我们需要一些微控制器,并且我们已经将GPS与Arduino和Raspberry Pi进行了接口。
我们选择了由U-blox制造的G7020 GPS模块。我们将从卫星接收特定位置的经度和纬度,并将其显示在16x2字符LCD上。因此,在这里我们将通过微芯片将GPS与PIC16F877A微控制器接口。
所需组件:
- Pic16F877A – PDIP40封装
- 面包板
- Pickit-3
- 5V适配器
- 液晶显示器JHD162A
- uBLOX-G7020 GPS模块
- 连接外围设备的电线。
- 4.7k电阻器
- 1万锅
- 20mHz晶体
- 2个33pF陶瓷电容器
电路图和说明:-
PIC16F877A微控制器上连接了16x2字符LCD,其中RB0,RB1,RB2分别连接到LCD引脚RS,R / W和E.RB4,RB5,RB6和RB7跨LCD的4引脚D4,D5连接,D6,D7。LCD以4位模式或半字节模式连接。了解有关将LCD与PIC微控制器接口的更多信息。
一个20MHz的晶体振荡器,在OSC1和OSC2引脚之间连接了两个33pF的陶瓷电容器。它将为微控制器提供恒定的20 MHz时钟频率。
uBlox-G7020 GPS模块,使用UART接收和发送数据。PIC16F877A在芯片内部包含一个USART驱动器,我们将通过USART接收来自GPS模块的数据,因此将通过单片机的Rx引脚与GPS的Tx引脚以及通过GPS的Transmit引脚连接的USART接收引脚进行交叉连接。
uBlox-G7020的针脚具有颜色代码。正或5V引脚为红色,负或GND引脚为黑色,发送引脚为蓝色。
我已经将所有这些都连接到了面包板上。
从GPS获取位置数据:
让我们看看如何使用USART连接GPS并在16x2字符LCD上查看结果。
模块将以9600波特率以多个字符串传输数据。如果我们使用波特率为9600的UART终端,我们将看到GPS接收到的数据。
GPS模块以NMEA格式发送实时跟踪位置数据(请参见上面的屏幕截图)。NMEA格式由几个句子组成,其中四个重要句子如下。有关NMEA语句及其数据格式的更多详细信息,请参见此处。
- $ GPGGA:全球定位系统修复数据
- $ GPGSV:可以看到GPS卫星
- $ GPGSA:GPS DOP和活动卫星
- $ GPRMC:建议的最低特定GPS /公交数据
在此处了解有关GPS数据和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 string中找到它。仅$ 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:GMT时间为14(hr):18(min):48(sec):00(ms)
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,M:海拔(海拔高度,以米为单位)
11. 1.9,M:大地水准面高度
12. * 74:校验和
因此,我们需要5号和6号来收集有关模块位置或模块位置的信息。
GPS与PIC单片机接口的步骤:-
- 设置微控制器的配置,包括振荡器配置。
- 设置LCD的所需端口(包括TRIS寄存器)。
- 使用USART将GPS模块连接到微控制器。
- 在9600波特率和4位LCD的连续接收模式下初始化系统USART。
- 根据纬度和经度的长度获取两个字符数组。
- 一次接收一个字符位,然后检查它是否从$开始。
- 如果$ Receive则为字符串,我们需要检查GPGGA,这5个字母和逗号。
- 如果是GPGGA,则我们将跳过时间,查找纬度和经度,然后将纬度和经度存储在两个字符数组中,直到未收到N(北)和E(东)。
- 我们将在LCD中打印阵列。
- 清除阵列。
代码说明:
让我们逐行查看代码。前几行用于设置配置位,这在上一教程中已进行了说明,因此我暂时跳过它们。完整的代码在本教程的结尾给出。
这五行用于包括库头文件, lcd.h 和 eusart.h 分别用于LCD和USART。而 xc.h 是单片机头文件。
#包括
在 void main() 函数中, system_init() ; 功能用于初始化LCD和USART。
空隙主(无效){ TRISB = 0x00; //设置为输出 system_init();
所述 lcd_init(); 和 EUSART_Intialize(); 从两个库 lcd.h 和 eusart.h中调用
void system_init(void){ lcd_init(); //这将初始化LCD EUSART1_Initialize(); //这将初始化Eusart }
在 while 循环中,我们中断GPGGA字符串以获取经度和纬度坐标。我们一次接收一位,并将其与GPGGA字符串中存在的各个字符进行比较。
我们破坏了将得到的代码:
incomer_data = EUSART1_Read(); //检查字符串'$ GPGGA', / * ------------------------------逐步查找GPGGA行- --------------------------- * / if(incomer_data =='$'){// GPS数据的第一条语句以$ sign incomer_data = EUSART1_Read(); //如果第一个if为true,则进入下一阶段 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 ==','){//首先,收到 incomer_data = EUSART1_Read(); //在此阶段,最后检查完成,找到了GPGGA。
通过使用此代码,我们跳过了UTC时间。
while(incomer_data!=','){//跳过格林尼治标准时间Time incomer_data = EUSART1_Read(); }
该代码用于在字符数组中存储纬度和经度数据。
incomer_data = EUSART1_Read(); 纬度= incomer_data; while(incomer_data!=','){ for(array_count = 1; incomer_data!='N'; array_count ++){ incomer_data = EUSART1_Read(); latitude = incomer_data; //存储纬度数据 } incomer_data = EUSART1_Read(); if(incomer_data ==','){ for(array_count = 0; incomer_data!='E'; array_count ++){ incomer_data = EUSART1_Read(); 经度= incomer_data; //存储经度数据 } }
最后,我们在LCD上打印了经度和纬度。
array_count = 0; lcd_com(0x80); // LCD第一行选择 while(array_count <12){//纬度数据数组为11位 lcd_data(latitude); //打印纬度数据 array_count ++; } array_count = 0; lcd_com(0xC0); // LCD第二行选择 while(array_count <13){//经度数据的数组为12位 lcd_data(longitude); //打印经度数据 array_count ++; }
这是我们如何将GPS模块与PIC微控制器接口以获取当前位置的纬度和经度。
完整的代码和头文件在下面给出。