STM32H747I-DISCO Virtual Com USART Example
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-01-27 2:27 PM
Hi,
If I understand right USART1 is used in STM32H747I-DISCO board for VCOM. I could not find any example for my board. I would like to want for an 8-byte host command using:
HAL_UART_Receive_IT(&huart1, hostCommand.buffer, 8);
Once a command is received then I process it, I create the answer and wait for the next command. So simple.
Noe: on CN13 pin 13 I see the command from my PC on scope, but the HAL_UART_RECEIVE_IT() never receives anything.
Can sombody send me a short example?
Thanks,
Louie
Solved! Go to Solution.
- Labels:
-
STM32H7 Series
-
UART-USART
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-01-28 8:54 AM
void USART1_IRQHandler(void) // gets called per byte/interrupt
{
HAL_UART_IRQHandler(&huart1); // calls into HAL, it works the buffering and calls your call-back when complete
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle) // call from HAL_UART_IRQHandler
{
// Do something with the filled buffer
..
HAL_UART_Receive_IT(&huart1, hostCommand.buffer, 8); // initate again (returns immediately)
}
void HAL_UART_ErrorCallback(UART_HandleTypeDef *UartHandle)
{
Error_Handler(); // or manage failure
}
main()
{
..
HAL_UART_Receive_IT(&huart1, hostCommand.buffer, 8); // start (returns immediately)
while(1);
}
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-01-27 2:41 PM
You need to be sure the NVIC is enabled for the UART which most people miss.
Don't worry, I won't byte.
TimerCallback tutorial! | UART and DMA Idle with multiple UART instances tutorial!
If you find my solution useful, please click the Accept as Solution so others see the solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-01-27 2:55 PM
Hi Karl,
Thanks for the reply. Of course, it is enabled.
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(huart->Instance==USART1)
{
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART1;
PeriphClkInitStruct.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Peripheral clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART1 GPIO Configuration
PB7 ------> USART1_RX
PA9 ------> USART1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
}
}
Thanks,
Louis
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-01-27 5:32 PM
HAL_UART_Receive_IT() returns immediately, you have to catch the content in the callback.
Make sure the UART is not flagging some kind of status or error, ie noise, framing, etc
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-01-27 11:26 PM - edited ‎2025-01-27 11:51 PM
Hi Tesla DeLoran,
Thanks for the generic answer, but you know the question: How I can do that?
In stm32h7xx_it.c:
void USART1_IRQHandler(void)
{
// RXNE flag will be cleared by reading of RDR register (done in call)
// Call function in charge of handling Character reception
USART1_CharReception_Callback();
// Generated code
// HAL_UART_IRQHandler(&huart1);
}
in main.c:
void USART1_CharReception_Callback(void)
{
// Get ISR register of USART3
uint32_t isr = huart1.Instance->ISR;
// USART_ISR_RXNE_RXFNE = Read Data Register or RX FIFO Not Empty
if (isr & USART_ISR_RXNE_RXFNE)
{
// Read Received character. RXNE flag is cleared by reading of RDR register
hostCommand.buffer[hostCommand.dataIndex++] = (uint8_t)huart1.Instance->RDR;
if (hostCommand.dataIndex >= HOST_CMD_BUF_LENGTH)
hostCommand.dataIndex = 0;
}
}
The interrupt is raised once during startup one and never again.
What is wrong?
Louis
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-01-28 12:10 AM
Hi @Louie88
Are you using the Virtual COM port on ST-Link connection ?
In this case, I'm not sure you are using the right PIN for RX (PB7).
Could you try PA10 instead ?
In DK manuals and schematics, I think PA9/PA10 are mentioned for VCP connection on this board.
Regards
Guenael
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-01-28 1:00 AM
Hi Guenael,
You are absolutely right. Thanks for the note. I never checked the pinouts because those were assigned by STM32CubeMX, when I enabled the USART1 for H7 CPU.
Bit I double checked it. I disable USART1 first then, the PB7 was released (form USART1). But when I enable USART1 again the STM32CubeMX always assigns PB7 instead of PA10 as RX pin. You found a bug in STM32CubeMX, I think.
Currently I am not in the office, but I will check it during this afternoon and report back what I found to you..
Thanks again! It seems to be very valuable notice.
Louis
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-01-28 1:02 AM
@Tesla DeLorean wrote:Make sure the UART is not flagging some kind of status or error, ie noise, framing, etc
@Louie88 wrote:Thanks for the generic answer, but you know the question: How I can do that?
Doesn't the HAL do that - via HAL_UART_IRQHandler() ?
Isn't there a HAL_UART_ErrorCallback() ?
A complex system designed from scratch never works and cannot be patched up to make it work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-01-28 2:18 AM - edited ‎2025-01-28 2:22 AM
That's not a bug. USART1 has 3 user selectable Rx pins, and 3 user selectable Tx pins. You just have to override what CubeMX selects when you enable USART1. So in CubeMX, left click PA9 and PA10 pins and choose USART1 Tx and Rx configuration.
Or search for it. For Rx example, you can see the 3 black pins that are available
Don't worry, I won't byte.
TimerCallback tutorial! | UART and DMA Idle with multiple UART instances tutorial!
If you find my solution useful, please click the Accept as Solution so others see the solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-01-28 2:25 AM
@Louie88 wrote:I never checked the pinouts because those were assigned by STM32CubeMX, when I enabled the USART1
Did you tell CubeMX that it's an STM32H747I-DISCO board?
A complex system designed from scratch never works and cannot be patched up to make it work.
