Skip to main content
LMüll.1
Associate
January 16, 2020
Question

STM32 Nucleo F429ZI UART RS232 receiving false data

  • January 16, 2020
  • 2 replies
  • 862 views

I'm trying to read GPS-Data on the F429ZI that is sent from a GPS Module (NMEA GGA & VTG) with 38400 Baud but I only receive weird symbols. I tried sending specific values from my PC but they also turn into nonsense on the receive-side.

"U" (85dec / 1010101) is the only symbol that is received correctly. But when I try to send it back to the PC, it also changes value.

Equal values sent produce the same wrong value on the uC but I cant see a relation between sent and received values.

Some Examples:

255dec -> 0

0 -> 0

177dec ->69dec

65dec -> 95dec

I read a lot about these problems that were solved with a change in clock frequencies but cant't make it work for me with any frequency combination.

Thanks for your help!

(I modified a STM UART-Example for my purpose.)

main.h

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H__
#define __MAIN_H__
 
/* User can use this section to tailor USARTx/UARTx instance used and associated
 resources */
 /* Definition for USARTx clock resources */
#define USARTx USART3
#define USARTx_CLK_ENABLE() __HAL_RCC_USART3_CLK_ENABLE()
#define USARTx_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define USARTx_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
 
#define USARTx_FORCE_RESET() __HAL_RCC_USART3_FORCE_RESET()
#define USARTx_RELEASE_RESET() __HAL_RCC_USART3_RELEASE_RESET()
 
/* Definition for USARTx Pins */
#define USARTx_TX_PIN GPIO_PIN_10
#define USARTx_TX_GPIO_PORT GPIOB
#define USARTx_TX_AF GPIO_AF7_USART3
#define USARTx_RX_PIN GPIO_PIN_11
#define USARTx_RX_GPIO_PORT GPIOB
#define USARTx_RX_AF GPIO_AF7_USART3
 
 
#define USER_Btn_Pin GPIO_PIN_13
#define USER_Btn_GPIO_Port GPIOC
#define LD3_Pin GPIO_PIN_14
#define LD3_GPIO_Port GPIOB
#define LD2_Pin GPIO_PIN_7
#define LD2_GPIO_Port GPIOB
 
/* ########################## Assert Selection ############################## */
/**
 * @brief Uncomment the line below to expanse the "assert_param" macro in the 
 * HAL drivers code
 */
/* #define USE_FULL_ASSERT 1U */
 
#ifdef __cplusplus
 extern "C" {
#endif
void _Error_Handler(char *, int);
 
#define Error_Handler() _Error_Handler(__FILE__, __LINE__)
#ifdef __cplusplus
}
#endif
 
#endif /* __MAIN_H__ */

main.c

UART_HandleTypeDef UartHandle;
char RxByte;
 
 
void SystemClock_Config(void);
 
void USART3_IRQHandler(void)
{
	HAL_UART_IRQHandler(&UartHandle);
}
 
void HAL_UART_RxCpltCallback(UART_HandleTypeDef* huart)
{
	if (huart->Instance == USART3)
	{
		/* Receive one byte in interrupt mode */
		HAL_UART_Receive_IT(&UartHandle, &RxByte, 1);
		HAL_UART_Transmit_IT(&UartHandle, &RxByte, 1);
	}
}
 
