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, "Lucida Console", "Liberation Mono", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Courier New", 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>}
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, "Lucida Console", "Liberation Mono", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Courier New", 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>}