STM32 i GPS
W pętli głównej realizowane jest sterowanie diodami LED, wykonywane jest to przez zdefiniowane definicje zapisujące odpowiednie bity do rejestru GPIOB->BSRR. W przypadku gdy uzyskiwane dane od modułu GPS są ważne wyświetlane są one na wyświetlaczu. Realizowane jest to poprzez odczyt z tablicy o odpowiednim indeksie, na listingu przedstawiono proces dla wyświetlania danych o szerokości geograficznej, analogiczne działania przeprowadzane są dla pozostałych informacji. W przypadku braku poprawnych danych na wyświetlaczu w zastępstwie danych o współrzędnych, czasie UTC oraz prędkości prezentowany jest odpowiedni komunikat.
W dalszej części realizowana jest aktualizacja danych tablic służących do generowania pliku .gpx. Proces jest wykonywany tylko w przypadku gdy od modułu GPS uzyskano nowe dane. Należy zwrócić uwagę na fakt iż plik .gpx dane o współrzędnych przechowuje w postaci sss.ssssss (najpierw mamy podane stopnie, następnie część ułamkową stopnia – nie odpowiadają one bezpośrednio wartości minut współrzędnych). Natomiast od modułu GPS dane są w postaci sssmm.mmmm (dwa lub trzy znaki stopnia, minuty, następnie część ułamkowa minut). W związku z powyższym należy wartości te odpowiednio przeliczyć.
Analogicznie postępowanie jest w przypadku aktualizacji pozostałych elementów tablic, wykorzystywanych do generowania pliku .gpx. Dodatkowo w przypadku prędkości należy pamiętać, iż moduł podaje prędkość w km/h natomiast plik .gpx rejestruje prędkość w m/s.
Na samym końcu pętli nieskończonej sprawdzane jest czy aktualnie trwa generowanie pliku .gpx oraz fakt czy generator oczekuje na nowe dane, W takim przypadku ustawiana jest odpowiednia zmienna oraz włączana jest obsługa przerwania UART od TXE (zakończenie transmisji pojedynczego znaku).
Program realizuje obsługę dwóch przerwań. Pierwsze z przerwań odpowiada za obsługę komunikacji pomiędzy mikrokontrolerem a modułem GPS, listing został przedstawiony poniżej.
void USART2_IRQHandler(void) { extern char RxBuffer[256]; extern uint16_t RxCounter; extern char RxBufferVTG[256]; extern char RxBufferRMC[256]; int i = 0; //odbiór danych if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) { //zapis odczytanego znaku RxBuffer[RxCounter] = (USART_ReceiveData(USART2) & 0x7F); //inkrementacja licznika danych RxCounter++; //zabezpieczenie przed wprowadzeniem zbyt długiego ciągu znaków if( (RxBuffer[RxCounter - 2] != '\r') && (RxBuffer[RxCounter - 1] != '\n') && (RxCounter == 255) ) {RxCounter = 253;} //zakończenie transmisji ciągu znakiem nowej linii else if( (RxBuffer[RxCounter - 2] == '\r') && (RxBuffer[RxCounter - 1] == '\n') ) { //odebrany ciąg jest komunikatem VTG if( (RxBuffer[0] == '$') && (RxBuffer[1] == 'G') && (RxBuffer[2] == 'P') && (RxBuffer[3] == 'V') && (RxBuffer[4] == 'T') && (RxBuffer[5] == 'G') ) { //skopiowanie odebranego ciągu do RxBufferVTG //oraz wyzerowanie RxBuffer for(i=0; i<256; i++) { RxBufferVTG[i] = RxBuffer[i]; RxBuffer[i] = 0; } //wyzerowanie licznika RxCounter = 0; } //odebrany ciąg jest komunikatem RMC else if( (RxBuffer[0] == '$') && (RxBuffer[1] == 'G') && (RxBuffer[2] == 'P') && (RxBuffer[3] == 'R') && (RxBuffer[4] == 'M') && (RxBuffer[5] == 'C') ) { //skopiowanie odebranego ciągu do RxBufferRMC //oraz wyzerowanie RxBuffer for(i=0; i<256; i++) { RxBufferRMC[i] = RxBuffer[i]; RxBuffer[i] = 0; } //wyzerowanie licznika RxCounter = 0; } //odebrany ciąg nie należy do oczekiwanych komunikatów else { //wyczyszczenie bufora for(i=0; i<256; i++) {RxBuffer[i] = 0;} //wyzerowanie licznika RxCounter = 0; } } } }
Obsługa przerwania jest rozpoczynana przez odbiór nowego znaku, zapisywany jest on do tablicy buforującej. Zakończenie zapisu do tablicy realizowane jest przez znak nowej linii wysłany przez moduł. W początkowej części zaimplementowano kod zabezpieczający przed wykroczeniem poza zakres tablicy. W dalszej części przerwania realizowane jest przepisanie odebranego ciągu do odpowiedniej tablicy. Proces ten rozpoczyna się w momencie odebrania znaku nowej linii, przepisanie danych do konkretnej tablicy realizowane jest poprzez sprawdzenie nagłówka odebranych danych, w momencie dopasowania bufor jest kopiowany do odpowiedniej tablicy. W przypadku gdy nagłówek nie pasuje do żadnego z oczekiwanych ciągów tablica jest czyszczona, a obsługa przerwania jest kończona.
Drugie obsługiwane przerwanie odpowiada za komunikację pomiędzy zestawem ZL27ARM, a komputerem rejestrującym dane pliku .gpx. Przerwanie jest obsługiwane w przypadku otrzymania nowego znaku lub zakończenia wysyłania znaku. W zależności od odebranego znaku poprzez instrukcje warunkowe następuje zmiana stanu pracy – zgodnie z określonymi założeniami. Natomiast wysyłanie znaków jest zależne od aktualnego stanu pracy generatora pliku .gpx, może ono wysyłać: wstęp pliku, element główny lub zakończenie pliku. Dodatkowo w razie konieczności może przejść do stanu: oczekiwania na nowe dane, zatrzymania generowania pliku lub wyłączenia generowania pliku .gpx. W przypadku zakończenia tworzenia pliku lub oczekiwania na nowe dane następuje wyłączenie przerwania od TXE (zakończenia wysyłania znaku).
Mariusz Dziębowski
m.dziebowski@interia.pl