cancel
Showing results for 
Search instead for 
Did you mean: 

How to use the 'HAL_UART_Receive_IT' within a function?

Marco S
Associate II

Hello,

I'm working with an STM32G4 MCU and I want to listen the UART3 with interruption. I am testing with a code which changes the color of a led. The following code works fine :

//main.c
 
#include "main.h"
 
 
 
FDCAN_HandleTypeDef hfdcan3;
 
FDCAN_HandleTypeDef hfdcan4;
 
 
 
char uart3_buffer[64]={0};
 
uint8_t RxChar3;
 
 
 
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_FDCAN3_Init();
 
 MX_UART4_Init();
 
 MX_USART3_UART_Init();
 
 
 
 /* USER CODE BEGIN 2 */
 
 
 
 
 
 /* USER CODE END 2 */
 
 
 
 /* Infinite loop */
 
 /* USER CODE BEGIN WHILE */
 
 while (1)
 
 {
 
	 	/* Listen the USART3. */
 
		HAL_UART_Receive_IT(&huart3, &RxChar3, 1);
 
 
 
		/* Copy only the non null characters into the buffer. */
 
		if(RxChar3==49){ // ASCII of character 1.
 
			HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1, GPIO_PIN_SET); /* Function to light on a led activating a GPIO. */
 
		}
 
		else if(RxChar3==50){ // ASCII of character 2.
 
			HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);/* Function to light on a led activating a GPIO. */
 
		}
 
		else if(RxChar3==51){ // ASCII of character 3.
 
			HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1, GPIO_PIN_RESET); /* Function to power off a led deactivating a GPIO. */
 
			HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET); /* Function to power off a led deactivating a GPIO. */
 
			HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_RESET); /* Function to power off a led deactivating a GPIO. */
 
		}
 
		else{
 
			HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_SET); /* Function to light on a led activating a GPIO. */
 
		}
 
 
 
		/* Sends the current value of Rxchar3 variable (only for debugging). */
 
		snprintf(uart3_buffer, sizeof(uart3_buffer), "Rxchar3: %u\n", RxChar3);
 
		HAL_UART_Transmit(&huart3, (uint8_t*)uart3_buffer, strlen(uart3_buffer), 0xFFFFFFFF);
 
	 HAL_Delay(500);
 
  /* USER CODE END WHILE */
 
 
 
  /* USER CODE BEGIN 3 */
 
 }
 
 /* USER CODE END 3 */
 
}

Nevertheless, as I have more than one than one serial port configured in the MCU I want to put the 'HAL_UART_Receive_IT' function within another function which receives as input parameter the number of serial interface. I have done as follows:

main.c

//main.c
FDCAN_HandleTypeDef hfdcan3;
FDCAN_HandleTypeDef hfdcan4;
 
char uart3_buffer[64]={0};
uint8_t RxChar3;
 
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_FDCAN3_Init();
  MX_UART4_Init();
  MX_USART3_UART_Init();
 
  /* USER CODE BEGIN 2 */
 
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  	/* Listen the USART3. */
		UART_RX_String01(3); // Listen UART3
 
		/* Copy only the non null characters into the buffer. */
		if(RxChar3==49){  // ASCII of character 1.
			HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1, GPIO_PIN_SET); /* Function to light on a led activating a GPIO. */
		}
		else if(RxChar3==50){  // ASCII of character 2.
			HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);/* Function to light on a led activating a GPIO. */
		}
		else if(RxChar3==51){ //  ASCII of character 3.
			HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1, GPIO_PIN_RESET); /* Function to power off a led deactivating a GPIO. */
			HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET); /* Function to power off a led deactivating a GPIO. */
			HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_RESET); /* Function to power off a led deactivating a GPIO. */
		}
		else{
			HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_SET); /* Function to light on a led activating a GPIO. */
		}
 
		/* Sends the current value of Rxchar3 variable (only for debugging). */
		snprintf(uart3_buffer, sizeof(uart3_buffer), "Rxchar3: %u\n", RxChar3);
		HAL_UART_Transmit(&huart3, (uint8_t*)uart3_buffer, strlen(uart3_buffer), 0xFFFFFFFF);
	  HAL_Delay(500);
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

uart_func.h

//uart_func.h
#ifndef INC_UART_FUNCTIONS_H_
#define INC_UART_FUNCTIONS_H_
 
#include "stm32g4xx_hal.h"
 
extern UART_HandleTypeDef huart3;
extern UART_HandleTypeDef huart4;
 
void UART_RX_String01(uint8_t);
 
#endif /* INC_UART_FUNCTIONS_H_ */

uart_func.c

//uart_func.c
#include "uart_func.h"
void UART_RX_String01(uint8_t port_number){
	uint8_t RxStringBuffer;
	HAL_StatusTypeDef RX_State;
 
	/* Select the UART port to be listened. */
	if (port_number==3){
		RX_State = HAL_UART_Receive_IT(&huart3, &RxStringBuffer, 1);
 
		/* Send the function's return value. */
		snprintf(uart_buffer, sizeof(uart_buffer), "Rx State %u", RX_State);
		HAL_UART_Transmit(&huart3, (uint8_t*)uart_buffer, strlen(uart_buffer), 0xFFFFFFFF);
	}
 
	if (port_number==4){
		RX_State = HAL_UART_Receive_IT(&huart4, &RxStringBuffer, 1);
 
		/* Send the function's return value. */
		snprintf(uart_buffer, sizeof(uart_buffer), "Rx State %u", RX_State);
		HAL_UART_Transmit(&huart4, (uint8_t*)uart_buffer, strlen(uart_buffer), 0xFFFFFFFF);
	}
}

The 'main.h' header file includes the 'uart_func.h' header. The problem I have with this is that in this case the MCU blocks around 20 seconds when I send a character to the serial interface. Then it continues turning. Why does this happen? Or isn't it possible to call this function out of the main.c ?

This discussion is locked. Please start a new topic to ask your question.
11 REPLIES 11

Exactly.

In order to be properly sent, data (located at an address in stack when declared as local) should remain consistent until transfer is completed : that's why it works when adding a delay. Without delay, after function exits, stack content is overwritten by further functions calls and parameters of your code.

Using HAL, use of a buffer declared as local as in your example, is possible only with "polling mode" function : HAL_UART_Transmit()

This function exits only when transfer is completed, so msg buffer content could be overwrtitten without impacting the transfer.

Regards

Totally agree...