cancel
Showing results for 
Search instead for 
Did you mean: 

UART2 interrupt skipping received bytes

Indu
Associate II

Hi everyone, i'm using uP STM32F103C8T6 processor and GPS module NEO M6Q with standard uart configuration on 9600 baud-rate .

I enable global UART2 interrupt to receive data from GPS module on every second. But for some reasons, interrupt starts skipping data from GPS module and some data are lost. Also, some times it's just stop working, not the whole device but only UART2. When I receive data to buffer, I parse out GPGGA data and send it out with USB to dock-light.

Does any have idea how to fix this, or maybe have solution for this problem.

0690X00000BvlPBQAZ.jpg

&&&&&&&&&&&&&&&&&&"main.c"&&&&&&&&&&&&&&&&&&
 
 
int main(void)
{
 
	GPIO_InitTypeDef GPIO_InitStruct = {0};
 
	//---HAL_Init---//
	HAL_Init();
	HAL_Delay(10);
 
	//---Config_System_Clock---//
	SystemClock_Config();
	HAL_Delay(10);
 
	//---Config_System_GPIO---//
	MX_GPIO_Init();
	HAL_Delay(10);
 
	//---Set_USB_Class---//
	USB_DEVICE_MasterHardReset();
 
	MX_ADC1_Init();
	HAL_Delay(10);
 
	//---Set_device_mode_status---//
	Device_Flag.Status_Work_Mode = DEBUG;
 
	//---Check_for_battery_voltage_level---//
	//-Make_measuremnt_of_BAT_Voltage_15_times-//
	for(int i = 0; i <= 15; i++)
	{
		Get_ADC1_Battery_Value(YES,NO);
	}
 
	Set_LED_status(ALL_Leds_on,ALL_leds_control);
	//---Wait_for_2_s---//
	HAL_Delay(2000);
	//---Turn_All_LED-s_OFF---//
	Set_LED_status(ALL_Leds_off,ALL_leds_control);
 
	//---Config_System_UART---//
	MX_USART1_UART_Init();
	MX_USART2_UART_Init();
	MX_USART3_UART_Init();
	HAL_Delay(10);
 
	__HAL_UART_ENABLE_IT(&UART2, UART_IT_RXNE); // flag receive
	HAL_Delay(10);
 
	//---Config_TIM2---//
	MX_TIM2_Init();
        MX_TIM3_Init();
	HAL_Delay(10);
 
	//---Set_USB_Class---//
	USB_DEVICE_MasterHardReset();
	HAL_Delay(10);
	MX_USB_DEVICE_Init();
	HAL_Delay(10);
 
	////////////////////////////////////////////////////////////////////////////////////////
	//---Set_LED_To_Default---//
	Set_LED_status(LED_battery_level,ALL_leds_control);
	////////////////////////////////////////////////////////////////////////////////////////
	//---Turn_All_LED-s_OFF---//
	Set_LED_status(ALL_Leds_off,ALL_leds_control);
 
	////////////////////////////////////////////////////////////////////////////////////////
	//---Change_PPS_Pin_WORKING_State---//
	MX_GPIO_Change_PPS_Pin_WORK_State(GPIO_MODE_INPUT);
 
	//---Turn_ON_GPS---//  HAL_GPIO_WritePin(PinA_GPS_EN_PWR_GPIO_Port,PinA_GPS_EN_PWR_Pin,GPIO_PIN_RESET);
	HAL_Delay(10);
 
 
	__HAL_UART_ENABLE_IT(&UART2,UART_IT_RXNE);
 
	//---Enable_UART2_Handler---//
	HAL_UART_IRQHandler(&UART2);
	//HAL_UART_IRQHandler(&UART3);
	HAL_Delay(10);
 
	//---Enable_TIM2_Handler---//
	HAL_TIM_Base_Start_IT(&htim2);
	HAL_TIM_Base_Start_IT(&htim3);
	HAL_Delay(10);
 
  while (1)
  {
 
	  Button_current_work_detection();
 
	  //---Check_battery_voltage---// //--If_voltage_is_low_then_go_in_shutdown_mode---//
	  Get_ADC1_Battery_Value(YES,NO);
 
	  //---Parse_GPS_data_from_module---//
	  GPS_BYTE_STEPPER(GPS_Variable.GPS_UART_RECEIVE);
 
          if((GPS_Variable.GPS_TIME_SEC[0] == '1') && (GPS_Variable.GPS_TIME_SEC[1] == '0')) 
           //Privat function 
  }
}
 
&&&&&&&&&&&&&&&&&&"stm32fxx_it.c"&&&&&&&&&&&&&&&&&&
 
 
void USART2_IRQHandler(void)
{
	/* USER CODE BEGIN USART3_IRQn 0 */
 
	  /* USER CODE END USART3_IRQn 0 */
	 HAL_UART_IRQHandler(&UART2);
	  /* USER CODE BEGIN USART3_IRQn 1 */
 
	 HAL_UART_Receive_IT(&UART2,GPS_Variable.GPS_UART_RECEIVE,256);
 
	 HAL_UART_ErrorCallback(&UART2);
}
 
 
 
