cancel
Showing results for 
Search instead for 
Did you mean: 

Delay, multi milliseconds, on the STM32F0, again..

XooM
Associate II

where I wrote it among the codes.. // Here I have to wait 500ms.
Can you help me to prevent the timers from being affected by this wait?
Can you give me the codes that I will add. Because I am very confused..

I tried many things but they all stopped the interrupts..

 

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{

	if(htim->Instance==TIM1)
	{
		
	if(input1==0) 
	{
		HAL_GPIO_WritePin(GPIOA, GPIO_Pin_1, GPIO_PIN_SET);
		// Here I have to wait 500ms.
		HAL_GPIO_WritePin(GPIOA, GPIO_Pin_1, GPIO_PIN_RESET);
	}

}

 

 

 

 

 

8 REPLIES 8

It's a bad idea to wait in the interrupt (and the callback is part of the interrupt).

The proper way to solve this is to set a flag (marked volatile) in the interrupt/callback, and in the main loop then perform the pin writes and delay upon that flag.

JW

MM..1
Chief II
HAL_TIM_PeriodElapsedCallback

or any other ISR callbacks is executed in ISR context and can be interrupted only with ISR with higher priority.

Then if you place 500ms here any other same or lower ISR is not executed and blocked and main code too.

Are you sure for this?

KnarfB
Principal III

HAL_Delay would work here if you set the priority of the timer interrupt lower than SysTick. As @waclawek.jan pointed out, spending long time in an interrupt handler is often considered bad style. Alternatives, besides the already suggested shifting to the main loop, could be: using another hardware timer in one pulse mode for firing a precise pulse in a timely manner or even using a RTOS with software timers for placing events in the scheduler time line.

In the end, it all depends on the overall design of your code/system.

hth

KnarfB


@KnarfB wrote:

HAL_Delay would work here if you set the priority of the timer interrupt lower than SysTick.


But could still block other interrupts - depending on their priority.

@XooM - As the others have said, it is generally a Bad Idea to have blocking delays (especially long blocking delays) in an interrupt handler.

Here is a better way:

https://community.st.com/t5/stm32-mcus-embedded-software/how-to-use-hal-gettick/m-p/741355/highlight/true#M56827

https://community.st.com/t5/stm32-mcus-embedded-software/how-to-use-hal-gettick/m-p/741449/highlight/true#M56836

 

Karl Yamashita
Lead III

Looks like your just want to toggle a GPIO? You can use the Systick to accomplish this. Mix the Systick with a timer callback and you can do many cool things. See this video https://www.youtube.com/watch?v=o0qhmXR5LD0

 

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.

As was explained/suggested to you yesterday, in one of your multiple threads on materially the same topic, perhaps just flag that you SET the pin, and have a structure/queue which can down count from 500 in the SysTick / 1 KHz / 1ms task that it needs to RESET the pin when 500ms have elapsed.

You REALLY need to break this one-dimensional thinking where every thing needs to occur in sequential code execution.

The CALLBACK is done under INTERRUPT CONTEXT, you shouldn't be dwelling here for 1/2 SECOND.

If the SysTick has a pre-emption level above this it can continue to count, but like I said doing it this way is just bad thinking.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
volatile uint32_t Tick_PA1_On;  // Time it was turned ON
volatile int PA1_On = 0; // Flag that is is ON

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if(htim->Instance==TIM1)
  {
    if(input1==0)
    {
      HAL_GPIO_WritePin(GPIOA, GPIO_Pin_1, GPIO_PIN_SET); // Turn ON PA1
      Tick_PA1_On = HAL_GetTick();
      PA1_On = 1;
    }
  }
}

...
in main loop, or SysTick Handler ??

  if (PA1_On)
  {
    if ((HAL_GetTick() - Tick_PA1_On) >= 500) // On for 500ms, turn it off now
    {
      HAL_GPIO_WritePin(GPIOA, GPIO_Pin_1, GPIO_PIN_RESET); // Turn OFF PA1
      PA1_On = 0;
    }
  }
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Since my English is not very good, sometimes I can't understand what you say very well. I translate but it is not very accurate either. Short code outputs like the ones you gave me now speed up my understanding. Thank you very much. I will turn on my computer and try this in a moment. Now my way of thinking has changed a little.