Question
Issue with USART RX buffer and char filter
Posted on September 12, 2014 at 07:21
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,173500,A,4562351,N,0250244,E,0.066,,100914,,,D*79\r\n$GPGGA,18000,4562881,N,0250231,E,1,10,0.90,2,M,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 thisvoid 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 Usart_interrupt_enable(); USART_Cmd(USART1, ENABLE); } #nmea #gps #state-machine #fsm