Skip to main content
Graduate
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?

    This topic has been closed for replies.
    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

    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

     

    ManhPhamAuthor
    Graduate
    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?

    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...

    Graduate II
    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?

    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.

    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).