AnsweredAssumed Answered

Implementing a Delay using TIMERs

Question asked by Greusard Alexandre on Dec 4, 2017
Latest reply on Dec 5, 2017 by Alan Chambers

Hi!

I'm working on an custom board with stm32f107VCT6, and I'm using only standard stm32 library.

 

My problem is that I try to make a simple delay using timer and a variable, but the code stops at the instruction "while" of my Delay wich is called in the TIM5_Handler....

 

If annyone have a clue, it would be very appreciated, I already tried a lot of workaround with no succes... Here is my code:

 

 

__IO uint16_t delay_counter;

int main()

{

       SetSysClockTo72();

 

      SetupLed();   // just Led to  see if the code is runing

 

   SetupTimerDelay();   // the timer used to decrement the delay value

 

   SetupTimerSecond();   // a one second timer wich toggle the led after a brief delay

 

   while(1)   // infinite loop

   {}

 

}

void TIM5_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)
    {
        TIM_ClearITPendingBit(TIM5, TIM_IT_Update);

 

        Delay(20);   // the problematic delay function

        GPIOD->ODR ^= GPIO_Pin_2; //  toggle the "working" led

    }
}

void Delay(uint32_t time)
{
    delay_counter=time;   // wich is decremented in the TIM3_Handler
    while( delay_counter!=0);   // the program stops here, nothing happens then...

}

void TIM3_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
    {
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);

      
        if(delay_counter)
               delay_counter--;  //decrementing the counter
    }
}

 

 

void SetSysClockTo72(void)
{
    RCC_DeInit ();                        // RCC system reset(for debug purpose)
    RCC_HSEConfig (RCC_HSE_ON);           // Enable HSE

 

    // Wait till HSE is ready
    while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);

 

    RCC_HCLKConfig   (RCC_SYSCLK_Div1);   // HCLK   = SYSCLK
    RCC_PCLK2Config  (RCC_HCLK_Div1);     // PCLK2  = HCLK    (APB2)
    RCC_PCLK1Config  (RCC_HCLK_Div2);     // PCLK1  = HCLK/2  (APB1)
    RCC_ADCCLKConfig (RCC_PCLK2_Div4);    // ADCCLK = PCLK2/4

 

    *(vu32 *)0x40022000 = 0x01;           // Flash 2 wait state

 

    // PLLCLK = 8MHz * 9 = 72 MHz
    RCC_PLLConfig ((uint32_t)0x00010000, RCC_PLLMul_9);

 

    // Enable PLL
    RCC_PLLCmd (ENABLE);

 

    // Attente synchronisation PLL
    while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

 

    // Select PLL as system clock source
    RCC_SYSCLKConfig (RCC_SYSCLKSource_PLLCLK);

 

    // Wait till PLL is used as system clock source
    while (RCC_GetSYSCLKSource() != 0x08);

}

void SetupTimerDelay()   //  1ms tick timer

{
    TIM_TimeBaseInitTypeDef TIMER_InitStructure;
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

 

      TIM_TimeBaseStructInit(&TIMER_InitStructure);
    TIMER_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIMER_InitStructure.TIM_Prescaler = SystemCoreClock/10000;     // 0.1 ms
    TIMER_InitStructure.TIM_Period = 10;                        // 0.1 ms * 10 => période = 1 ms
    TIM_TimeBaseInit(TIM3, &TIMER_InitStructure);

 

    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);

 

    TIM_Cmd(TIM3, ENABLE);

 

    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

}

void SetupLed()

{

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOD, &GPIO_InitStructure);

}

void SetupTimerSecond()
{
    TIM_TimeBaseInitTypeDef TIMER_InitStructure;

 

      RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);

 

      TIM_TimeBaseStructInit(&TIMER_InitStructure);
    TIMER_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIMER_InitStructure.TIM_Prescaler = SystemCoreClock/2000;
    TIMER_InitStructure.TIM_Period = 2000;
    TIM_TimeBaseInit(TIM5, &TIMER_InitStructure);

 

    TIM_ITConfig(TIM5, TIM_IT_Update, ENABLE);

 

    TIM_Cmd(TIM5, ENABLE);

 

    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
    NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

 

}

 

Many thanks!

 

Alex.

Outcomes