Глобальная система навигации и определения положения (Global Positioning System, GPS) – это система, позволяющая определять такие параметры текущего местоположения как ее высота, долгота, широта, всеобщее скоординированное время (UTC) и многое другое по информации, получаемой от нескольких спутников.
Считать данные GPS можно с помощью практически любого современного микроконтроллера (платы). В данной статье мы рассмотрим подключение GPS модуля к микроконтроллеру PIC и считывание GPS данных с его помощью. В качестве GPS модуля мы выбрали G7020 от компании U-blox. С его помощью мы будем определять значения широты и долготы для нашего текущего местоположения и отображать их на экране ЖК дисплея 16х2.
Также на нашем сайте мы рассматривали подключение GPS модуля к другим микроконтроллерам (платам):
Необходимые компоненты
- Микроконтроллер PIC16F877A (купить на AliExpress).
- GPS модуль uBLOX-G7020 (или аналогичный).
- Держатель микросхем на 40 контактов (купить на AliExpress).
- Программатор PICkit 3 (купить на AliExpress).
- Кварцевый генератор 20 МГц (купить на AliExpress).
- Конденсаторы 33 пФ – 2 шт. (купить на AliExpress).
- Резистор 4,7 кОм (купить на AliExpress).
- Адаптер на 5 В.
- ЖК дисплей 16х2 (купить на AliExpress).
- Потенциометр 10 кОм (купить на AliExpress).
- Макетная плата.
- Соединительные провода.
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Схема проекта
Схема подключения GPS модуля к микроконтроллеру PIC представлена на следующем рисунке.
В представленной схеме контакты RS, R/W и E ЖК дисплея подключены к контактам RB0, RB1 и RB2 микроконтроллера PIC, а контакты D4, D5, D6, D7 ЖК дисплея подключены к контактам RB4, RB5, RB6 и RB7 микроконтроллера. ЖК дисплей подключен в 4-битном режиме. Более подробно о его подключении к микроконтроллеру PIC вы можете прочитать в этой статье.
Кварцевый генератор 20MHz с помощью двух керамических конденсаторов 33 пФ подключен к контактам OSC1 и OSC2 микроконтроллера PIC. Он будет обеспечивать стабильную тактовую частоту для микроконтроллера.
GPS модуль uBlox-G7020 будет принимать данные от спутников и передавать их в микроконтроллер PIC16F877A через последовательный порт связи (USART). Более подробно про использование последовательного порта в микроконтроллерах PIC вы можете прочитать в этой статье.
GPS модуль uBlox-G7020 имеет цветовое обозначение проводов, выходящих из него. Его положительный (для подачи питания 5V) провод красного цвета, общий провод (GND) – черного цвета, а выходной провод – синего цвета.
Получение данных GPS
GPS данные модуль uBlox-G7020 передает на свой выход в виде нескольких строк со скоростью 9600 бод. Если мы включим терминал последовательного порта (UART terminal) на скорости 9600 бод, то мы увидим эти данные.
Модуль uBlox-G7020 передает GPS данные в так называемом формате NMEA, который состоит из нескольких строк. Четырьмя самыми важными строками в нем являются:
- $GPGGA: Global Positioning System Fix Data (фиксированные данные глобального местоположения);
- $GPGSV: GPS satellites in view (спутники GPS в нашей зоне действия);
- $GPGSA: GPS DOP and active satellites (активные спутники);
- $GPRMC: Recommended minimum specific GPS/Transit data (специализированные данные GPS/транзитные данные).
Более подробные сведения об NMEA формате можно получить здесь (на английском языке).
Пример принимаемых GPS данных выглядит следующим образом:
1 2 3 4 5 6 |
$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 выглядит следующим образом:
1 |
$GPGGA,141848.00,2237.63306,N,08820.86316,E,1,03,2.56,1.9,M,-54.2,M,,*74 |
Что означают эти данные:
1. Строка $GPGGA всегда начинается со знака “$”.
2. GPGGA означает фиксированные данные системы глобального позиционирования.
3. Запятая “,” разделяет различные значения в строке.
4. 141848.00: GMT время 14(часов):18(минут):48(секунд):00(мс).
5. 2237.63306,N: широта 22 (градуса) 37 (минут) 63306 (секунд). N (North) – северная.
6. 08820.86316,E: долгота 088 (градусов) 20 (минут) 86316 (секунд). E (East) – восточная.
7. 1 : фиксированное качество 0= invalid data (неправильные данные), 1= (правильные данные), 2=DGPS fix
8. 03 : количество спутников, с которыми в данный момент поддерживается связь.
9. 1.0: HDOP.
10. 2.56,M : высота над уровнем моря в метрах.
11. 1.9,M : Geoids height (геоидная высота).
12. *74 : контрольная сумма.
Таким образом, в нашем проекте нам понадобятся только данные из 5-й и 6-й позиций данной строки.
Шаги для подключения GPS модуля к микроконтроллеру PIC
- Настроить биты конфигурации микроконтроллера.
- Настроить порт, к которому подключен ЖК дисплей.
- Соединить GPS модуль с микроконтроллером PIC через последовательный порт связи (USART).
- Сконфигурировать USART для работы в режиме непрерывного приема со скоростью 9600 бод. Сконфигурировать ЖК дисплей для работы в 4-битном режиме.
- Инициализировать два символьных массива. Один – для приема данных широты, второй – для приема данных долготы.
- Принимать по одному символу и проверять является ли этот символ $ или нет.
- Если обнаружили символ $, то потом следует проверить следуют ли за ним символы GPGGA и запятая.
- Если это строка GPGGA, то пропускаем в ней первые данные (всемирного времени) и находим в ней данные широты и долготы. Эти данные последовательно сохраняем в два наших символьных массива до тех пор пока не встретим в строке символы N (North) и E (East).
- Выводим значения массивов на ЖК дисплей.
- Очищаем массивы.
Объяснение программы для микроконтроллера PIC
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
Первым делом в программе настраиваются биты конфигурации, более подробно про их настройку можно прочитать в этой статье. Также в программе необходимо подключить заголовочные файлы используемых библиотек: lcd.h – для работы с ЖК дисплеем, eusart.h – для работы с USART, xc.h – для компилятора XC8.
1 2 3 4 5 |
#include <xc.h> #include <stdio.h> #include <string.h> #include "supporing_cfile\lcd.h" #include "supporing_cfile\eusart1.h" |
Далее, в функции main(), функция system_init() используется для инициализации ЖК дисплея и последовательного порта (USART).
1 2 3 |
Void main(void) { TRISB = 0x00; // Setting as output system_init(); |
Функции lcd_init() и EUSART_Intialize() вызываются из библиотек lcd.h and eusart.h.
1 2 3 4 |
void system_init(void){ lcd_init(); // This will initialise the lcd EUSART1_Initialize(); // This will initialise the Eusart } |
Затем в цикле while мы последовательно, бит за битом, принимаем данные строки GPGGA и сравниваем принятые символы с теми, которые содержатся в строке GPGGA.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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 time).
1 2 3 |
while (incomer_data != ','){ // skipping GMT Time incomer_data=EUSART1_Read(); } |
Затем сохраняем значения широты и долготы в символьные массивы.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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 } } |
И, наконец, выводим значения широты и долготы на экран ЖК дисплея.
1 2 3 4 5 6 7 8 9 10 11 12 |
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++; } |
Исходный код программы
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
/* * 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 <xc.h> #include <stdio.h> #include <string.h> #include "supporing_cfile\lcd.h" #include "supporing_cfile\eusart1.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; // на вывод данных system_init(); // System getting ready and initialising the LCD and USART driver. //LCD_ScrollMessage("Circuitdigest.com"); while(1){ incomer_data=EUSART1_Read(); // проверяем наличие строки '$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(); // на этом этапе мы можем сказать что строка GPGGA найдена while (incomer_data != ','){ // пропускаем GMT время 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; // сохраняем данные широты } 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; // сохраняем данные долготы } } array_count=0; //lcd_com(0x80); // LCD line one selection while(array_count<12){ // массив данных широты содержит 11 символов lcd_data(latitude[array_count]); // выводим на экран данные широты array_count++; } array_count=0; lcd_com(0xC0); // Lcd line two selection while(array_count<13){ // массив данных долготы содержит 12 символов lcd_data(longitude[array_count]); // выводим данные долготы array_count++; } //lcd_com(0x01); //очищаем экран ЖК дисплея } } } } } } } } 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(); // инициализируем ЖК дисплей EUSART1_Initialize(); // инициализируем последовательный порт (USART) } |
Файлы для скачивания: GPS-with-PIC-header-file.zip.