0
\$\begingroup\$

I am trying to configure a GPS receiver with PIC16F876A. In the code below i am receiving characters from UART, and checking whether received character is $. If condition is true, receive characters and store it in character array gps until , is seen.

If I type in characters through serial prompt in Linux, code works as it is supposed to. But if I connect it to the GPS receiver I only get first two characters and LCD will show OVERRUN. I am new to PIC. what should I do??

char a, gps[50];
int i, j, k, flag = 0;
void GPS_init()
{
        TXSTA = 0X24; //00100100
        RCSTA = 0X90; //10010000
        SPBRG = 25;
}

char uart_rx()
{
        while(!RCIF);
        //RCIF=0;
        a=RCREG;
        return(a);

}


void GPS()
{
    for(i=0; ;i++)
    {
        a = uart_rx();
        TXREG = a;   //view received data in serial terminal
        while(TRMT == 0);
        data(a); 
        if(OERR == 1)
        {
            command(0Xc0);
            display("OVERRUN"); //Display string to LCD
            CREN = 0;
        }

        if(a == '$')
        {
            gps[0] = '$';
            for(k=1; ;k++)
            {
                gps[k] = uart_rx();
                data(gps[k]);   //display character to LCD
                TXREG = gps[k]; //view received data in serial terminal
                while(TRMT == 0);

                if(gps[k] == ',')
                {
                    gps[k] = '\0';
                    flag = 1;
                    break;      
                }
            }
        }

        if(flag == 1)
        {
            flag = 0;
            break;
        }
    }
}

main()
{
    GPS_init();
    LCD_init();
    command(0x80);
    display("Initializing");
    command(0x01);
    GPS();


    while(1)
    {
        command(0XC0);
        display(gps);
    }

}
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

The overrun error means that you aren't taking the bytes out of the UART receiver as fast as they are coming in. My guess would be that the problem is with this code

while(TRMT == 0);

I assume that this causes execution to pause until the byte put into TXREG has actually been transmitted. This pause is what is killing your ability to keep up with the input.

Bottom line is that you shouldn't be trying to do both processes (receiving and transmitting) in lock-step. You need to use a data buffer (e.g., your gps array) to allow the two processes to run asynchronously.

\$\endgroup\$
5
  • \$\begingroup\$ I put received data in TXREG to see how much data I've received. Even with out it am not able to receive desired data. \$\endgroup\$
    – Athul
    Commented Mar 17, 2018 at 3:24
  • \$\begingroup\$ Today I configured uart as an interrupt, and receive five character after $, and if they are same as GPGGA,, it would print it out on screen. Even pasting large data as this gffgjjkgjgjgjffg\nff\n\rvbgfjffgjjhgjgjgjffg\nff\n\rvbgfggjffg\nff\n\rvbgfjgjhydfgfgffgjjhgjgjgjffgjffg\nff\n\rvbgfjgjhydfgfgffgjjhgjgjgjffg\nff\n\rvbgfjgjhydfgfgffgjjhgjgjgjffg\nff\n\rvbgfjgjhydfgfgffgjjhgjgjgjffg\nff\n\rvbgfjgjhydfgfgfhgty74332365%%#!#$GPRGA,dgfgjhydfgfgfhgty74332365%%#!#$GPGGA,dgf on serial prompt, I could get $GPGA to print on serial prompt. But connecting GPS module wold cause OVERRUN error \$\endgroup\$
    – Athul
    Commented Mar 17, 2018 at 9:31
  • \$\begingroup\$ There's no way I can comment on that without seeing the new code. Add it to your question. \$\endgroup\$
    – Dave Tweed
    Commented Mar 17, 2018 at 11:21
  • \$\begingroup\$ I will update that. \$\endgroup\$
    – Athul
    Commented Mar 18, 2018 at 8:08
  • \$\begingroup\$ I've commented off a=TXREG while(TRMT==0) and data() lines, but still not working. \$\endgroup\$
    – Athul
    Commented Mar 18, 2018 at 8:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.