Search code examples
cgpsinterruptcircular-bufferusart

GPS UART data written multiple times to Buffer


I am receiving/reading data from a GPS module sent via USART3 to the STM32F091. The data gets there just fine which I confirm by sending it to my PC COM3 port and feeding it to 'u-center' (GPS evaulation software).

My problem is that I want to evaluate the data myself in my C program, and for that purpose I feed it into a Ring Buffer, however, every character of the GPS signal is written multiple times to the buffer, instead of one by one.

For example

GGGGGGGPPPPPPPPSSSSSSSS instead of GPS

I am unsure what I'm doing wrong, maybe it's something really obvious I'm overlooking after staring at this code so long.

Here's the relevant code.

stm32f0xx_it.c

#include <main.h>

void USART3_8_IRQHandler(void)
{
    if (USART_FLAG_RXNE != RESET)
    {
        uint16_t byte = 0;
        /* Data reception */

        /* Clear Overrun Error Flag, necessary when RXNE is used */
        USART_GetITStatus(USART3, USART_IT_ORE);

        /* Read from Receive Data Register and put into byte */
        byte = USART_ReceiveData(USART3);

        (*pRXD3).wr = ((*pRXD3).wr + 1) % (*pRXD3).max;
        (*pRXD3).Buffer[(*pRXD3).wr] = byte;

        /* Send Data to PC, and reset Transmission Complete Flag  */
        USART_GetITStatus(USART1, USART_IT_TC);
        USART_SendData(USART1, byte);

        return;
    }
    return;
}

uartGPS.h

....
    struct GPSuart
    {
        BYTE Buffer[255];
        WORD max;
        WORD re;
        WORD wr;
    };
....

main.h

....
extern volatile BYTE B_ser_txd_3[255];
extern volatile BYTE B_ser_rxd_3[255];
extern volatile struct GPSuart TXD_uart_3;
extern volatile struct GPSuart RXD_uart_3;
extern volatile struct GPSuart *pRXD3;
extern volatile struct GPSuart *pTXD3;
....

Let me know if I should provide additional information.


Solution

  • This:

    if (USART_FLAG_RXNE != RESET)
    

    does not test a flag, that code is inspecting the flag constant itself, which is not what you meant.

    You need more code, to access the UART's status register and check the flag:

    if (USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) != RESET)