cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 Nucleo F429ZI UART RS232 receiving false data

LMüll.1
Associate

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 */
 

2 REPLIES 2

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
Up vote any posts that you find helpful, it shows what's working..
LMüll.1
Associate

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!