stm32-usart-uart-dma-rx-tx
stm32-usart-uart-dma-rx-tx copied to clipboard
F411 USART Low Level Driver Not Work Well
Hi MaJerle,
Sorry to trouble you. I have made my own PCB board with F411 MCU; and I made my USART code by following your example. My issue is: the USART2 does not work well if I use LL driver. This is the init code generated by CubeIDE. ` static void MX_USART2_UART_Init(void) {
/* USER CODE BEGIN USART2_Init 0 */
/* USER CODE END USART2_Init 0 */
LL_USART_InitTypeDef USART_InitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
/* Peripheral clock enable */ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2);
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); /**USART2 GPIO Configuration PA2 ------> USART2_TX PA3 ------> USART2_RX */ GPIO_InitStruct.Pin = LL_GPIO_PIN_2|LL_GPIO_PIN_3; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; GPIO_InitStruct.Alternate = LL_GPIO_AF_7; LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN USART2_Init 1 */
/* USER CODE END USART2_Init 1 / USART_InitStruct.BaudRate = 115200; //USART_InitStruct.BaudRate = 1000000; USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; USART_InitStruct.StopBits = LL_USART_STOPBITS_1; USART_InitStruct.Parity = LL_USART_PARITY_NONE; USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; LL_USART_Init(USART2, &USART_InitStruct); LL_USART_ConfigAsyncMode(USART2); LL_USART_Enable(USART2); / USER CODE BEGIN USART2_Init 2 */
/* USER CODE END USART2_Init 2 */ } `
And this is the function for USART2 to transmit: ` void Start_USART2_Tx(void* data, uint16_t len) { const uint8_t* d = data;
for (; len > 0; --len, ++d) {
LL_USART_TransmitData8(USART2, *d);
while (!LL_USART_IsActiveFlag_TXE(USART2)) {}
}
while (!LL_USART_IsActiveFlag_TC(USART2)) {}
} `
The above code only works when baud rate is <= 115200; when baud rate is higher it hangs at the following line
while (!LL_USART_IsActiveFlag_TXE(USART2)) {}
However, if I use HAL library, my PCB works even baud rate reaches 921600. ` static void MX_USART2_UART_Init(void) {
/* USER CODE BEGIN USART2_Init 0 */
/* USER CODE END USART2_Init 0 */
/* USER CODE BEGIN USART2_Init 1 */
/* USER CODE END USART2_Init 1 / huart2.Instance = USART2; huart2.Init.BaudRate = 921600; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } / USER CODE BEGIN USART2_Init 2 */
/* USER CODE END USART2_Init 2 */ } `
The following code works fine without any hanging. ` while (1) { HAL_UART_Transmit(&huart2, (uint8_t *)"LED ON\r\n", 8, 0xFFFF); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET); HAL_Delay(1000); HAL_UART_Transmit(&huart2, (uint8_t )"LED OFF\r\n", 9, 0xFFFF); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET); HAL_Delay(1000); / USER CODE END WHILE */
/* USER CODE BEGIN 3 */
} `
I have checked HAL_UART_Transmit; it basically also checks USART TXE flags besides some lines of code handling timeout situation. Do you have any idea what could the reason?
Aside using HAL for UART - do you also use HAL for other things when it works?
No, for the working HAL UART code, it only Tx through UART2 to a PC, while my LL code does a little bit more: it also uses UART1 to communicate to another module. However, communications with the two ports are sequential. They don't work at the same time.
The USB to UART cable (TTL-232R-3V3) is 2 meters long. Not sure if it contributes to the problem.
If you use debugger - do you see any UART error status bit set somewhere? Do you have any other interrupt that is not allowing this code to proceed?
For debugger, you mean IDE like Keil, right? How to check UART error status bit? Check the UART register? I haven't looked into it. For testing the baud rate code, I don't have any interrupt enabled. In fact, I follow your code structure to make the UART communication. For Tx, there is no DMA and no interrupt. For Rx, I use DMA and 2 interrupts: buffer full and half full. But my problem happens in the Tx part, the Rx part is not enabled yet. Thx for your time and advice. I will investigate more to find out why.
Keil or IAR or CubeIDE are one of the IDEs. In case of GCC, you can debug even in command line.