Skip to main content
Associate II
September 23, 2024
Solved

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

  • September 23, 2024
  • 2 replies
  • 4133 views

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?

Best answer by Andrew Neil

@Andrew Neil wrote:


The setting is based on the current configuration of the UART


It's tested at runtime:

 /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */
 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
 {
 pdata8bits = NULL;
 pdata16bits = (const uint16_t *) pData;
 }
 else
 {
 pdata8bits = pData;
 pdata16bits = NULL;
 }

this is where it makes the decision to treat the buffer as 8 or 16 bits.

 


@Andrew Neil wrote:
 whether it is sending 9-bit data frames, or 8-bit data frames.

Clearly, you can't fill a 9-bit data frame from a single 8-bit buffer entry - you need something at least 9 bits.

C doesn't provide a 9-bit datatype - the next available option after 8 bits (single byte) is 16 bits (two bytes).

2 replies

Andrew Neil
Super User
September 23, 2024

See the documentation:

 

/**
 * @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.
 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
 * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits)
 * (as sent data will be handled using u16 pointer cast). Depending on compilation chain,
 * use of specific alignment compilation directives or pragmas might be required
 * to ensure proper alignment for pData.
 * huart UART handle.
 * pData Pointer to data buffer (u8 or u16 data elements).
 * Size Amount of data elements (u8 or u16) to be sent.
 * @retval HAL status
 */
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)

 

See also the User Manual for the HAL; eg,

https://www.st.com/resource/en/user_manual/um2217-description-of-stm32h7-hal-and-lowlayer-drivers-stmicroelectronics.pdf#page=1876

 

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
ManhPhamAuthor
Associate II
September 23, 2024

I read this but I fill data elements, the received data is lost

I fill the byte, I received all data

So this document is not clearly, Size must be 2*data element arry (u16) or 4*data element arry (u32), right?

Andrew Neil
Super User
September 23, 2024

As it says, you use u16 when the UART frame's data payload size is larger than 8 bits - therefore can't be filled using a single u8 item.

So, if you are receiving complete data byte-by-byte, that means your data must fit in 8 bit payloads - so you should not be using a u16 buffer.

Show a minimal but complete complete example which illustrates your issue.

PS:

See also the device Reference Manual - see how the parity and extra data payload bits are handled...

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Senior III
September 23, 2024

By default it is uint8_t which is transmitted via uart. If you want to send integers, convert them to uint8_t and send . in the receiving side you have to take care to assemble it again. Does it answer your question?

"If you feel a post has answered your question, please click ""Accept as Solution""."
Andrew Neil
Super User
September 23, 2024

@Techn wrote:

By default it is uint8_t ?


No.

The setting is based on the current configuration of the UART - whether it is sending 9-bit data frames, or 8-bit data frames.

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Andrew Neil
Andrew NeilBest answer
Super User
September 23, 2024

@Andrew Neil wrote:


The setting is based on the current configuration of the UART


It's tested at runtime:

 /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */
 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
 {
 pdata8bits = NULL;
 pdata16bits = (const uint16_t *) pData;
 }
 else
 {
 pdata8bits = pData;
 pdata16bits = NULL;
 }

this is where it makes the decision to treat the buffer as 8 or 16 bits.

 


@Andrew Neil wrote:
 whether it is sending 9-bit data frames, or 8-bit data frames.

Clearly, you can't fill a 9-bit data frame from a single 8-bit buffer entry - you need something at least 9 bits.

C doesn't provide a 9-bit datatype - the next available option after 8 bits (single byte) is 16 bits (two bytes).

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.