Home > Back-end >  I'm trying to receive UART interrupts
I'm trying to receive UART interrupts

Time:09-07

I want to receive UART interrupts, but shouldn't the basic structure of the interrupts be made like that?

Sometimes it doesn't work and sometimes it prints out printf ("test\r\n") but sometimes it doesn't print out the received data, but I don't know what the cause is Can you tell me the solution?

I tried to pull the HAL_UART_Receive_IT door out while, but it didn't work

I don't think it's a connection problem since I'm sending a message

void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}

When I entered this code, there was an error Error[Li006]: duplicate definitions for "USART1_IRQHandler";

The code below is the code that is currently experiencing a problem

uint8_t received_msg[10]; 
char check_msg[10]; 
//UART read 
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){ 
  if(huart -> Instance == USART1){ 
      printf("test\r\n"); 
       
      HAL_UART_Receive_IT(&huart1, (uint8_t*)received_msg, sizeof(received_msg)); 
 } 
} 
/* 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_I2C1_Init(); 
  MX_TIM6_Init(); 
  MX_USART1_UART_Init(); 
  /* USER CODE BEGIN 2 */ 
  HAL_TIM_Base_Start_IT(&htim6); 
  calibrate(0.01, 4); 
     
  /* USER CODE END 2 */ 
  /* Infinite loop */ 
  /* USER CODE BEGIN WHILE */ 
  while (1) { 
      rcvStat = HAL_UART_Receive_IT(&huart1, received_msg, sizeof(received_msg)); 
      if(rcvStat != HAL_OK){ 
          printf("error\r\n"); 
     } 
     sprintf(check_msg, "%s", (char*)received_msg); 
     printf("%s\r\n", check_msg); 
      
      
     printf("%d, %d\r\n", timer, flag); 
      
     HAL_Delay(timer); 
      
     printf("---------------------\r\n"); 
     memset(received_msg, 0, strlen(received_msg)); 
     memset(check_msg, 0, strlen(check_msg)); 
      
      
     /* USER CODE END WHILE */ 
     /* USER CODE BEGIN 3 */ 
} 
/* USER CODE END 3 */ 
} 

CodePudding user response:

I do not have enough reputation to comment. So this is not an answer but rather a suggestion.

  1. Here the UART interrupt will be triggered just after receiving 10 bytes of data. (uint8_t received_msg[10];). So while debugging as mentioned sometimes the interrupt is triggered, but did always receive the exact 10 bytes of data?

  2. The HAL_UART_Receive_IT(&huart1, received_msg, sizeof(received_msg)); initializes the interrupt. So it is kind of strange for me to call the function in the while loop.

CodePudding user response:

Call the RX interrupt once before the while loop and then after you have recieved the data in the ISR. Remove it from the inside of the while.

It seems like in the update loop you are re-issuing the RX_IT call, you should call this once and wait for data to arrive (ISR fires) and then re-issue at that point inside of ISR. Otherwise with a message size greater than one byte, you could re-issue the IT function after it recieved a few bytes and miss some bytes since it requests 10 bytes before the interrupt fires after being issued once.

Your ISR should primarily only be there for moving the RX'd data from one spot, to another for processing. Printf is a pig and will most likely cause you to miss messages coming in if they are coming in real-time and not a one-off message.

A suggestion, would be to implement some type of circular FIFO queue in the ISR which stuffs the data in a FIFO buffer and that FIFO is accessed in your control loop for parsing, or action. That way, you are reciving each symbol and quickly exiting the interrupt and all data should be there for processing. I have had great success with this method in the past.

  • Related