I am trying to understand how I can setup the UART peripheral to receive 9 bit data blocks.

I am using the ST IDE (STM32 cube IDE) and the Nucleo-F103RB board. I can setup the peripheral in 9bit mode using the STM32 Cube. But the HAL function to transmit/receive data still uses an 8bit pointer to a data buffer.

HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);

How can I receive the 9th bit?

  • \$\begingroup\$ First, you need to specify exactly which STM32 as there is substantial difference across the product line. Next you should look at the actual HAL source code; or it may well be that it is best to simply write your own UART receive code - somewhat uniquely in the case of the UART, whoever wrote ST's code seems to have a somewhat different idea of what one would want it to do than what most projects actually turn out to need - even without the 9th bit concern. \$\endgroup\$ Commented Sep 3, 2019 at 20:47
  • \$\begingroup\$ @ChrisStratton I updated the question; it's the nucleo F103rb board. I would really appreciate some guidance. Where would I begin when I want to write my own UART receive code? Would that mean stepping away completely from the HAL? So I'd have to setup the UART peripheral on my own too then? PS: so I was correct that the HAL doesn't support receiving/transmitting 9 bit UART? Because I read on a ST community Q&A thread that they proposed to just cast it to a uint16_t pointer (which would surprise me if that would work...) \$\endgroup\$
    – bas
    Commented Sep 3, 2019 at 21:37
  • \$\begingroup\$ Again, read the existing code \$\endgroup\$ Commented Sep 3, 2019 at 21:38
  • \$\begingroup\$ OK, will dive into their source files too \$\endgroup\$
    – bas
    Commented Sep 3, 2019 at 21:41

1 Answer 1


If you are trying to stuff 9 bits of data into an 8 bit integer, that simply wont work. The compiler would likely cut off the 9th bit, or complain you didn't pass it an array.

You will need to pass it an array of 8 bit integers large enough to capture your received data. In this case, you would need 2 8 bit integers, giving you 16 bits of bit-space for the API to stuff its 9 bits into. The HAL function will write to both integers in the array you passed it. You will need to apply some fancy bit-masking and typecasting to massage the buffer into a native type, or decompose it further into whatever schema you have devised.

  • \$\begingroup\$ Thx for the answer, I have more homework to do :). \$\endgroup\$
    – bas
    Commented Sep 3, 2019 at 21:42
  • \$\begingroup\$ I don't agree with this answer. The STM32F1's UARTs have a programmable data word length of 8 or 9 bits. It is set in the field WordLength of the the UART_InitTypeDef. The receive buffer will require 2 bytes for each 9 bit value. The least significant bits are in the first byte and the ninth bit in the second byte. \$\endgroup\$
    – Codo
    Commented Sep 4, 2019 at 6:35
  • \$\begingroup\$ @Codo, I assumed the API is calling for a uint8_t. Thus, to receive 9 bits, we would need to pass an uint8_t array of size 2 to capture all the bits. I think we are in agreement here... what don't you agree with? \$\endgroup\$
    – gregb212
    Commented Sep 4, 2019 at 14:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.