STM32 HAL UART Recieve Errors - Page 1
Forum section: electronics / general

author: PatrickCPE
author_rank: Newbie
timestamp: January 12, 2022, 09:30:47 pm
content: Hey everyone,I'm having some issues with the STM32 HAL_UART_Receive function. I've posted on the ST forums, but I figure you folks on here are pretty knowledgeable about this sorta thing as well. I'll link my post on the ST forum (It has code snippets and screenshots of the debugging steps I've taken) and I'll just summarize the issue here.Link to ST forums:https://community.st.com/s/question/0D53W00001JAeWZSA1/haluartreceive-polling-mode-only-picks-up-first-character-from-uartI'm trying to read from a GPS module via UART.Expected Behavior:* Read GPS data via USUART1 into a buffer until the buffer is full or timeout occurs* Print a new line to the serial terminal on USUART2* Print the data contained within the Buffer to USUART2Behavior that occurs:* Reads only the first character into the buffer (which maybe it reads one transfer at a time then returns, but this doesn't explain why subsequent reads fail)* New line prints just fine* Buffer data only contains the first char, and will only print once (because besides that the buffer is zeroed out)Debugging Steps:* Connect GPS directly to PC (Works fine, confirmed 9600 baud, no parity, 1 stop bit)* Connect Logic Analyzer to GPS Tx Pin (Works fine, logic analyzer catches the correct GPS Message format)* Debugger on STM32 (Can see that the UART reads into the buffer correctly once, fails for any subsequent read)Any help on this would be much appreciated.Thank you!

author: DavidAlfa
author_rank: Super Contributor
timestamp: January 12, 2022, 09:39:18 pm
content: What's the GPS update rate?

author: PatrickCPE
author_rank: Newbie
timestamp: January 12, 2022, 09:46:44 pm
content: From what I can see 5 Hz.The GPS is a clone of the Neo-6M (my fault for buying china clones, a real datasheet is very nice)Neo-6M datasheet:https://www.u-blox.com/sites/default/files/products/documents/NEO-6_DataSheet_%28GPS.G6-HW-09005%29.pdfLink to the actual GPS module used:https://www.amazon.com/dp/B07P8YMVNT?ref=ppx_yo2_dt_b_product_details&th=1

author: rcbuck
author_rank: Frequent Contributor
timestamp: January 13, 2022, 02:56:22 am
content: You are never going to get this to work with polling. It only takes 1.04 msec for each byte at 9600 baud. You have a 100 msec delay in your main while loop. When you execute that delay you are causing a buffer overrun in the USART receiver and everything stops. Then you have a 1 second delay for some reason.Here is some code I used to read the NMEA input from a NEO-6M and repeat it back out to my PC.Code:void USART1_IRQHandler(void) // Sync and Queue NMEA Sentences{static char rx_buffer; // holding buffer to build line - Global variablestatic int rx_index = 0;if (USART1->SR & USART_SR_RXNE) // Received character?{char rx = (char)(USART1->DR & 0xFF);if ((rx == '\r') || (rx == '\n')) // Is this an end-of-line condition, either will suffice?{if (rx_index != 0) // Line has some content{memcpy((void *)line_buffer, rx_buffer, rx_index); // Copy to static line buffer from dynamic receive bufferline_buffer = 0; // Add terminating NULline_valid = 1; // flag new line valid for processingrx_index = 0; // Reset content pointer}}else{if ((rx == '$') || (rx_index == LINEMAX)) // If resync or overflows pull back to startrx_index = 0;rx_buffer[rx_index++] = rx; // Copy to buffer and increment__NOP();OutChar(rx); // code to repeat incoming data - not needed for GPS clock}}}These are some of the variables that you see in the USART handler. They are at the beginning of the startup code section.Code:/* USER CODE END PTD *//* Private define ------------------------------------------------------------*/#define LINEMAX 80 // Maximal allowed/expected line lengthvolatile char line_buffer[LINEMAX + 1]; // Holding buffer with space for terminating NULvolatile int line_valid = 0;/* USER CODE END PD */I added this code to the USART initialization code the was generated by the IOC tool.Code:/* USER CODE BEGIN USART1_Init 2 */// setup UART interrupt to be handled by USART1_IRQHandler functionHAL_NVIC_SetPriority(USART1_IRQn, 0, 0);HAL_NVIC_EnableIRQ(USART1_IRQn);__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE); // flag receive/* USER CODE END USART1_Init 2 */I was using a blue pill board for my tests. The code above with a lot more code was used to make a 6 digit, 2.3 inch clock. The GPS module provides the time source to the clock so it is never more than a couple of hundred milliseconds off. I used one of the clone boards (not the one you have) and it worked fine. The module on the board is labeled as a Ublox NEO-6M but a label doesn't mean anything for products coming out of China.What are you trying to accomplish? If you simply need the time information I would suggest reprogramming the GPS module so that the only data that it sends out is the $GPRMC string. You can pull the time and date information from that single message.