cancel
Showing results for 
Search instead for 
Did you mean: 

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

ControlFreak
Associate III

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)

}

11 REPLIES 11
ControlFreak
Associate III

Here is image of what I am sending and receiving

T J
Lead

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

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

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
Lead

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

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
Lead

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

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
Lead

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.