cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 UART using interrupt transmitts by byte or data elements array?

ManhPham
Associate III

Hello everyone,

I sent the data by UART with command:

uint16_t Size[8];

HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)

Question: Size on this command is 16 bytes or Size is 8 data elements of array?

21 REPLIES 21

no, I transmit array of uint16_t or uint32_t, I ask the size of package is number of byte or element of array?

If uint8_t number of byte = element of array, so I can not distinguish.

It's not about the size of your source data - it's about the output frame size sent by the UART.

  • If your UART is transmitting 8-bit frames, then you need to supply 8-bit buffer entries;
  • If your UART is transmitting 9-bit frames, then you need to supply 16-bit buffer entries, and 7 bits of each entry are unused.

 

PS:

So, if your data is uint32_t, and your UART is set to 8-bit frames, it will take one byte at a time from the buffer, and transmit one byte in each UART frame:

                 +---------------------------------------+---------------------------------------+---------------------------------------+---------------------------------------+
uint32_t         | A7 : A6 : A5 : A4 : A3 : A2 : A1 : A0 : B7 : B6 : B5 : B4 : B3 : B2 : B1 : B0 : C7 : C6 : C5 : C4 : C3 : C2 : C1 : C0 : D7 : D6 : D5 : D4 : D3 : D2 : D1 : D0 |
                 +---------------------------------------+---------------------------------------+---------------------------------------+---------------------------------------+
                 v                                       v                                       v                                       v                                       v
                 +---------------------------------------+                                       v                                       v                                       v
1st 8-bit frame: | A7 : A6 : A5 : A4 : A3 : A2 : A1 : A0 |                                       v                                       v                                       v
                 +---------------------------------------+                                       v                                       v                                       v
                                                         v                                       v                                       v                                       v
                                                         +---------------------------------------+                                       v                                       v
2nd 8-bit frame:                                         | B7 : B6 : B5 : B4 : B3 : B2 : B1 : B0 |                                       v                                       v
                                                         +---------------------------------------+                                       v                                       v
                                                                                                 v                                       v                                       v
                                                                                                 +---------------------------------------+                                       v
3rd 8-bit frame:                                                                                 | C7 : C6 : C5 : C4 : C3 : C2 : C1 : C0 |                                       v
                                                                                                 +---------------------------------------+                                       v
                                                                                                                                         v                                       v
                                                                                                                                         +---------------------------------------+
4th 8-bit frame:                                                                                                                         | D7 : D6 : D5 : D4 : D3 : D2 : D1 : D0 |
                                                                                                                                         +---------------------------------------+

 

if your data is uint32_t, and your UART is set to 9-bit frames, it will take two bytes at a time from the buffer, and transmit 9 bits in each UART frame:

uint32_t         | A7 : A6 : A5 : A4 : A3 : A2 : A1 : A0 : B7 : B6 : B5 : B4 : B3 : B2 : B1 : B0 : C7 : C6 : C5 : C4 : C3 : C2 : C1 : C0 : D7 : D6 : D5 : D4 : D3 : D2 : D1 : D0 |
                 +---------------------------------------+---------------------------------------+---------------------------------------+---------------------------------------+
                 v                                            v                                  v                                            v
                 +--------------------------------------------+                                  v                                            v
1st 9-bit frame: | A7 : A6 : A5 : A4 : A3 : A2 : A1 : A0 : B7 |                                  v                                            v
                 +--------------------------------------------+                                  v                                            v
                                                                                                 v                                            v
                                                                                                 +--------------------------------------------+
2nd 9-bit frame:                                                                                 | B7 : B6 : B5 : B4 : B3 : B2 : B1 : B0 : C7 |
                                                                                                 +--------------------------------------------+

Note that you will lose the top 7 bits from each byte pair taken from your buffer, because it is only a 9-bit frame - it can only take 9 bits.

 

uint16_t Array16[8];

HAL_UART_Transmit_IT(&USART1, (uint8_t *)Array16, sizeof(Array16));

Will send the array as 16 bytes, for a USART in 8-bit mode.

