N
N
nemoforum2012-09-26 21:40:45
Microcontrollers
nemoforum, 2012-09-26 21:40:45

STM32: how to call Delay on System Tick Timer from external interrupt handler?

I am new to ARM and in particular STM32. I'm trying to make a delay on the System Tick Timer. The function that implements this is called in the EXTI0 external interrupt handler. After a one-time operation of an external interrupt, it stops working. What am I doing wrong?
STM32VLDiscovery (STM32F100RBT6B). Defines STM32F10X_MD_VL USE_STDPERIPH_DRIVER are specified in the project properties.

#include "stm32f10x.h"

int SysTickDelay=0;

GPIO_InitTypeDef PORT_Init_Struct;

void Delay( unsigned int Val);

int main(void)
{	
//- init ---------------------------------------------------------
// Clock enable
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_USART1 | RCC_APB2ENR_AFIOEN | RCC_APB2Periph_AFIO , ENABLE);
// PortC8|9 Out Push-Pull (LED)
  PORT_Init_Struct.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
  PORT_Init_Struct.GPIO_Speed = GPIO_Speed_50MHz;
  PORT_Init_Struct.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC, &PORT_Init_Struct);
// Interrupts
  AFIO->EXTICR[0] |= AFIO_EXTICR1_EXTI1_PB;
  EXTI->IMR |= EXTI_IMR_MR0;
  EXTI->RTSR |= EXTI_RTSR_TR0;
  NVIC_EnableIRQ(EXTI0_IRQn);
  
//-----------------------------------------------------------------
  SysTick_Config(SystemCoreClock /1000);
  while(1);	
}

void Delay( unsigned int Val)  
{  
  SysTickDelay = Val;  
  while (SysTickDelay != 0); 
}  

void SysTick_Handler(void)  
{  
  if (SysTickDelay != 0)  
  {  
    SysTickDelay--;  
  }  
}  

void EXTI0_IRQHandler(void)
{
  GPIOC->ODR^=GPIO_Pin_8 | GPIO_Pin_9;
  EXTI->PR|=0x01;
  Delay(100);
}

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
smartly, 2012-09-27
@smartly

1. Calling delays from within an interrupt handler is very bad.
2. The Delay function should hang. you need to mark SysTickDelay as volatile.
3. I don't remember about EXTI, but perhaps it needs to be reset explicitly before exiting.

T
Timur Khasanshin, 2016-10-18
@itxs

1. In the EXTI interrupt, you need to clear the interrupt flag in order to be able to re-trigger this interrupt.
2. SysTickDelay must be of type uint32_t, otherwise you are not using the full half of the possible range.
3. It's good that your SysTickDelay is decremented, otherwise there were cases.
4. No interruptions with delays inside! Do it asynchronously, with timers, spinlocks (it's just a flag variable), etc.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question