int main(void)
{
	/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	HAL_Init();
 
	/* Configure the system clock */
	SystemClock_Config();
 
	/*##-1- Configure the UART peripheral ######################################*/
 /* Put the USART peripheral in the Asynchronous mode (UART Mode) */
 /* UART configured as follows:
	- Word Length = 8 Bits (7 data bit + 1 parity bit) :
					BE CAREFUL : Program 7 data bits + 1 parity bit in PC HyperTerminal
	- Stop Bit = One Stop bit
	- Parity = ODD parity
	- BaudRate = 9600 baud
	- Hardware flow control disabled (RTS and CTS signals) */
 
	UartHandle.Instance = USARTx;
	UartHandle.Init.BaudRate = 38400;
	UartHandle.Init.WordLength = UART_WORDLENGTH_9B;
	UartHandle.Init.StopBits = UART_STOPBITS_1;
	UartHandle.Init.Parity = UART_PARITY_NONE;
	UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	UartHandle.Init.Mode = UART_MODE_TX_RX;
	UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
	if (HAL_UART_Init(&UartHandle) != HAL_OK)
	{
		/* Initialization Error */
		Error_Handler();
	}
 
	HAL_UART_MspInit(&UartHandle);
 
	/* Peripheral interrupt init*/
	HAL_NVIC_SetPriority(USART3_IRQn, 0, 0);
	HAL_NVIC_EnableIRQ(USART3_IRQn);
 
	if (HAL_UART_Receive_IT(&UartHandle, &RxByte, 1) != HAL_OK)
	{
		HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, 1);
	}
 
	/* Infinite loop */
	while (1)
	{
		
	}
 
}
 
 
void SystemClock_Config(void) 
{
	RCC_OscInitTypeDef RCC_OscInitStruct;
	RCC_ClkInitTypeDef RCC_ClkInitStruct;
 
	/**Configure the main internal regulator output voltage
	*/
	__HAL_RCC_PWR_CLK_ENABLE();
 
	__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
 
	/**Initializes the CPU, AHB and APB busses clocks
	*/
	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
	RCC_OscInitStruct.HSIState = RCC_HSI_ON;
	RCC_OscInitStruct.HSICalibrationValue = 16; 
	RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
	RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
	RCC_OscInitStruct.PLL.PLLM = 16;
	RCC_OscInitStruct.PLL.PLLN = 72;
	RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; 
	RCC_OscInitStruct.PLL.PLLQ = 7;
	if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
	{
		_Error_Handler(__FILE__, __LINE__);
	}
 
	/**Initializes the CPU, AHB and APB busses clocks
	*/
	RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
		| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
	RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
	RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
	RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
	RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
 
	if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
	{
		_Error_Handler(__FILE__, __LINE__);
	}
 
	/**Configure the Systick interrupt time
	*/
	HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);
 
	/**Configure the Systick
	*/
	HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
 
	/* SysTick_IRQn interrupt configuration */
	HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
 

system_stm32f4xx.c (snippet)

 
#include "stm32f4xx.h"
 
#if !defined (HSE_VALUE) 
 #define HSE_VALUE ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz */ 
#endif /* HSE_VALUE */
 
#if !defined (HSI_VALUE)
 #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/ //DEFAULT 16000000
#endif /* HSI_VALUE */
 

stm32f4xx_hal_conf.h (snippet)

/* ########################## HSE/HSI Values adaptation ##################### */
/**
 * @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
 * This value is used by the RCC HAL module to compute the system frequency
 * (when HSE is used as system clock source, directly or through the PLL). 
 */
#if !defined (HSE_VALUE) 
 #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ //TEST 25000000) //DEFAULT: 8000000U
#endif /* HSE_VALUE */
 
#if !defined (HSE_STARTUP_TIMEOUT)
 #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */
 
/**
 * @brief Internal High Speed oscillator (HSI) value.
 * This value is used by the RCC HAL module to compute the system frequency
 * (when HSI is used as system clock source, directly or through the PLL). 
 */
#if !defined (HSI_VALUE)
 #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ //DEFAULT: 16000000U
#endif /* HSI_VALUE */
 

This topic has been closed for replies.

2 replies

Tesla DeLorean
Guru
January 16, 2020

The STM32 expects CMOS levels, not RS232 ones. Use a MAX3232 or equivalent.

Get a scope and check the baud rate by looking at the bit timing. Most GPS default to 9600 baud.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
LMüll.1
LMüll.1Author
Associate
January 16, 2020

Thank you for your quick response!

The baudrate is stated in the datasheet of the GPS so it should be correct but I'll try to get a RS232 - CMOS Converter

Thanks a lot!