Skip to main content
Graduate
July 22, 2024
Solved

Why does the value of the variable inside the interrupt not change?

  • July 22, 2024
  • 3 replies
  • 2126 views

In this code, the value of the range variable in the purse does not change correctly. What is the reason?

Board = NUCLEO-F413ZH

/* External variables --------------------------------------------------------*/
extern UART_HandleTypeDef huart4;
extern volatile uint8_t range;
extern uint8_t first_buffer[5];
extern uint8_t main_buffer[8];
/* USER CODE BEGIN EV */

void UART4_IRQHandler(void)
{
 /* USER CODE BEGIN UART4_IRQn 0 */

 /* USER CODE END UART4_IRQn 0 */
 HAL_UART_IRQHandler(&huart4);
 /* USER CODE BEGIN UART4_IRQn 1 */
 //__HAL_UART_ENABLE_IT(&huart4, UART_IT_RXNE);
 if(range == 0) {
	 HAL_UART_Receive_IT(&huart4, first_buffer, 5);
	 range = 1;
 }
 else if(range == 1){
	 HAL_UART_Receive_IT(&huart4, main_buffer, 8);
	 range = 0;
 }
 /* USER CODE END UART4_IRQn 1 */
}

 

    This topic has been closed for replies.
    Best answer by Karl Yamashita

    I just confirmed, writing your code in UART4_IRQHandler doesn't work. range doesn't update.

    But writing your code in the callback works so range changes correctly. 

    3 replies

    Super User
    July 22, 2024

    What if range is not 0 and not 1?

    Graduate
    July 22, 2024

    Hello, the full code is as follows:

     

    main.c:

    /* USER CODE BEGIN Header */
    /**
     ******************************************************************************
     * @file : main.c
     * @brief : Main program body
     ******************************************************************************
     */
    #include "main.h"
    
    UART_HandleTypeDef huart4;
    UART_HandleTypeDef huart3;
    
    PCD_HandleTypeDef hpcd_USB_OTG_FS;
    
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_USART3_UART_Init(void);
    static void MX_USB_OTG_FS_PCD_Init(void);
    static void MX_UART4_Init(void);
    
    volatile uint8_t range = 0;
    uint8_t first_buffer[5];
    uint8_t main_buffer[8];
    
    int main(void)
    {
     HAL_Init();
    
     SystemClock_Config();
    
     MX_GPIO_Init();
     MX_USART3_UART_Init();
     MX_USB_OTG_FS_PCD_Init();
     MX_UART4_Init();
    
     __HAL_UART_ENABLE_IT(&huart4, UART_IT_RXNE);
    
     while (1)
     {
     HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_14);
     HAL_Delay(250);
     }
    }
    
    #endif /* USE_FULL_ASSERT */

     

    stm32f4xx_it.h:

    /* USER CODE BEGIN Header */
    /**
     ******************************************************************************
     * @file stm32f4xx_it.c
     * @brief Interrupt Service Routines.
     ******************************************************************************
     */
    /* USER CODE END Header */
    
    #include "main.h"
    #include "stm32f4xx_it.h"
    
    extern UART_HandleTypeDef huart4;
    extern volatile uint8_t range;
    extern uint8_t first_buffer[5];
    extern uint8_t main_buffer[8];
    
    void UART4_IRQHandler(void)
    {
     HAL_UART_IRQHandler(&huart4);
    
     if(range == 0) {
    	 HAL_UART_Receive_IT(&huart4, first_buffer, 5);
    	 range = 1;
     }
     else if(range == 1) {
    	 HAL_UART_Receive_IT(&huart4, main_buffer, 8);
    	 range = 0;
     }
    }

     

     

    The Range variable measures whether 5 bytes or 8 bytes will be read. However, the variable values do not change properly; sometimes it remains 1 when it should be 0, sometimes the opposite happens, and sometimes it works correctly. But regardless of the situation, it always reads the 5-byte portion the first time it runs, then reads the 8-byte portion without checking the value of the range variable.

    Super User
    July 22, 2024

    Generally, you should be putting HAL_UART_Receive_IT within a user callback such as the receive complete callback. The way it is now, it'll trigger off of any UART IRQ, including each received character. Certainly not what you want. Monitor the return status of HAL_UART_Receive_IT and do something useful when it's something other than HAL_OK.

    Most likely, the variable is changing as it should but bugs in the code are responsible for the bad behavior you're seeing.

    Graduate
    July 22, 2024

    Hello, the full code is as follows:

     

    main.c:

    /* USER CODE BEGIN Header */
    /**
     ******************************************************************************
     * @file : main.c
     * @brief : Main program body
     ******************************************************************************
     */
    #include "main.h"
    
    UART_HandleTypeDef huart4;
    UART_HandleTypeDef huart3;
    
    PCD_HandleTypeDef hpcd_USB_OTG_FS;
    
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_USART3_UART_Init(void);
    static void MX_USB_OTG_FS_PCD_Init(void);
    static void MX_UART4_Init(void);
    
    volatile uint8_t range = 0;
    uint8_t first_buffer[5];
    uint8_t main_buffer[8];
    
    int main(void)
    {
     HAL_Init();
    
     SystemClock_Config();
    
     MX_GPIO_Init();
     MX_USART3_UART_Init();
     MX_USB_OTG_FS_PCD_Init();
     MX_UART4_Init();
    
     __HAL_UART_ENABLE_IT(&huart4, UART_IT_RXNE);
    
     while (1)
     {
     HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_14);
     HAL_Delay(250);
     }
    }
    
    #endif /* USE_FULL_ASSERT */

     

    stm32f4xx_it.c:

    /* USER CODE BEGIN Header */
    /**
     ******************************************************************************
     * @file stm32f4xx_it.c
     * @brief Interrupt Service Routines.
     ******************************************************************************
     */
    /* USER CODE END Header */
    
    #include "main.h"
    #include "stm32f4xx_it.h"
    
    extern UART_HandleTypeDef huart4;
    extern volatile uint8_t range;
    extern uint8_t first_buffer[5];
    extern uint8_t main_buffer[8];
    
    void UART4_IRQHandler(void)
    {
     HAL_UART_IRQHandler(&huart4);
    
     if(range == 0) {
    	 HAL_UART_Receive_IT(&huart4, first_buffer, 5);
    	 range = 1;
     }
     else if(range == 1) {
    	 HAL_UART_Receive_IT(&huart4, main_buffer, 8);
    	 range = 0;
     }
    }

     

    The Range variable measures whether 5 bytes or 8 bytes will be read. However, the variable values do not change properly; sometimes it remains 1 when it should be 0, sometimes the opposite happens, and sometimes it works correctly. But regardless of the situation, it always reads the 5-byte portion the first time it runs, then reads the 8-byte portion without checking the value of the range variable.

     

    Super User
    July 23, 2024

    The code you linked still has the issues I pointed out in my previous reply.

    Graduate II
    July 23, 2024

    I just confirmed, writing your code in UART4_IRQHandler doesn't work. range doesn't update.

    But writing your code in the callback works so range changes correctly. 

    Graduate
    July 23, 2024

    Thanks You Sir!