В этой статье я расскажу про подключение GPS приемника к микроконтроллеру, на примере модуля u-blox GY-NEO6MV2. Приемник представляет из себя небольшую плату на которой расположены модуль NEO-6M-0-001, стабилизатор напряжения 3.3В, EEPROM память, аккумулятор и светодиод. Модуль продается вместе с активной антенной квадратной формы. Как и все GPS приемники, для передачи данных, модуль использует широко распространенный интерфейс UART, что облегчает его сопряжение с микроконтроллером.
Связь с GPS приемниками осуществляется по протоколу NMEA 0183, это текстовый стандарт связи, использующийся в морском (навигационном) оборудовании. Протокол NMEA 0183 включает в себя множество различных сообщений и команд, я рассмотрю несколько основных сообщений, связанных с глобальной системой позиционирования.
Модуль можно приобрести здесь, есть более дешевый вариант собранный на красной плате с маленькой антенной, можно заказать тут.
По стандарту NMEA все сообщения начинаются с символа “$” и заканчиваются спецсимволами <CR> – возврат каретки (шестнадцатеричное значение 0x0D) и <LF> – перевод строки (шестнадцатеричное значение 0x0A). Первые два символа после “$” являются идентификатором системы, следующие три символа – идентификатор сообщения, например $GPZDA, где GP – глобальная система позиционирования, ZDA – означает, что сообщение содержит информацию о дате по UTC и локальный часовой пояс. После идентификатора сообщения следуют поля, содержащие значения параметров, в конце сообщения после символа “*” находится контрольная сумма. Поля разделяются запятыми, некоторые значения в полях могут отсутствовать, при этом запятые в сообщении не удаляются.
Для того чтобы увидеть сообщения которые выдает GPS модуль, я подключил его к компьютеру через USB-UART преобразователь на чипе PL2303. Для подключения использовал только один вывод на GPS модуле, выход передатчика TX, так как отправлять команды на модуль я не буду, только принимать сообщения. В качестве терминальной программы использовал Terminal v1.9b by Bray. По умолчанию модуль настроен на скорость 9600 бит/сек, в программе необходимо установить следующие настройки: 8 бит данных, без проверки четности, один стоповый бит, управление потоком отключаем.
Ниже приведен скриншот окна программы с сообщениями, полученными от GPS модуля.
В зависимости от количества видимых спутников, данный модуль выдает от 6 до 8 сообщений, которые обновляются каждую секунду (стандартное время для большинства приемников). При достаточном количестве спутников и устойчивом сигнале на модуле начинает мигать светодиод.
Информация о координатах местоположения, времени и скорости в разных сообщениях могут дублироваться. Рассмотрим назначение полей каждого сообщения:
RMC – минимальная рекомендуемая навигационная информация, содержит информацию о времени, дате, координатах местоположения, скорости и направлении курса.
$GPRMC,170840.00,A,5509.68339,N,06125.49498,E,0.204,,311015,,,A*7D | |
170840.00 | Время UTC: 17ч. 08м. 40.00 сек. |
A | Статус достоверности: A – достоверные данные, V – недостоверные данные |
5509.68339 | Широта: 55 градусов, 09.68339 минут |
N | N – северная, S – южная |
06125.49498 | Долгота: 061 градусов, 25.49498 минут |
E | E – восточная, W – западная |
0.204 | Горизонтальная скорость (узлов в час) |
– | Направление курса относительно истинного севера (градусы) |
311015 | Дата: 31 октября 2015 года |
– | Магнитное склонение (градусы) |
– | Направление склонения: E – восточное, W – западное |
A | Режим: A – автономный, D – дифференциальный, E – аппроксимация, N – недостоверные данные |
*7D | Контрольная сумма |
VTG – текущее направление курса и скорость относительно Земли.
$GPVTG,,T,,M,0.204,N,0.378,K,A*29 | |
– | Направление курса (градусы) |
T | Курс относительно истинного севера |
– | Направление курса (градусы) |
M | Курс относительно магнитного севера |
0.204 | Горизонтальная скорость |
N | Единица измерения скорости (узлов в час) |
0.378 | Горизонтальная скорость |
K | Единица измерения скорости (километров в час) |
A | Неизвестный параметр |
*29 | Контрольная сумма |
GGA – зафиксированные данные глобальной системы позиционирования, содержит информацию о времени, координатах местоположения, высоте, статусе определения координат, количестве использованных спутников.
$GPGGA,170840.00,5509.68339,N,06125.49498,E,1,07,2.41,186.2,M,-13.5,M,,*77 | |
170840.00 | Время UTC: 17ч. 08м. 40.00 сек. |
5509.68339 | Широта: 55 градусов, 09.68339 минут |
N | N – северная, S – южная |
06125.49498 | Долгота: 061 градусов, 25.49498 минут |
E | E – восточная, W – западная |
1 | Статус определения координат: 0 – позиция не определена, 1 – позиция определена, 2- позиция определена с повышенной точностью (DGPS) |
07 | Количество использованных спутников |
2.41 | Снижение точности в горизонтальной плоскости (HDOP) |
186.2 | Высота над уровнем моря |
M | Единица измерения высоты (метры) |
-13.5 | Геоидальное различие — различие между земным эллипсоидом WGS-84 и уровнем моря (геоидом) |
M | Единица измерения геоидального различия (метры) |
– | Время с момента последнего обновления DGPS (секунды), 0 – DGPS не используется |
*77 | Контрольная сумма |
GSA – Уровень точности определения координат и активные спутники, содержит информацию о режиме работы, спутниках, снижении точности в различных плоскостях.
$GPGSA,A,3,06,29,23,26,02,09,31,,,,,,3.48,2.41,2.51*0D | |
A | Режим 1: М – ручной 2D или 3D, A – автоматический 2D-разрешено переключение 2D/3D |
3 | Режим 2: 1 – позиция не определена, 2 – 2D позиция определена, высота не определена, 3 – 3D позиция и высота определена |
06 | Идентификатор 1-го спутника использованного для определения координат |
29 | Идентификатор 2-го спутника использованного для определения координат |
…… | |
– | Идентификатор 12-го спутника использованного для определения координат |
3.48 | Снижение точности по местоположению (PDOP) |
2.41 | Снижение точности в горизонтальной плоскости (HDOP) |
2.51 | Снижение точности в вертикальной плоскости (VDOP) |
*0D | Контрольная сумма |
GSV – Информация о видимых спутниках, содержит число видимых спутников, их идентификаторы, высота, азимут, уровень сигнала.
$GPGSV,3,1,11,02,13,325,27,03,34,182,17,06,19,287,23,07,15,237,15*70 | |
3 | Количество сообщений GSV, (от 1 до 3), зависит от количества видимых спутников |
1 | Порядковый номер сообщения, (от 1 до 3) |
11 | Количество видимых спутников |
02 | Идентификатор спутника |
13 | Высота спутника (градусы) |
325 | Азимут спутника (градусы) |
27 | Уровень сигнала, отношение сигнал/шум от 00 до 99 дБ, 0 – нет сигнала. |
03,34,182,17 | То же самое для 2-го спутника |
06,19,287,23 | То же самое для 3-го спутника |
07,15,237,15 | То же самое для 4-го спутника |
*70 | Контрольная сумма |
GLL – географическая позиция – широта/долгота, содержит информацию о времени, координатах местоположения.
$GPGLL,5509.68339,N,06125.49498,E,170840.00,A,A*65 | |
5509.68339 | Широта: 55 градусов, 09.68339 минут |
N | N – северная, S – южная |
06125.49498 | Долгота: 061 градусов, 25.49498 минут |
E | E – восточная, W – западная |
170840.00 | Время UTC: 17ч. 08м. 40.00 сек. |
A | Статус достоверности: A – достоверные данные, V – недостоверные данные |
*65 | Контрольная сумма |
Теперь рассмотрим подключение GPS модуля к микроконтроллеру, для вывода информации я решил использовать LCD дисплей Nokia 5110, так как буду выводить значительное количество символов. Ниже приведена схема подключения:
Микроконтроллер PIC16F628A и LCD дисплей питаются напряжением 3,3В, для того чтобы избежать согласования уровней между линиями ввода/вывода дисплея и микроконтроллера. Чтение сообщений с GPS приемника осуществляется встроенным в микроконтроллер модулем USART. Светодиод HL1 служит индикатором приема и мигает при получении сообщения GPRMC.
Рассмотрим код программы микроконтроллера:
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 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; #include <P16F628A.INC> LIST p=16F628A __CONFIG H'3F18' ;Конфигурация микроконтроллера Sec equ 20h ;вспомогательный регистр счета Sec1 equ 21h ;вспомогательный регистр счета nomer equ 22h ;регистр хранения кода ascii символа scetbit equ 23h ;регистр счета кол-ва бит для spi perem equ 24h ;промежуточный регистр хранения передаваемого байта по spi priem equ 28h ;промежуточный регистр хранения данных полученных по UART temp equ 29h ;вспомогательный регистр счета tmp_symb equ 2Ah ;вспомогательный регистр счета для таблицы данных sp_h equ 2Bh ;старший регистр хранения кол-ва использованных спутников sp_l equ 2Ch ;младший регистр хранения кол-ва использованных спутников flag equ 78h ;регистр флагов FSR_prer equ 7Bh ;регистр хранения значения FSR для обработчика прерываний W_TEMP equ 7Dh ;регистр хранения значения аккумулятора W STATUS_TEMP equ 7Eh ;регистр хранения значения STATUS FSR_temp equ 7Fh ;регистр хранения значения FSR для основной программы data_gps equ 00A0h ;адрес первого регистра для хранения сообщений от модуля GPS #DEFINE sdata PORTB,3 ;присвоение названий линиям ввода-вывода #DEFINE sclk PORTB,4 ;для работы с LCD дисплеем #DEFINE dat_com PORTB,5 ; #DEFINE res_lcd PORTB,0 ; #DEFINE cs PORTB,6 ; #DEFINE led PORTB,7 ;светодиод индикации приема сообщения "GPRMC" от GPS модуля ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; org 0000h ;начать выполнение программы с адреса 0000h goto Start ;переход на метку Start ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Подпрограмма обработки прерываний org 0004h ;начать выполнение подпрограммы с адреса 0004h movwf W_TEMP ;сохранение значений ключевых регистров swapf STATUS,W ; clrf STATUS ; movwf STATUS_TEMP ; movf FSR,W ;сохранение текущего значения регистра FSR, и movwf FSR_temp ;восстановление ранее сохраненного значения movf FSR_prer,W ; movwf FSR ; priem_usart movf RCREG,W ;сохранение байта полученного по UART в регистр INDF movwf INDF ;проверка сохраненного значения на совпадение movlw '$' ;с символом "$" xorwf INDF,W ; btfss STATUS,Z ; goto priem_1 ;нет совпадения: переход на метку priem_1 movlw data_gps ;есть совпадение: установка адреса первого регистра movwf FSR ;для загрузки сообщений от GPS модуля goto exxit ;переход на метку exxit priem_1 movlw 0x0D ;проверка сохраненного значения на совпадение xorwf INDF,W ;с символом возврата каретки 0x0D btfss STATUS,Z ; goto priem_2 ;нет совпадения: переход на метку priem_2 bsf flag,0 ;есть совпадение: установка флага получения сообщения от GPS модуля goto exxit ;переход на метку exxit priem_2 incf FSR,F ;инкремент регистра FSR: установка адреса следующего регистра movlw 0xF0 ;защита от переполнения банка памяти xorwf FSR,W ;проверка значения регистра FSR на совпадение btfss STATUS,Z ;с числом 0xF0 goto exxit ;нет совпадения: переход на метку exxit movlw data_gps ;есть совпадение: установка адреса первого регистра movwf FSR ;для загрузки сообщений от GPS модуля exxit movf FSR,W ;сохранение текущего значения регистра FSR, и movwf FSR_prer ;восстановление ранее сохраненного значения movf FSR_temp,W ; movwf FSR ; swapf STATUS_TEMP,W ;восстановление содержимого ключевых регистров movwf STATUS ; swapf W_TEMP,F ; swapf W_TEMP,W ; ; retfie ;выход из подпрограммы обработки прерывания ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Основная программа Start clrf PORTA ;сброс регистра PORTA movlw b'01000001' ;установка значений выходных защелок порта B movwf PORTB ; movlw b'00000111' ;выключение компараторов movwf CMCON ; bsf STATUS,RP0 ;выбрать 1-й банк movlw b'00000110' ;настройка линий ввода\вывода порта B movwf TRISB ;RB1,RB2,RB7 - на вход, остальные на выход movlw b'11111111' ;настройка линий ввода\вывода порта A movwf TRISA ;все линии на вход movlw 0x19 ;запись числа 0x19 в регистр SPBRG для задания movwf SPBRG ;скорости обмена USART, для частоты тактового ;генератора в 4МГц скорость составит 9600 бит/сек movlw b'00100100' ;настройка модуля USART: выбор асинхронного movwf TXSTA ;высокоскоростного режима USART, ;настройка модуля передатчика USART: 8-ми битная ;передача, разрешение передачи bcf STATUS,RP0 ;выбрать 0-й банк movlw b'10010000' ;настройка модуля USART: включение модуля USART movwf RCSTA ;настройка модуля приемника USART: 8-ми битный ;прием, разрешение приема clrf flag ;сброс регистра флагов movlw data_gps ;запись адреса первого регистра (регистры хранения сообщений от movwf FSR_prer ;модуля GPS) в регистр FSR_prer, выполняется однократно ;после включения питания bsf STATUS,RP0 ;выбрать 1-й банк bsf PIE1,RCIE ;разрешение прерываний от приемника USART bcf STATUS,RP0 ;выбрать 0-й банк bsf INTCON,PEIE ;разрешение прерывания периферийных модулей bsf INTCON,GIE ;глобальное разрешение прерываний call init_lcd ;вызов подпрограммы инициализации дисплея call clear_lcd ;вызов подпрограммы очистки дисплея call viv_not ;вывод на дисплей сообщения "--- " ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; gps_start bcf flag,0 ;сброс флага получения сообщения от GPS модуля gps_a0 btfss flag,0 ;опрос флага получения сообщения от GPS модуля goto gps_a0 ;сообщение не получено: переход на метку gps_a0 ;сообщение получено: movlw .0 ;проверка первых четырех символов сообщения на call srav_gps ;совпадение с символами "GPRMC" путем вызова btfss flag,1 ;подпрограммы сравнения srav_gps goto gps_a1 ;нет совпадения: переход на метку gps_a1 bsf led ;включение светодиода индикации приема call gps_gprmc ;есть совпадение: вызов подпрограммы gps_gprmc bcf led ;выключение светодиода индикации приема goto gps_start ;переход на метку gps_start gps_a1 movlw .5 ;проверка первых четырех символов сообщения на call srav_gps ;совпадение с символами "GPVTG" путем вызова btfss flag,1 ;подпрограммы сравнения srav_gps goto gps_a2 ;нет совпадения: переход на метку gps_a2 call gps_gpvtg ;есть совпадение: вызов подпрограммы gps_gpvtg goto gps_start ;переход на метку gps_start gps_a2 movlw .10 ;проверка первых четырех символов сообщения на call srav_gps ;совпадение с символами "GPGGA" путем вызова btfss flag,1 ;подпрограммы сравнения srav_gps goto gps_a3 ;нет совпадения: переход на метку gps_a3 call gps_gpgga ;есть совпадение: вызов подпрограммы gps_gpgga goto gps_start ;переход на метку gps_start gps_a3 movlw .15 ;проверка первых четырех символов сообщения на call srav_gps ;совпадение с символами "GPGSV" путем вызова btfss flag,1 ;подпрограммы сравнения srav_gps goto gps_start ;нет совпадения: переход на метку gps_start call gps_gpgsv ;есть совпадение: вызов подпрограммы gps_gpgsv goto gps_start ;переход на метку gps_start ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;подпрограмма анализа сообщения "GPRMC", поиск и вывод на дисплей ;значения полей времени, координат, статуса достоверности gps_gprmc call ust_cur_1 ;вызов подпрограммы установки позиции курсора на Lcd дисплее incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка первого символа поля, содержащего информацию о времени btfss flag,2 ; goto time_1 ;есть данные о времени: переход на метку time_1 call viv_not ;обнаружен символ "," нет данных о времени: вывод на дисплей сообщения "--- " goto status_1 ;переход на метку status_1 time_1 movf INDF,W ; call viv_symb ;вывод значения часов, разряд десятков incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка окончания поля, факт совпадения с символом "," btfsc flag,2 ; goto status_1 ;обнаружен символ "," конец поля: переход на метку status_1 movf INDF,W ; call viv_symb ;вывод значения часов, разряд единиц movlw ':' ; call viv_symb ;вывод разделителя, символ ":" incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка окончания поля, факт совпадения с символом "," btfsc flag,2 ; goto status_1 ;обнаружен символ "," конец поля: переход на метку status_1 movf INDF,W ; call viv_symb ;вывод значения минут, разряд десятков incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка окончания поля, факт совпадения с символом "," btfsc flag,2 ; goto status_1 ;обнаружен символ "," конец поля: переход на метку status_1 movf INDF,W ; call viv_symb ;вывод значения минут, разряд единиц movlw ':' ; call viv_symb ;вывод разделителя, символ ":" incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка окончания поля, факт совпадения с символом "," btfsc flag,2 ; goto status_1 ;обнаружен символ "," конец поля: переход на метку status_1 movf INDF,W ; call viv_symb ;вывод значения секунд, разряд десятков incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка окончания поля, факт совпадения с символом "," btfsc flag,2 ; goto status_1 ;обнаружен символ "," конец поля: переход на метку status_1 movf INDF,W ; call viv_symb ;вывод значения секунд, разряд единиц time_2 incf FSR,F ;пропуск символов, поиск символа "," окончания поля call prov_symb ;проверка окончания поля, факт совпадения с символом "," btfss flag,2 ; goto time_2 ;символ "," не обнаружен: переход на метку time_2 status_1 call ust_cur_st ;вызов подпрограммы установки позиции курсора на Lcd дисплее incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка окончания поля, факт совпадения с символом "," btfsc flag,2 ; goto kord_NS_1 ;обнаружен символ "," нет статуса достоверности: переход на метку kord_NS_1 movf INDF,W ; call viv_symb ;вывод значения статуса достоверности incf FSR,F ;инкремент регистра FSR kord_NS_1 incf FSR,F ;инкремент регистра FSR call ust_cur_2 ;вызов подпрограммы установки позиции курсора на Lcd дисплее call prov_symb ;проверка первого символа поля, содержащего координаты широты btfss flag,2 ; goto kord_NS_2 ;есть данные о координатах: переход на метку kord_NS_2 call viv_not ;обнаружен символ "," нет данных о координатах: вывод на дисплей сообщения "--- " goto tip_NS_1 ;переход на метку tip_NS_1 kord_NS_2 movf INDF,W ; call viv_symb ;вывод координат широты (градусы), разряд десятков incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка окончания поля, факт совпадения с символом "," btfsc flag,2 ; goto tip_NS_1 ;обнаружен символ "," конец поля: переход на метку tip_NS_1 movf INDF,W ; call viv_symb ;вывод координат широты (градусы), разряд единиц movlw ' ' ; call viv_symb ;вывод разделителя, символ " " kord_NS_3 incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка окончания поля, факт совпадения с символом "," btfsc flag,2 goto tip_NS_1 ;обнаружен символом ",": переход на метку tip_NS_1 movf INDF,W ; call viv_symb ;вывод координат широты (минуты) goto kord_NS_3 ;переход на метку kord_NS_3 tip_NS_1 incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка типа широты btfsc flag,2 ; goto kord_WE_1 ;обнаружен символ "," тип широты отсутствует: переход на метку kord_WE_1 movf INDF,W ; call viv_symb ;вывод типа широты (северная, южная) incf FSR,F ;инкремент регистра FSR kord_WE_1 incf FSR,F ;инкремент регистра FSR call ust_cur_3 ;вызов подпрограммы установки позиции курсора на Lcd дисплее call prov_symb ;проверка первого символа поля, содержащего координаты долготы btfss flag,2 ; goto kord_WE_2 ;есть данные о координатах: переход на метку kord_WE_2 call viv_not ;обнаружен символ "," нет данных о координатах: вывод на дисплей сообщения "--- " return ;возврат из подпрограммы gps_gprmc kord_WE_2 movf INDF,W ; call viv_symb ;вывод координат долготы (градусы), разряд сотен incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка окончания поля, факт совпадения с символом "," btfsc flag,2 ; goto tip_WE_1 ;обнаружен символ "," конец поля: переход на метку tip_WE_1 movf INDF,W ; call viv_symb ;вывод координат долготы (градусы), разряд десятков incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка окончания поля, факт совпадения с символом "," btfsc flag,2 ; goto tip_WE_1 ;обнаружен символ "," конец поля: переход на метку tip_WE_1 movf INDF,W ; call viv_symb ;вывод координат долготы (градусы), разряд единиц movlw ' ' ; call viv_symb ;вывод разделителя, символ " " kord_WE_3 incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка окончания поля, факт совпадения с символом "," btfsc flag,2 ; goto tip_WE_1 ;обнаружен символом ",": переход на метку tip_WE_1 movf INDF,W call viv_symb ;вывод координат долготы (минуты) goto kord_WE_3 ;переход на метку kord_WE_3 tip_WE_1 incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка типа долготы btfsc flag,2 ; return ;обнаружен символ "," тип долготы отсутствует: возврат из подпрограммы gps_gprmc movf INDF,W ; call viv_symb ;вывод типа долготы (западная, восточная) return ;возврат из подпрограммы gps_gprmc ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;подпрограмма анализа сообщения "GPVTG", поиск и вывод на дисплей значения скорости перемещения gps_gpvtg call ust_cur_4 ;вызов подпрограммы установки позиции курсора на Lcd дисплее movlw .6 ;пропуск 3-x полей movwf temp ; gpvtg_1 incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка окончания поля, факт совпадения с символом "," btfss flag,2 ; goto gpvtg_1 ;символ "," не обнаружен: переход на метку gpvtg_1 decfsz temp,F ;обнаружен символ "," конец поля: декремент регистра temp goto gpvtg_1 ;значение регистра не равно 0: переход на метку gpvtg_1 incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка первого символа поля, содержащего значение скорости btfss flag,2 ; goto gpvtg_2 ;есть данные о скорости: переход на метку gpvtg_2 call viv_not ;обнаружен символ "," нет данных о скорости: вывод на дисплей сообщения "--- " return ;;возврат из подпрограммы gps_gpvtg gpvtg_2 movf INDF,W ; call viv_symb ;вывод значения скорости incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка окончания поля, факт совпадения с символом "," btfss flag,2 ; goto gpvtg_2 ;символом "," не обнаружен: переход на метку gpvtg_2 incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка единицы измерения btfsc flag,2 ; return ;обнаружен символ "," единица измерения отсутствует: возврат из подпрограммы gps_gpvtg movf INDF,W ; call viv_symb ;вывод единицы измерения (K) return ;возврат из подпрограммы gps_gpvtg ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;подпрограмма анализа сообщения "GPGGA", поиск и вывод на дисплей значения высоты и кол-ва использованных спутников gps_gpgga call ust_cur_5 ;вызов подпрограммы установки позиции курсора на Lcd дисплее movlw .6 ;пропуск 4-x полей movwf temp ; gpgga_1 incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка окончания поля, факт совпадения с символом "," btfss flag,2 ; goto gpgga_1 ;символ "," не обнаружен: переход на метку gpgga_1 decfsz temp,F ;обнаружен символ "," конец поля: декремент регистра temp goto gpgga_1 ;значение регистра не равно 0: переход на метку gpgga_1 incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка первого символа поля, содержащего кол-во использован. спутников btfsc flag,2 ; goto sput_1 ;обнаружен символ "," нет данных о спутниках: переход на метку sput_1 movf INDF,W ; movwf sp_h ;сохранение числа использованных спутников в регистр sp_h, разряд десятков incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка окончания поля, факт совпадения с символом "," btfsc flag,2 ; goto sput_1 ;обнаружен символ ",": переход на метку sput_1 movf INDF,W ; movwf sp_l ;сохранение числа использованных спутников в регистр sp_l, разряд единиц movlw .2 ;запись числа в W, для счетчика пропуска запятых, пропуск 2-х запятых goto sput_2 sput_1 movlw .1 ;пропуск одной запятой sput_2 movwf temp ; sput_3 incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка окончания поля, факт совпадения с символом "," btfss flag,2 ; goto sput_3 ;символ "," не обнаружен: переход на метку sput_3 decfsz temp,F ;обнаружен символ "," конец поля: декремент регистра temp goto sput_3 ;значение регистра не равно 0: переход на метку sput_3 incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка первого символа поля, содержащего значение высоты btfss flag,2 ; goto visota_1 ;есть данные о высоте: переход на метку visota_1 call viv_not ;обнаружен символ "," нет данных о высоте: вывод на дисплей сообщения "--- " goto viv_sp ;переход на метку viv_sp visota_1 movf INDF,W ; call viv_symb ;вывод высоты incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка окончания поля, факт совпадения с символом "," btfss flag,2 ; goto visota_1 ;символом "," не обнаружен: переход на метку visota_1 incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка единицы измерения btfsc flag,2 ; goto viv_sp ;обнаружен символ "," единица измерения отсутствует: переход на метку viv_sp movf INDF,W ; call viv_symb ;вывод единицы измерения (M) viv_sp call ust_cur_6 ;вызов подпрограммы установки позиции курсора на Lcd дисплее movf sp_h,W ; call viv_symb ;вывод кол-ва использованных спутников, разряд десятков movf sp_l,W ; call viv_symb ;вывод кол-ва использованных спутников, разряд единиц movlw '/' ; call viv_symb ;вывод символа "/" return ;возврат из подпрограммы gps_gpgga ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;подпрограмма анализа сообщения "GPGSV", поиск и вывод на дисплей кол-ва видимых спутников gps_gpgsv call ust_cur_sp ;вызов подпрограммы установки позиции курсора на Lcd дисплее movlw .2 ;пропуск 2-x параметров movwf temp ; gpgsv_1 incf FSR,F ; call prov_symb ; btfss flag,2 ; goto gpgsv_1 ; decfsz temp,F ; goto gpgsv_1 ; movlw '/' ; call viv_symb ;вывод символа "/" incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка первого символа поля, содержащего кол-во видимых спутников btfsc flag,2 ; return ;обнаружен символ "," нет данных о спутниках: выход из подпрограммы gps_gpgsv movf INDF,W ; call viv_symb ;вывод кол-ва видимых спутников, разряд десятков incf FSR,F ;инкремент регистра FSR call prov_symb ;проверка окончания поля, факт совпадения с символом "," btfsc flag,2 ; return ;обнаружен символ ",": выход из подпрограммы gps_gpgsv movf INDF,W ;вывод кол-ва видимых спутников, разряд единиц call viv_symb ; return ;выход из подпрограммы gps_gpgsv ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Подпрограмма проверки содержимого регистра INDF на совпадение с символом "," prov_symb bcf flag,2 ;сброс флага совпадения movlw ',' ; xorwf INDF,W ; btfss STATUS,Z ; return ;нет совпадения: выход из подпрограммы bsf flag,2 ;есть совпадение: установка флага совпадения return ;выход из подпрограммы viv_not movlw '-' ;Подпрограмма вывода на дисплей сообщения (--- ) call viv_symb ;вывод символа "-" movlw '-' ; call viv_symb ;вывод символа "-" movlw '-' ; call viv_symb ;вывод символа "-" movlw ' ' ; call viv_symb ;вывод символа " " return ;выход из подпрограммы ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Подпрограмма проверки 4-х символов загруженных в память на совпадение с символами хранящиеся в таблице данных ;Сравнение при помощи косвенной адресации srav_gps movwf nomer ;сохранение условного номера символа в таблице данных movlw .5 ;зпись счетчика для отсчета кол-ва сравнений movwf temp ; bcf flag,1 ;сброс флага совпадения символов movlw data_gps ;запись адреса первого регистра (регистры хранения сообщений от movwf FSR ;(модуля GPS) в регистр FSR_prer srav_1 call table ;вызов подпрограммы таблицы данных xorwf INDF,W ;сравнение символа из таблицы данных с символом загруженным в память btfss STATUS,Z ; return ;нет совпадения: выход из подпрограммы incf FSR,F ;есть слвпадение, инкремент регистра FSR incf nomer,F ;инкремент условного номера смивола в иаблице данных decfsz temp,F ;декремент счетчика кол-ва сравнений goto srav_1 ;счетчик не равен нулю: переход на метку srav_1 bsf flag,1 ;счетчик равен нулю: установка флага совпадения символов return ;выход из подпрограммы table movlw high tab ;таблица хранения последовательности ascii символов movwf PCLATH ; movf nomer,W ; addlw low tab ; btfsc STATUS,C ; incf PCLATH,F ; movf nomer,W ; addwf PCL,F ; tab dt 'G', 'P', 'R', 'M', 'C'; ;условный номер первого симаолв = 0 dt 'G', 'P', 'V', 'T', 'G'; ;условный номер первого симаолв = 5 dt 'G', 'P', 'G', 'G', 'A'; ;условный номер первого симаолв = 10 dt 'G', 'P', 'G', 'S', 'V'; ;условный номер первого симаолв = 15 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Здесь приведен неполный код, не отображены подпрограммы инициализации, очистки, вывода символа на дисплей, полную версию можно скачать в конце статьи.
В подпрограмме обработки прерываний происходит прием сообщений и сохранение в регистры ОЗУ 1-го банка. После получения байта по USART, в обработчике прерываний происходит его проверка, при обнаружении символа “$”, с помощью косвенной адресации выбирается первый регистр ОЗУ 1-го банка для загрузки последующих символов. Кроме этого полученный символ проверяется на совпадение со спецсимволом <CR> (возврат каретки), таким образом, определяется конец сообщения, после чего выставляется флаг получения сообщения flag,0. Дополнительно производится отслеживание текущего адреса регистра ОЗУ, на факт переполнения памяти, в случае переполнения загрузка начинается с первого регистра 1-го банка.
В основной программе происходит опрос флага flag,0, при получении сообщения выполняется его анализ. Сначала проверяются первые четыре символа, чтобы определить идентификатор сообщения. С помощью подпрограммы srav_gps выполняется сравнение загруженных символов с символами из таблицы данных table. Если обнаружено совпадение, вызывается соответствующая подпрограмма для анализа полей сообщения.
Подпрограмма gps_gprmc анализирует сообщение RMC, выводит на первую строку дисплея значение времени и статуса достоверности, на вторую строку выводится значение широты, на третью строку значение долготы. Подпрограмма gps_gpvtg анализирует сообщение VTG, выводит значение горизонтальной скорости на 4-ю строку дисплея. Подпрограмма gps_gpgga анализирует сообщение GGA, выводит значение высоты над уровнем моря на 5-ю строку дисплея, а также количество использованных спутников на 6-ю строку дисплея в виде двух цифр и символа “/”. Подпрограмма gps_gpgsv анализирует сообщение GSV, выводит количество видимых спутников на 6-ю строку дисплея в виде символа “/” и двух цифр.
В процессе анализа полей каждый символ, с помощью подпрограммы prov_symb проверяется на совпадение с запятой “,”. Таким образом, определяется конец поля, так как длина некоторых полей может изменяться. Если внутри поля (между запятыми) не обнаружено данных, на дисплей выводится три символа тире и пробел “- – – ”. Если отсутствует статус достоверности или количество видимых/использованных спутников, на дисплее вместо этих данных будут пустые поля.
На открытой местности процесс поиска спутников и определения координат (холодный старт) занимает по времени чуть больше минуты. Горячий старт (после непродолжительного отключения питания) занимает несколько секунд. В квартире на подоконнике поиск может занимать до 10 минут, внутри помещения модуль почти не видит спутников. Раньше всех появляется информация о времени и количестве спутников, позже появляется остальные параметры: координаты, скорость, высота, одновременно с этим меняется значение статуса, появляется символ A, сигнализируя о достоверности данных. К устройству можно подключать GPS приемники других моделей, так как все они работают по стандарту NMEA.
Этот модуль я применил в GPS GSM трекере, в ламповых часах на ИВ-11, а также в часах на газоразрядных индикаторах.
Модуль можно приобрести здесь GPS модуль u-blox NEO-6mv2.
Как связаться с автором?
На странице “Об авторе” есть мои контакты
Хочу заказать в Китае модуль VK2828 и на основе вашей программы сделать так, чтобы с GPS скорость передавалась в стрелочный спидометр машины.
Здравствуйте!
Можно ли изменить прошивку микроконтроллера, чтобы вывести сигнал для коррекции часов, например, раз в час или раз в сутки?
Здравствуйте!
Уровень интерфейса данных LCD дисплея Nokia 5110 – 2.7-5В, подсветка максимум 3.3В, согласно спецификации. Поэтому согласование уровней между линиями ввода/вывода дисплея и микроконтроллера не нужно.