&&&&&&&&&&&&&&&&&&"stm32fxx_hal_msp.c"&&&&&&&&&&&&&&&&&&
 
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)
{
  if(htim_base->Instance==TIM2)
  {
  /* USER CODE BEGIN TIM2_MspDeInit 0 */
 
  /* USER CODE END TIM2_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_TIM2_CLK_DISABLE();
 
    /* TIM2 interrupt DeInit */
    HAL_NVIC_DisableIRQ(TIM2_IRQn);
  /* USER CODE BEGIN TIM2_MspDeInit 1 */
 
  /* USER CODE END TIM2_MspDeInit 1 */
  }
  else if(htim_base->Instance==TIM3)
  {
  /* USER CODE BEGIN TIM2_MspDeInit 0 */
 
  /* USER CODE END TIM2_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_TIM3_CLK_DISABLE();
 
    /* TIM2 interrupt DeInit */
    HAL_NVIC_DisableIRQ(TIM3_IRQn);
  /* USER CODE BEGIN TIM2_MspDeInit 1 */
 
  /* USER CODE END TIM2_MspDeInit 1 */
  }
 
}
 
 
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(huart->Instance==USART1)
  {
  /* USER CODE BEGIN USART1_MspInit 0 */
 
  /* USER CODE END USART1_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_USART1_CLK_ENABLE();
  
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART1 GPIO Configuration    
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX 
    */
 
    GPIO_InitStruct.Pin = PinA_TxLORA_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(PinA_TxLORA_GPIO_Port, &GPIO_InitStruct);
 
    GPIO_InitStruct.Pin = PinA_RxLORA_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(PinA_RxLORA_GPIO_Port, &GPIO_InitStruct);
 
 
  /* USER CODE END USART1_MspInit 1 */
  }
  else if(huart->Instance==USART2)
  {
  /* USER CODE BEGIN USART2_MspInit 0 */
 
  /* USER CODE END USART2_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_USART2_CLK_ENABLE();
  
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART2 GPIO Configuration    
    PA2     ------> USART2_TX
    PA3     ------> USART2_RX 
    */
 
 
 
    GPIO_InitStruct.Pin = PinA_TxGPS_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(PinA_TxGPS_GPIO_Port, &GPIO_InitStruct);
 
    GPIO_InitStruct.Pin = PinA_RxGPS_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(PinA_RxGPS_GPIO_Port, &GPIO_InitStruct);
 
    /* USER CODE BEGIN USART1_MspInit 1 */
    HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USART2_IRQn);
 
  /* USER CODE BEGIN USART2_MspInit 1 */
 
  /* USER CODE END USART2_MspInit 1 */
  }
  else if(huart->Instance==USART3)
  {
    /* USER CODE BEGIN USART2_MspInit 0 */
 
    /* USER CODE END USART2_MspInit 0 */
      /* Peripheral clock enable */
      __HAL_RCC_USART3_CLK_ENABLE();
 
      __HAL_RCC_GPIOB_CLK_ENABLE();
      /**USART2 GPIO Configuration
      PA2     ------> USART2_TX
      PA3     ------> USART2_RX
      */
      GPIO_InitStruct.Pin = PinB_TxDebug_Pin;
      GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
      HAL_GPIO_Init(PinB_TxDebug_GPIO_Port, &GPIO_InitStruct);
 
      GPIO_InitStruct.Pin = PinB_RxDebug_Pin;
      GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      HAL_GPIO_Init(PinB_RxDebug_GPIO_Port, &GPIO_InitStruct);
 
      /* USER CODE BEGIN USART1_MspInit 1 */
      HAL_NVIC_SetPriority(USART3_IRQn, 5, 5);
      HAL_NVIC_EnableIRQ(USART3_IRQn);
    /* USER CODE END USART2_MspInit 1 */
    }
 
}
 

1 REPLY 1
KnarfB
Principal III

few thoughts:

GPS_Variable.GPS_UART_RECEIVE is filled by the USART hardware asynchronously. So you cannot read it in the while loop and expect data integrity. This needs synchronization.

Your pattern of using the interrupt is unusual. You should not call HAL_UART_IRQHandler(&UART2); and HAL_UART_ErrorCallback(&UART2); See my comment in HAL_UART_Receive_IT

Without intervention, HAL_UART_Receive_IT(&UART2,GPS_Variable.GPS_UART_RECEIVE,256); calls HAL_UART_RxCpltCallback only after having received 256 bytes. This might be too late ?

Although interrrupt (plus DMA ?!) is more (most) efficient, the code gets more complex. If your while loop doesn't do much more, why not simply using polling (HAL_UART_Receive) ?