AnsweredAssumed Answered

Issue with USART RX buffer and char filter

Question asked by anton.bogdan on Sep 12, 2014
Latest reply on Sep 29, 2014 by Clive One

Hello all, i started a little project with my discovery board, using stm32f407vg and a ublox neo 6m gps.
The comunication between the two is done via USART1. At every second the gps sends somewhere at 500bytes over serial, the message in ascii looks like this:

 $GPRMC,173527.00,A,4544.62351,N,02113.50244,E,0.066,,100914,,,D*79\r\n$GPGGA,180351.00,4544.62881,N,02113.50231,E,1,10,0.90,99.2,M,36.8,M,,*65\r\n$GPVTG,,T,,M,0.048,N,0.089,K,D*2B\r\n$GP..... and so on

GPRMC,GPGGA,GPVTG are NMEA standard 183 message ids for gps data, and i want to extract only the GGA data

My rx routine looks like this
void USART1_IRQHandler(void) 
  static uint8_t cnt = 0;   // counts number of characters
  int i;
  if(USART_GetITStatus(USART1, USART_IT_RXNE))   // check if the USART1 receive interrupt flag was set
      char t = USART1->DR;      // character from data reg is stored into t
      if (t != '\r')    // if not end of string
          received_string[cnt] = t; // charstored in receive buffer
          cnt++;    //
      else      // if end detected
          received_string[cnt++] = '\0';    // put terminator character in the end of buffer
          cnt = 0;      // reset character counter
          USART_Puts(USART1, received_string); // send character to terminal
          for (i = 0; i <= MAX_STRLEN+1; i++) // flush buffer
            received_string[i] = '\0';                      

My main concern is to filter only the dat between $GPGGA and its \r\n, i have tryied instead of t !='\r'  to putif (t = 'GGA') .
How can i filter only that part of the data? My experience with serial is very poor, in fact this is my first project with serial dat

 The init code for usart1 is this

#define GPIO_RS232_TX             GPIO_Pin_6
#define GPIO_RS232_RX             GPIO_Pin_7
#define baudrate 9600
NVIC_InitTypeDef NVIC_InitStruct;
void Usart_interrupt_enable(){
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // enable the USART1 receive interrupt
    NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;       //  USART1 interrupts
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;// this sets the priority group of the USART1 interrupts
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;      // this sets the subpriority inside the group
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;             // the USART1 interrupts are globally enabled
    NVIC_Init(&NVIC_InitStruct);                             // the properties are passed to the NVIC_Init function which takes care of the low level stuff
void serial_init(){
USART_InitTypeDef USART_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct; 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);  // enable the peripheral  
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // Enable clock for USART1
GPIO_InitStruct.GPIO_Pin =   GPIO_RS232_TX | GPIO_RS232_RX ;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1); // Serial TX
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1); // Serial Rx
GPIO_Init(GPIOB, &GPIO_InitStruct);
USART_InitStruct.USART_BaudRate = baudrate;             // the baudrate is set to the value we passed into this init function
USART_InitStruct.USART_WordLength = USART_WordLength_8b;// we want the data frame size to be 8 bits (standard)
USART_InitStruct.USART_StopBits = USART_StopBits_1;     // we want 1 stop bit (standard)
USART_InitStruct.USART_Parity = USART_Parity_No;        // we don't want a parity bit (standard)
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // we don't want flow control (standard)
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // we want to enable the transmitter and the receiver
USART_Init(USART1, &USART_InitStruct);                  // again all the properties are passed to the USART_Init function which takes care of all the bit setting