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. 

 

 

 

 

Don't worry, I won't byte.
TimerCallback tutorial! | UART and DMA Idle tutorial!

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. 

 

Don't worry, I won't byte.
TimerCallback tutorial! | UART and DMA Idle tutorial!

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)




Don't worry, I won't byte.
TimerCallback tutorial! | UART and DMA Idle tutorial!

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. 

 

Don't worry, I won't byte.
TimerCallback tutorial! | UART and DMA Idle tutorial!

If you find my solution useful, please click the Accept as Solution so others see the solution.