cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L151CBU UART 8E1 (Parity) Problem

yldzmuhammed
Associate III

Hello everyone,

I have created a project with STM32L151CBU and used UART2 (PA2, PA3) for communication with some other transceiver IC.

I have configured my UART as follows for (1-bit start, 8 bits data, 1 bit EVEN parity, and 1 bit stop) communication.

	/** USART2 GPIO Configuration
		* PA1     ------> USART2_RTS
		* PA2     ------> USART2_TX
		* PA3     ------> USART2_RX
	*/
	GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pin 	 = IOLink_TxEn_Pin;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	GPIO_InitStruct.Pull          = GPIO_NOPULL;
	GPIO_InitStruct.Mode       = GPIO_MODE_AF_PP;
	GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
	GPIO_InitStruct.Speed	      = GPIO_SPEED_FREQ_VERY_HIGH;
	GPIO_InitStruct.Pin            = IOLink_Tx_Pin | IOLink_Rx_Pin;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
	/* USART2 interrupt Init */
	HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
	HAL_NVIC_EnableIRQ(USART2_IRQn);
	
  huart2.Init.BaudRate 	= 38400;
  huart2.Instance 			= USART2;
  huart2.Init.Mode 		= UART_MODE_TX_RX;
  huart2.Init.StopBits 		= UART_STOPBITS_1;
  huart2.Init.Parity 		= UART_PARITY_EVEN;
  huart2.Init.WordLength 	= UART_WORDLENGTH_9B;
  huart2.Init.HwFlowCtl 	= UART_HWCONTROL_NONE;
  huart2.Init.OverSampling  = UART_OVERSAMPLING_16;
  HAL_UART_Init(&huart2);
	

I have also enabled the receive interrupt and I am getting some data but that is the problem.

Normally I should receive 0xA2, but I am getting sometimes 0x1FD, and mostly 0x69.

The 0x1FD is ok and normal. Because my transmitter device is tries to send 3 different baud rate. When transmits first baud rate data 0xA2, it means in 38400 baud 0x1FD (including parity). But I don't know about the 0x69.

When try to receive or transmit same data from F0 mcu, there is no problem. But I could not successfully receive with this mcu.

By the way, I am checking the data from mcu's rx pin with logic analyzer and everything is as it is.

What is wrong here? What am I missing?

8 REPLIES 8
TDK
Guru

The clock rate is likely off. Since you have a logic analyzer, output MCO or some other known clock source and verify it for accuracy.

> The 0x1FD is ok and normal. 

How are you receiving 9 bits when it's configured for 8 bits? I don't see how transmitting 0xA2 allows you to receive 0x1FD even if the clock rate is off.

> By the way, I am checking the data from mcu's rx pin with logic analyzer and everything is as it is.

Show it.

If you feel a post has answered your question, please click "Accept as Solution".

Hello,

What do you mean by "The clock rate is likely off."? Do you mean there is something wrong with systick or internal/external clock source?

I am going to share related screenshots here.

> Show it.

I attached logic analyzer screenshots. All the data are 0xA2 but with different baud rates. This is IO-Link. So first data in COM1, second COM2 (38400), third COM3 (4800) baud.

0693W00000GW2xmQAD.png0693W00000GW2yGQAT.png 

> I don't see how transmitting 0xA2 allows you to receive 0x1FD even if the clock rate is off.

Since I don't understand what do you mean by clock rate is off, I am not sure how to respond to that. Please explain it to me.

> How are you receiving 9 bits when it's configured for 8 bits?

I configured my USART2 to 9 bits. Why did you say that? Here is the configuration. Am I missing something?

  huart2.Init.BaudRate 	= 38400;
  huart2.Instance 			= USART2;
  huart2.Init.Mode 		= UART_MODE_TX_RX;
  huart2.Init.StopBits 		= UART_STOPBITS_1;
  huart2.Init.Parity 		= UART_PARITY_EVEN;
  huart2.Init.WordLength 	= UART_WORDLENGTH_9B;
  huart2.Init.HwFlowCtl 	= UART_HWCONTROL_NONE;
  huart2.Init.OverSampling  = UART_OVERSAMPLING_16;
  HAL_UART_Init(&huart2);

And here is the UART RX callback

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(ch == 0xA2)
	{
		__breakpoint(0);
		BSP_ReceiveCallback(ch, 0x00);
	}
	
	HAL_UART_Receive_IT(&huart2, &ch, 1);
}
//

0693W00000GW30RQAT.png0693W00000GW30WQAT.png 

I enabled the MCO but I can not see any clock even I set the MCO source as HSI.

I checked for system clock with mco. There is no problem with it. With followed configuration, I can see 4MHz on MCO pin. What else I should check?

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
  /** Configure the main internal regulator output voltage
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8;
  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV3;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses 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_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
  HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_8);
}

TDK
Guru

Why are you changing the baud rate mid stream here? The logic analyzer says there are issues, but that's because you're changing the baud rate.

You should be able to send a known signal at a known baud rate and view that in the logic analyzer to determine if the clock speed is as you expect. That would be step 1 in analyzing the problem. It looks like you're also sending 0x00 in addition to 0xA2.

> I configured my USART2 to 9 bits. Why did you say that?

You said you received 0x1FD. That's 9 bits.

If you feel a post has answered your question, please click "Accept as Solution".

With the 9-bit/Parity mode you need to read the data register as 16-bit, and then mask the low-order 8-bit, otherwise you will also see the parity bit when it is set.

I've got no reason to believe the L151 implementation is broken.

Perhaps try making a complete/concise demo of your issue rather than these piece-meal snippets which don't convey the complete context of the variables, etc.

Check the divisors and register settings. Check signal polarity expectations.

Check HSE_VALUE define.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I am not sure why did you thinking that I am changing the baud but I am not. At least not on purpose.

I found the problem and what was causing it and I fixed it.

The problem was, somehow baud rate changed after my UART init function. That was why I could not be able to receive the correct value/data.

I found this after doing this but before you said :)

> You should be able to send a known signal at a known baud rate and view that in the logic analyzer to determine if the clock speed is as you expect. 

No, I am not actually. That was about the baud rate issue.

> It looks like you're also sending 0x00 in addition to 0xA2.

Now everything is working fine.

Thank you for your support.

It was all about a library mistakes. Thank you anyway.