2024-09-23 12:27 AM
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?
Solved! Go to Solution.
2024-09-23 06:39 AM
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.
2024-09-23 07:02 AM - edited 2024-09-23 08:46 AM
It's not about the size of your source data - it's about the output frame size sent by the UART.
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.
2024-09-23 11:05 AM
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
2024-09-23 08:08 PM - edited 2024-09-23 08:08 PM
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.
2024-09-24 02:51 AM
@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.
2024-09-24 09:01 AM
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.
2024-09-24 09:23 AM
How are you receiving that data?
PC ports and apps won't support 9 bits ...
2024-09-24 12:20 PM
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)
2024-09-25 12:22 AM
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?
2024-09-25 01:52 AM
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.