16-bit words being emitted in Little Endian format.

sizeof() computes the byte size of the array in memory

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

Pass the array as uint8_t as that is what the HAL_UART_Transmit_IT is expecting. The HAL driver does not know you're trying to pass uint16_t or uint32_t, so the HAL driver will only transmit the lower byte of each index of the array. 

 

 

 

 

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.

@Karl Yamashita wrote:

Pass the array as uint8_t as that is what the HAL_UART_Transmit_IT is expecting.


Not quite: the HAL_UART_Transmit_IT is expecting either uint8_t or uint16_t - depending on how the UART is configured.

 

@Andrew Neil 

 

So reading the notes ST has

/**
  * @brief Send an amount of data in interrupt mode.
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
  *         the sent data is handled as a set of u16. In this case, Size must indicate the number
  *         of u16 provided through pData.
  * @param huart UART handle.
  * @param pData Pointer to data buffer (u8 or u16 data elements).
  * @param Size  Amount of data elements (u8 or u16) to be sent.
  * @retval HAL status
  */

 

I've tried the 9 bit, no parity and it would only send every first byte of a uint16_t array. That's why i strong heartily said it won't work with uint16_t 

// set for 9,1,n
uint16_t data[] = {0x1122,0x3344,0x5566,0x7788};

HAL_UART_Transmit_IT(&huart2, data, 4);

 // receive
22 44 66 88

 

Today, I tried on another Nucleo board with the same results as above. I then went back to 8,1,n and it does work with uin16_t

// set for 8,1,n
uint16_t data[] = {0x1122,0x3344,0x5566,0x7788};

HAL_UART_Transmit_IT(&huart2, data, 4);

// received
22 11 44 33

 

Unless I'm interpreting the ST notes incorrectly, the 9 bit, no parity, doesn't work as intended. 

 

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.

How are you receiving that data?

PC ports and apps won't support 9 bits ...

I'm using a Nucleo-G431RB, UART1 transmitting to UART3.

As I said, setting for 9 Bit, no parity, does not pass the array as uint16_t as ST's note indicates it should.

If you transmit just normal 8,1,n then it works. 

 

Below is what I ran in debug mode, did a break on the Nop, and copied/pasted the array below

/* USER CODE BEGIN 0 */
uint16_t data[] = {0x1122,0x3344,0x5566,0x7788};
uint8_t data3[8] = {0};

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart == &huart3)
	{
		Nop();
	}
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  MX_USART1_UART_Init();
  MX_USART3_UART_Init();
  /* USER CODE BEGIN 2 */

  HAL_UART_Receive_IT(&huart3, data3, 4);

  HAL_UART_Transmit_IT(&huart1, data, 4);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}



// UART1 Tx 9,1,n
// UART3 Rx 8,1,n

// The Expressions shows how data is received which is not correct
data3[0] uint8_t 0x22 (Hex)
data3[1] uint8_t 0x44 (Hex)
data3[2] uint8_t 0x66 (Hex)
data3[3] uint8_t 0x88 (Hex)
data3[4] uint8_t 0x0 (Hex)
data3[5] uint8_t 0x0 (Hex)
data3[6] uint8_t 0x0 (Hex)
data3[7] uint8_t 0x0 (Hex)



// UART1 Tx 8,1,n
// UART3 Rx 8,1,n

// this is correct
data3[0] uint8_t 0x22 (Hex)
data3[1] uint8_t 0x11 (Hex)
data3[2] uint8_t 0x44 (Hex)
data3[3] uint8_t 0x33 (Hex)
data3[4] uint8_t 0x0 (Hex)
data3[5] uint8_t 0x0 (Hex)
data3[6] uint8_t 0x0 (Hex)
data3[7] uint8_t 0x0 (Hex)




Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.

Did you have both UARTs configured in 9-bit mode?

If you look at the TX line with a scope, do you see the 9th bit being transmitted?

The OP does not want to send 9 bit data. Instead, he wants to transmit the uint16_t as 2 complete bytes, or 16 bits. 

 

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.