Skip to main content
IHarg.1
Associate II
February 2, 2023
Solved

Why is HAL_UART_RxCpltCallback running twice for each communication?

  • February 2, 2023
  • 3 replies
  • 2196 views

I am using a STM32L073RZT6 MCU and the Cube IDE V1.11. Using the .IOC, I instantiated UART1 on PB7-6 with global interrupts enabled and a DMA service for RX. On the PC side of things I'm using PuTTy as a sniffer and a UART to USB cable for COMS. I have provided screenshots of the configuration, PuTTy output and code snippets below. Each time I transmit a character to the MCU, the rx callback runs twice, but, on the second go around, the rx buffer seems to be reset and transmits 'None'. While I am confused by this added behavior, I mostly am concerned with why it runs the call back twice. Any guidance would be appreciated. Thank you.

/* USER CODE BEGIN PV */
volatile uint8_t uart_tx_buffer[4];
volatile uint8_t uart_rx_buffer[4];
const uint8_t uart_default_msg[8] = {'W', 'A', 'I', 'T', 'I', 'N', 'G', 0x0D};
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */
 
/* USER CODE END PFP */
 
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
 
/* 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_DMA_Init();
 MX_USART1_UART_Init();
 /* USER CODE BEGIN 2 */
 HAL_UART_Receive_DMA(&huart1, uart_rx_buffer, 1);
 /* USER CODE END 2 */
 
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
 /* USER CODE END WHILE */
 
 /* USER CODE BEGIN 3 */
	HAL_UART_Transmit(&huart1, uart_default_msg, 8, 100);
	HAL_Delay(10000);
 }
 /* USER CODE END 3 */
}
 
 
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
	int i = 0;
	switch(uart_rx_buffer[0]){
		case('p'):
 
			uart_tx_buffer[0] = 'p';
			uart_tx_buffer[1] = 'u';
			uart_tx_buffer[2] = 'l';
			uart_tx_buffer[3] = 's';
			i++;
			HAL_UART_Transmit(&huart1, uart_tx_buffer, 4, 100);
 
			break;
		case('h'):
			uart_tx_buffer[0] = 'h';
			uart_tx_buffer[1] = 'e';
			uart_tx_buffer[2] = 'a';
			uart_tx_buffer[3] = 't';
			i++;
			HAL_UART_Transmit(&huart1, uart_tx_buffer, 4, 100);
 
			break;
		default:
			uart_tx_buffer[0] = 'N';
			uart_tx_buffer[1] = 'o';
			uart_tx_buffer[2] = 'n';
			uart_tx_buffer[3] = 'e';
			HAL_UART_Transmit(&huart1, uart_tx_buffer, 4, 100);
			i++;
			break;
	}
//	HAL_UART_Receive_DMA(&huart1, uart_rx_buffer, 1);
}
/* USER CODE END 4 */

.

0693W00000Y9r3WQAR.png0693W00000Y9r4AQAR.png0693W00000Y9r3RQAR.png

This topic has been closed for replies.
Best answer by KnarfB

How do you transmit the char, pressing ENTER?

You may debug your code and inspect the content of the rx buffer.

hth

KnarfB

3 replies

KnarfB
KnarfBBest answer
Super User
February 2, 2023

How do you transmit the char, pressing ENTER?

You may debug your code and inspect the content of the rx buffer.

hth

KnarfB

IHarg.1
IHarg.1Author
Associate II
February 2, 2023

Yes.. yes I am. That makes perfect sense now, thank you.

C. Mart
Associate II
February 2, 2023

Check out this function: HAL_UARTEx_ReceiveToIdle(_IT/DMA). Its good to know this functions exists if you expect an unknown amount of bytes within a buffer size. An use case would be if you want to receive any word with a length in range from 4 to 8 letters, and you would like to get an interrupt whenever a word comes in, without having to read letter by letter and waiting for an EOT character