Skip to main content
ControlFreak
Associate III
October 26, 2018
Question

STM32L4+USART+Rx+HAL-------Distortion of received data

  • October 26, 2018
  • 11 replies
  • 1920 views

Hello Everyone,

I am using Nucleo-32 board in my project. I am programming USART to receive 10 character data and then transmit this 10 character data back.

Problem that I am observing is that if accidentally 11 character it is suppose to display error message after that every time I enter 10 character string, my response character shift right+1. Can someone

Please find below code:

HAL_Init();

 SystemClock_Config();

 GPIO_Toggle();

 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);

 __HAL_RCC_USART1_CLK_ENABLE();

 UartHandle.Instance    = USART1;

 UartHandle.Init.BaudRate  = 4800;

 UartHandle.Init.WordLength = UART_WORDLENGTH_8B;

 UartHandle.Init.StopBits  = UART_STOPBITS_1;

 UartHandle.Init.Parity   = UART_PARITY_NONE;

 UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;

 //UartHandle.Init.OverSampling=UART_OVERSAMPLING_16;

 //UartHandle.Init.OneBitSampling=UART_ONE_BIT_SAMPLE_DISABLE;

 UartHandle.Init.Mode    = UART_MODE_TX_RX  ;

 if(HAL_UART_DeInit(&UartHandle) != HAL_OK)

 {

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);

 }

 if(HAL_UART_Init(&UartHandle) != HAL_OK)

 {

 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);

 }

 LTC_2873();

  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET); // Mode RS485

  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_14,GPIO_PIN_RESET); // RS485 Terminator Enable

  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET); // RS485 Driver Enable

  HAL_UART_Transmit_IT( &UartHandle,&aTxBuffer[0],strlen((const char*)aTxBuffer));

  HAL_Delay(1000);

 while(1)

 {

 do

{

   HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET); // RS485 Receiver Enable

 HAL_Delay(20);

   while(HAL_UART_Receive_IT( &UartHandle,&aRx_Buffer[0],10)!=HAL_OK);

   HAL_Delay(20);

}while(rx_cplt!=1);

  HAL_Delay(50);

if(rx_cplt==1)

{

HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET); // RS485 Driver Enable

HAL_Delay(20);

HAL_UART_Transmit_IT( &UartHandle,&aRx_Buffer[0],10);

HAL_Delay(20);

rx_cplt=0;

  }//end of if

 }//end of while(1)

}

This topic has been closed for replies.

11 replies

ControlFreak
Associate III
October 26, 2018

Here is image of what I am sending and receiving

T J
Senior III
October 26, 2018

you should be using the DMA functionality, it works very well and trouble free.

I cannot see where you set rx_cplt, I cannot see where you load the aRx_Buffer for transmission

not a good idea to use the same buffer for Rx and Tx...

then you are not sure which parts are Tx or Rx..

this line seems wrong, you should only turn on the RxInterrupt once...

  while(HAL_UART_Receive_IT( &UartHandle,&aRx_Buffer[0],10)!=HAL_OK); <--- waiting here for HAL_OK

maybe you should change that to:

HAL_UART_Receive_IT( &UartHandle,&aRx_Buffer[0],10);

this one: change to Tx buffer

HAL_UART_Transmit_IT( &UartHandle,&aTx_Buffer[0],10);

ControlFreak
Associate III
October 26, 2018

1) where is rx_cplt is set? :

Answer: It is set in Rx call back function

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)

{

rx_cplt=1;

}

2) Change it to &aRx_Buffer[0]

Answer: I already tried it not, not very helpful

3) Why I am using same buffer for Tx and Rx

Answer: I am trying to Transmit back my received data

4) Why while(HAL_UART_Receive_IT( &UartHandle,&aRx_Buffer[0],10)!=HAL_OK);

Answer: Beacuse I want my while(1) loop- continuous loop to wait here it receives some data for futhur action

ControlFreak
Associate III
October 26, 2018

I will Try with DMA but I guess it will give me same results when I will enter data string more than limit

T J
Senior III
October 26, 2018

you must separate the Rx and Tx buffers...

then you will know what is happening.

HAL_UART_Receive_IT is set and forget... You should not be waiting on this line.

you should only wait for the Rx_Cplt flag.

HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET); // RS485 Receiver Enable
HAL_UART_Receive_IT( &UartHandle,&aRx_Buffer[0],10);
 do
{
 
}while(rx_cplt!=1);

ControlFreak
Associate III
October 26, 2018

You were right I should not have  "while(HAL_UART_Receive_IT( &UartHandle,&aRx_Buffer[0],10)!=HAL_OK);" As I using interrupt method and not polling method. Thank for that

I made a copy of array and then used that copy for Tx,

But I Still see the same issue when I send more than 10 character

T J
Senior III
October 26, 2018

show/zip your code... I am guessing here...

do you have a scope ?

Load TX buffer with "Text1" Transmit, receive into Rx buffer, check your text.

then

Load TX buffer with "DifferentText" Transmit, receive into Rx buffer, check your text

You should be using the DMA functionality.

ControlFreak
Associate III
October 26, 2018

Can you explain me this

#if defined(USART_CR1_FIFOEN)

 uint32_t         FifoMode;         /*!< Specifies if the FIFO mode is being used.

                             This parameter can be a value of @ref UARTEx_FIFO_mode. */

 uint16_t         NbRxDataToProcess;    /*!< Number of data to process during RX ISR execution */

 uint16_t         NbTxDataToProcess;    /*!< Number of data to process during TX ISR execution */

# end if

It is part of STM32l4XX_HAL_USART.h

T J
Senior III
October 26, 2018

I haven't used the L4 series yet, you will have to cope with the slight differences there...

Just use the DMA, it is very good.

Tesla DeLorean
Guru
October 27, 2018

Fixed lengths, and sequential rx and then tx, leave very little room for recovery or resync.

I'd approach this differently. Side step HAL and do a stateful byte level management in the IRQ Handler.

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