cancel
Showing results for 
Search instead for 
Did you mean: 

Facing issue in HAL_GetTick() whille reading tick on interrupt

Taksh
Associate II

Hello Everyone,

I'm currently working on a project using the STM32L4 micro controller, where I'm developing a multi-level menu system displayed on a Segment LCD. I'm using a magnetic switch connected to a GPIO pin, which is configured to trigger interrupts on both rising and falling edges.

What i am trying to do is,

Main Menu Switching: When the magnetic switch is held for more than 2 seconds, the system should cycle through the main menu options.
Sub menu Navigation: When the magnetic switch is held for 1 second or less, it should allow navigation within the sub menus of the current main menu.
If the switch is held for a duration between 1 to 2 seconds, no action is taken.
Implementation: To achieve this, I use the HAL_GetTick() function to measure the duration for which the magnet is near the switch. Below is a summary of the code:

 

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    switch (GPIO_Pin)
    {
        case BSP_LCD_MAG_SWITCH_Pin:
            METER_DEBUG("Magnetic Interrupt\r\n");
            uint32_t current_time = HAL_GetTick();  // Get the current time in ms
            METER_DEBUG("Current time = %ld\r\n", current_time);

            if (!magnet_near_switch)
            {
                // Rising edge: magnet brought near the switch
                magnet_near_switch = true;
                start_time = current_time;  // Record the start time
                METER_DEBUG("start time = %ld\r\n", start_time);
            }
            else
            {
                // Falling edge: magnet moved away from the switch
                magnet_near_switch = false;
                uint32_t hold_duration = 0;
                hold_duration = current_time - start_time; // Calculate hold time
                METER_DEBUG("hold_duration = %ld\r\n", hold_duration);

                if (hold_duration > 2000)
                {  // Held for more than 2 seconds
                    // Switch between main menus
                    current_menu = (current_menu + 1) % 4; // Cycle through main menus
                    in_submenu = false;  // Exit submenu mode
                    METER_DEBUG("Update main menu display\r\n");
                    update_lcd_menu(current_menu);
                }
                else if (hold_duration <= 1000)
                {  // Held for 1 second or less
                    // Switch between submenus within the current main menu
                    if (in_submenu)
                    {
                        current_submenu = (current_submenu + 1) % 4; // Cycle through submenus
                    }
                    else
                    {
                        in_submenu = true;  // Enter submenu mode if not already in
                        current_submenu = 0;  // Start from the first submenu
                    }
                    METER_DEBUG("Update sub menu display\r\n");
                    update_lcd_submenu(current_menu, current_submenu);
                }
            }
            break;
    }
}

 

Problems I'm Facing:

1)Inconsistent Behavior: Occasionally, the system exits the submenu unexpectedly or doesn't navigate through the main menu as intended.
2)Power Mode Impact: I’m using the sequencer, which places the system in Stop 2 mode during idle states. This seems to affect the accuracy of the HAL_GetTick() function, leading to unreliable timing calculations.

Questions:

1)Timing Accuracy in Low-Power Mode: Is HAL_GetTick() suitable for time measurements in a system that frequently enters Stop 2 mode? If not, what alternatives can I use to get accurate timing, especially for durations like 2 seconds and 1 second?
2)RTC-Based Timing: Would using the RTC peripheral to track the timing be a more reliable approach? If yes, any guidance on implementing RTC-based time tracking in this scenario?

I am not able to get proper time ticks at HAL_GetTick() on an interrupt. please any one suggest me why HAL_GetTick() function not working properly, Did i miss some configuration?

Thanks in advance.

Taksh

2 REPLIES 2

Make sure the SysTick interrupt has a priority setting that preempts everything else, it just has to increment a count, so isn't going to have a significant impact on other execution.

Perhaps use a 32-bit TIM, maximal/free-run, provide for a timebase directly from the TIM->CNT register.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Karl Yamashita
Lead III

If you're using stop mode 2, then Systick is not running. You should use the RTC. You can look at the example code ST provides in the repository that is on your computer. Or you can use the Example selector when you start a new project in STM32CubeIDE

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.