cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F411 Blackpill : fonction HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)

Joel14
Associate II

Bonjour,

j'ai un système communicant avec des cartes identiques possédant des modules STM32F411 CE8 black pill . une carte est maitre et les autres cartes sont toutes esclaves. je suis en mode "UART_TwoBoards_ComPolling"

mon IDE est STM32IDE avec les drivers du STM32Cube_FW_F4_V1.26.2

le maitre transmet HAL_UART_Receive(&huart1, aTxBuffer_UART, nbbytes,510); 

l'esclave reçoit avec HAL_UART_Receive(&huart1, aRxBuffer_UART, nbbytes,500); 

avec

test avec initialisation du soft

"

uint8_t aTxBuffer_UART[40] = {3, 10 , 0, 2, 1, 66,77,88,99, AA};

uint8_t aRxBuffer_UART[40] = {0};

uint8_t nbbytes = 10;

"

la fonction HAL_UART_Receive récupère aRxBuffer_UART[40] = {AA, 3, 10 , 0, 2, 1, 66,77,88,99};

Comme vous pouvez le voir le dernier byte se retrouve à la première position suivi des autres bytes dans le bon ordre. pourtant j'ai un analyseur logique sur la liaison et les bytes sont bien émis dans le bon ordre.

les paramètres d'initialisation de la comm sont les suivantes pour l'ensemble des cartes.

 /* USER CODE END USART1_Init 1 */

 huart1.Instance = USART1;

 huart1.Init.BaudRate = 19200;

 huart1.Init.WordLength = UART_WORDLENGTH_8B;

 huart1.Init.StopBits = UART_STOPBITS_1;

 huart1.Init.Parity = UART_PARITY_NONE;

 huart1.Init.Mode = UART_MODE_TX_RX;

 huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;

 huart1.Init.OverSampling = UART_OVERSAMPLING_16;

 if (HAL_UART_Init(&huart1) != HAL_OK)

 {

  Error_Handler();

 }

 /* USER CODE BEGIN USART1_Init 2 */

 HAL_UART_MspInit(&huart1);

 /* USER CODE END USART1_Init 2 */

Avez vous rencontrez ce genre de problème et comment l'avez vous résolu ? je suis dans l'impasse. j'ai même essayé en mode IT avec HAL_UART_Receive_IT(&huart1, aRxBuffer_UART, nbbytes);  c'est encore pire car là je ne reçois que le 1er byte.

Merci pour vos réponses.

Joël

7 REPLIES 7
TDK
Guru

The first byte received looks to be the last byte from the previous transaction. You need to sync the sender and receiver properly.

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

Thanks you TDK . 

The uart is an asynchronous system and i don't use RTS and CTS.

For you how can I synchronise Tx and Rx ?

regards. Joël

RTS/CTS would be for flow-control, the issue here is where in the cycle you might find the receive and transmitting parties. You're ability to handle startup misalignments, or ones where data-loss might case them to come out of sync with each other.

You'd need some preamble or sync byte so you know you're dealing with the beginning of the next data packet.

Like NMEA sentences with GPS starting with a '$' and ending with a CR/LF pair.

Generally using HAL_UART_Receive() with multiple byte counts reduces your flexibility to address reception and sync issues as they occur.

You could also perhaps use a GPIO to indicate you're about to send new data, and you can flush the UART or abort/restart any pending operation.

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

If the data you're receiving is in bursts, with a delay between them, you could use HAL_UARTEx_ReceiveToIdle with an appropriate timeout value. This will timeout and return, letting you sync up with the start of the next burst of data.

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

Thanks for your quick answers.

I made à very simple program herunder on master and slave. between master and slave I have a cable with 30cm lentgh

Slave program

    while (1)
    {
      /* USER CODE END WHILE */    
	//code dans le slave
 
      /* USER CODE BEGIN 3 */
 
  	      //************synchro tx_rx*****************************
 
  	      uint8_t nbbytes = 2;
  	      HAL_UART_Receive(&huart1, &aRxBuffer_UART[0], nbbytes, 10 );
  	      //*******************************************************
  	      HAL_Delay(10);
    }

Master program

  while (1)
    {
      /* USER CODE END WHILE */   
	//code dans le master
 
      /* USER CODE BEGIN 3 */
  	      //************synchro tx_rx*****************************
  	      aTxBuffer_UART[0] = 0x1 ;  // 10101010
  	      aTxBuffer_UART[1] = 0x2 ;  // 01010101
  	      uint8_t nbbytes = 2;
  	      HAL_UART_Transmit(&huart1, &aTxBuffer_UART[0], nbbytes, 10 );
  	      //*******************************************************
  	      HAL_Delay(10);
 
    }

0693W00000GXQSfQAP.png 

Data ares sent correctly

Reception is all time bad.

0693W00000GXQSQQA5.png0693W00000GXQSfQAP.png 

Tomorrow, I will trie tu use another pin in interrupt mode to launch receive mode because uart interrup mode fail also

Regards.

Joël

Joel14
Associate II

Hello,

I try to use another pin connected to Rx pin. this second pin PB0 is in GPIO_EXTIO mode.

I put the HAL_UART_RECEIVE() function in the EXTI0_IRQ handler

0693W00000GXbTFQA1.pngreceived frame

0693W00000GXbUNQA1.pngreceived frame in rx buffer is allways good whitout rotation in the data. the last bytes in the frame is the time. this is normal that bytes changes beetwen the 2 captures.

0693W00000GXbV6QAL.png

Joel14
Associate II

I write a second message because I don't understand why I cannot use UART_INTERRUP because I have a error handler. due the error handler i use the prvious solution with a second IO in interrupt mode.

Joël

0693W00000GXberQAD.png 

0693W00000GXbfkQAD.png0693W00000GXbg4QAD.png