cancel
Showing results for 
Search instead for 
Did you mean: 

Interupt uart not working nucleo g431rb

NJP.1
Associate III

Hi all i am working in interrupt driven uart uart2 which is connected to the usb port in nucleo -g431rb The interrupt handler is not been called I have shared my code any thoughts kindly share.

void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */
 
  uint32_t isrflags   = READ_REG(huart2.Instance->ISR);
  uint32_t cr1its     = READ_REG(huart2.Instance->CR1);
     if (((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
     {
         
         ch = huart2.Instance->RDR;
         
         HAL_UART_Transmit(&huart2, &ch, 1, 100);
     }
 
 
  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */
 
  /* USER CODE END USART2_IRQn 1 */
}i
 
 
 
 
 
nt 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_TIM1_Init();
  MX_TIM2_Init();
  MX_UART4_Init();
  MX_USART1_UART_Init();
  MX_USART2_UART_Init();
  MX_USART3_UART_Init();
  /* USER CODE BEGIN 2 */
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  uint8_t data[50] = "interupt uart testing\r\n";
  HAL_UART_Transmit (&huart2, data, sizeof (data), 100);
  while (1)
  {
	 // HAL_UART_Transmit (&huart1, data, sizeof (data), 10);
	  if(ch == 'a')
	  {
		  HAL_UART_Transmit (&huart2, data, sizeof (data), 100);
		  ch = 0;
	  }
	 // HAL_UART_Transmit (&huart3, data, sizeof (data), 10);
	 // HAL_UART_Transmit (&huart4, data, sizeof (data), 10);
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

This discussion is locked. Please start a new topic to ask your question.
7 REPLIES 7
gbm
Principal

Have you enabled the RXNE interrupt in UART and UART interrupt in NVIC?

HAL_UART interrupt routine will interfere with your interrupt handling. Maybe you should simply not cal it at all.

sizeof(data) is 50. The string should be defined as const char str [], then its size would be sizeof(str) - 1. ch variable must be volatile.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
Piranha
Chief II

Think why the HAL has functions ending with ***_IT() and ***_DMA().

And learn splitting thoughts into sentences...

NJP.1
Associate III

Thankyou for the reply I got the solution I need to add the below line in the uart init funciton.

"USART2->CR1 |= (USART_CR1_TE | USART_CR1_RXNEIE | USART_CR1_RE | USART_CR1_UE);"

Thankyou for the reply..

Karl Yamashita
Principal
  • You didn't enable UART Rx interrupt.
  • You should use HAL_UART_RxCpltCallback() when saving your data or setting a flag.
  • You need to keep track of HAL status for receive and transmit. Set an error flag for either one so you can test for !HAL_OK and either re-enable Rx interrupt or try and transmit again. I have snippets for the Rx as an example. For Tx, you'll have to figure out how to re-transmit data if HAL status returns HAL_BUSY.
  • Avoid transmitting from an interrupt. Instead save the data to a ring buffer and poll it. Then you can Transmit it from a polling routine.

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_TIM1_Init();
  MX_TIM2_Init();
  MX_UART4_Init();
  MX_USART1_UART_Init();
  MX_USART2_UART_Init();
  MX_USART3_UART_Init();
  /* USER CODE BEGIN 2 */
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
    EnableUART_Interrupt();
  uint8_t data[50] = "interupt uart testing\r\n";
  HAL_UART_Transmit (&huart2, data, sizeof (data), 100);
  while (1)
  {
        if(GetUartEnErrorFlag())
        {
            ClearUartEnErrorFlag();
            EnableUART_Interrupt();
        }
 
	 // HAL_UART_Transmit (&huart1, data, sizeof (data), 10);
	  if(ch == 'a')
	  {
		  HAL_UART_Transmit (&huart2, data, sizeof (data), 100);
		  ch = 0;
	  }
	 // HAL_UART_Transmit (&huart3, data, sizeof (data), 10);
	 // HAL_UART_Transmit (&huart4, data, sizeof (data), 10);
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
 
void EnableUART_Interrupt(void)
{
	if(HAL_UART_Receive_IT(&huart2, ch, 1) != HAL_OK)
	{
		UART_RxEnErrorFlag = true; // set error flag
	}
}
 
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance == huart2.Instance) // check if UART2 caused interrupt
	{
		...// do something with data in ch variable. Typically save byte to a ring buffer for polling in main. Also ch holds the data already so no need to copy from DR register to ch variable.
		EnableUART_Interrupt(); // re-enable interrupt
	}
}
 
bool GetUartEnErrorFlag(void)
{
	return UART_RxEnErrorFlag;
}
 
void ClearUartEnErrorFlag(void)
{
	UART_RxEnErrorFlag = false;
}

I was told that if a devices starts to smoke, put the smoke back in. I guess I never got all the smoke because the device never worked afterwards.
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.

Thankyou for the effort you have put I will implement the missed thing in my code. Thankyou..

Karl Yamashita
Principal

Also for anyone wondering, when you call HAL_UART_Receive_IT(&huart2, ch, 1), you're telling HAL driver to save the incoming data to the ch variable. When HAL_UART_RxCpltCallback is called, ch holds the new data.

I was told that if a devices starts to smoke, put the smoke back in. I guess I never got all the smoke because the device never worked afterwards.
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.