PDA

View Full Version : Correctly receiving the nmea characters from A2200-A GPS



kimi123
- 3rd November 2016, 09:54
I have been working on this project for a little while, trying to receive the characters from my GPS and then display these characters on a 16x2 LCD. I am using an interrupt on my UART RX pin which allows the program to enter the interrupt service routine when a character is detected which is working.
In the interrupt service routine the NMEA data is then extracted and stored in a 80 character array and then broken down again into smaller arrays to extract the individual data I am wanting to display. However when I do go to display these characters I see nothing.
The LCD part of the program is working perfectly and I can see on my oscilloscope that characters are being transmitted by the GPS, so the problem might be that I am not storing this information properly and I have set the bit rates correctly?
The microcontroller that I am using is the PIC32mx795f512h (http://www.kynix.com/Detail/67092/PIC32MX795F512H-80V%2FMR.html), if anyone might know what my problem might be any help would be hugely appreciated.
Below is my main and interrupt service routine

int32_t main(void)

<code style="margin: 0px; padding: 0px; border: 0px; font-family: Consolas, Menlo, Monaco, &quot;Lucida Console&quot;, &quot;Liberation Mono&quot;, &quot;DejaVu Sans Mono&quot;, &quot;Bitstream Vera Sans Mono&quot;, &quot;Courier New&quot;, monospace, sans-serif; white-space: inherit;">{#ifndef PIC32_STARTER_KIT SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE); InitApp(); //initialise ports & interrupts intLCD(); //initialise LCD clrLCD(); putsLCD("Initialising \n \t TCAS"); // configure for multi-vectored mode INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);//UART1 enable for own gps UARTConfigure(UART1, UART_ENABLE_PINS_TX_RX_ONLY); UARTSetFifoMode(UART1, UART_INTERRUPT_ON_TX_NOT_FULL | UART_INTERRUPT_ON_RX_NOT_EMPTY); UARTSetLineControl(UART1, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1); UARTSetDataRate(UART1, GetPeripheralClock(), 4800); UARTEnable(UART1, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX)); // Configure UART1 RX Interrupt INTEnable(INT_SOURCE_UART_RX(UART1), INT_ENABLED); INTSetVectorPriority(INT_VECTOR_UART(UART1), INT_PRIORITY_LEVEL_2); INTSetVectorSubPriority(INT_VECTOR_UART(UART1), INT_SUB_PRIORITY_LEVEL_0); //UART2 enable for surrounding PORTSetPinsDigitalOut(IOPORT_F, BIT_5); //data transmitter PORTSetPinsDigitalIn(IOPORT_F, BIT_4); //data receiver // enable interrupts INTEnableInterrupts(); //allow uart >300ms to initialise Delayms(5000); gpsINITIALISE(); //initialise GPS to receive data >100ms //main loop int check = 0; while(1) //wait in here for uart interrupt { ValidMsg = NotTrue; //clear valid message variable if(check == 0) { putsLCD("Resend \n \t message"); sendMessages(); //send for gga message check = 1; } if(ValidMsg = True) //check to see if data is valid in main string { putsLCD("Message \n \t Valid"); DisableIntU1RX; //dissable interrupts on uart 1 createString(); //create character string to transmit to nearby aircraft EnableIntU2RX; //enable interrupts on UART2 Delayms(10000); //wait for data to be received from nearby aircraft DisableIntU2RX; //dissable interrupts on uart 2 GPStest(); //display the individual strings } if (ValidMsg = NotTrue) //check to see is not valid { putsLCD("Message1 \n \t Invalid"); for(s=0; s<80; s++) //clear received data string { GGA[s]=0; } sendMessages(); //resend for gga message } }}// U1RX interrupt, majority of GPS relies withinvoid __ISR(_UART_1_VECTOR, ipl6) _U1RXInterrupt(void){ int parse=0; // string counterif(U1STAbits.OERR == 1) U1STAbits.OERR = 0;if(U1STAbits.URXDA) //check if data is ready to be read { c = getcUART1(); while(UARTReceivedDataIsAvailable(UART1)); //check to see if data is available if(c == '$') //c == $, hex=0x0024 { count = 0; } if(count < 6) { dataTest[count] = c; count++; } else if(count > 5 && count < 80) { if(dataTest[4]=='G') //test data string { GGA[count]=c; ValidMsg = True; //data is valid } else //error ValidMsg = NotTrue; //data is valid count++; PORTToggleBits(IOPORT_B, BIT_2); } } //extract data into individual strings x=0; for(parse=1;parse<80;parse++) { if ((parse >=1) & (parse <6)) //Message Type { command[parse-1] = GGA[parse]; } else if ((parse >6) & (parse < 17)) //Time { time[x] = GGA[parse]; x++; if (parse == 16) x=0; } else if ((parse > 17) & (parse < 27)) //Latitude { lat[x] = GGA[parse]; x++; if (parse == 26) x=0; } else if (parse == 28) //Latitude Dir latDir = GGA[parse]; else if ((parse > 29) & (parse < 40)) //Longitude { lon[x] = GGA[parse]; x++; if (parse == 39) x=0; } else if (parse == 41) //Longitude Dir lonDir = GGA[parse]; else if (parse == 43) //Fix Quality fixQ = GGA[parse]; else if ((parse > 51) & (parse < 55)) //altitude { altitude[x] = GGA[parse]; x++; if(parse == 54) x=0; } } INTClearFlag(INT_SOURCE_UART_RX(UART1)); // Clear the RX interrupt Flag </code></pre>}

Demon
- 3rd November 2016, 14:56
Is this C?

You are on a PIC Basic forum. You might get help, maybe.

Robert

Art
- 10th November 2016, 14:28
Hi,
Thereís something very wrong with the formatting of your text you posted!
In that mess it looks like you waste time after seeing serial data, and then hope to catch the start of the next sentence,
and then want data to be aligned at the indexes you expect, which is not how Iíd go about it.

If your GPS has PPS or freq output have you thought to use that to trigger the interrupt?
It is guaranteed that the data will immediately follow that (canít remember if it's the rising or falling edge of the pulse).

Either way, I donít see a need for any delay in the receive routine for a Pic32.
Try Microchipsí own forum, they expect C!