Skip to main content
louati-amir
Associate III
June 18, 2013
Question

TIM2 Interrupt problem

  • June 18, 2013
  • 9 replies
  • 1354 views
Posted on June 18, 2013 at 11:25

I write this code witch turn on the 4 leds of the stm32 when pushing the bouttan and after it wait for some time and turn off the 4 leds.

I checked the code without the delay it work fine but whith the delay the program is blocked in the delay function witch mean that the timer_2 interruption don't work :\

if someone can tell me what did I do wrong or what did I miss ?

//------------------the code----------------------

#include ''stm32f4xx.h''

#include ''stm32f4xx_gpio.h''

#include ''stm32f4xx_rcc.h''

#include ''stm32f4xx_tim.h''

uint32_t n_ms=0;

void TIM2_IRQHandler(void)

{

  TIM2->SR &= ~TIM_SR_UIF; // clear IRQ flag in TIM2

  n_ms++;

}

void delay(uint32_t h){

  n_ms=0;

  while(n_ms < h);

}

void init_timer2(void){

  TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;

  TIM_TimeBaseInitStruct.TIM_ClockDivision      = TIM_CKD_DIV4;

  TIM_TimeBaseInitStruct.TIM_CounterMode        = TIM_CounterMode_Up;

  TIM_TimeBaseInitStruct.TIM_Period             = 0;   

  TIM_TimeBaseInitStruct.TIM_Prescaler          = 0xFFFF;

//---------------------------------------------------------

  TIM_DeInit(TIM2);

  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);

  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

}

void init_input_output_pins(void){

  //Setting port_D

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

    GPIO_InitTypeDef  GPIO_InitStructure_D;

      GPIO_InitStructure_D.GPIO_Pin   = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;

      GPIO_InitStructure_D.GPIO_Speed = GPIO_Speed_50MHz;

      GPIO_InitStructure_D.GPIO_Mode  = GPIO_Mode_OUT;

      GPIO_InitStructure_D.GPIO_PuPd  = GPIO_OType_PP;

      GPIO_InitStructure_D.GPIO_OType = GPIO_PuPd_NOPULL;

 

  //Setting port_A

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);    

    GPIO_InitTypeDef  GPIO_InitStructure_A;

      GPIO_InitStructure_A.GPIO_Pin   = GPIO_Pin_0;

      GPIO_InitStructure_A.GPIO_Speed = GPIO_Speed_50MHz;

      GPIO_InitStructure_A.GPIO_Mode  = GPIO_Mode_IN;

      GPIO_InitStructure_A.GPIO_PuPd  = GPIO_OType_PP;

      GPIO_InitStructure_A.GPIO_OType = GPIO_PuPd_DOWN;

  //

 

  GPIO_Init(GPIOA, &GPIO_InitStructure_A);

  GPIO_Init(GPIOD, &GPIO_InitStructure_D);

 

}

void main (void){

  SystemInit();

  init_timer2();

  init_input_output_pins();

   

  while (1) {

    if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)){  

      //turn on leds

      GPIO_WriteBit(GPIOD,GPIO_Pin_12,1);

      GPIO_WriteBit(GPIOD,GPIO_Pin_13,1);

      GPIO_WriteBit(GPIOD,GPIO_Pin_14,1);

      GPIO_WriteBit(GPIOD,GPIO_Pin_15,1);

      //wait some time based on timer interruption

      delay(100);

    }

    else                                

      //turn off leds

      GPIO_WriteBit(GPIOD,GPIO_Pin_12,0);

      GPIO_WriteBit(GPIOD,GPIO_Pin_13,0);

      GPIO_WriteBit(GPIOD,GPIO_Pin_14,0);

      GPIO_WriteBit(GPIOD,GPIO_Pin_15,0);

  };

}
    This topic has been closed for replies.

    9 replies

    waclawek.jan
    Super User
    June 18, 2013
    Posted on June 18, 2013 at 12:18

    > uint32_t n_ms=0;

    No, you want

    volatile uint32_t n_ms=0;

    Check out the volatile keyword in some good C textbook.

    >  TIM2->SR &= ~TIM_SR_UIF; // clear IRQ flag in TIM2

    No, you want

    TIM2->SR = ~TIM_SR_UIF;

    as TIMx_SR bits are rc_w0 (look up in the User Manual what does that mean). But this is not the main problem.

    Also

    >  TIM_TimeBaseInitStruct.TIM_Period             = 0;   

    prevents the timer from running, as TIMx_ARR must be nonzero.

    JW

    louati-amir
    Associate III
    June 18, 2013
    Posted on June 18, 2013 at 13:10

    I tired your advice but it don't worck.

    in the librarie of ''stm32f4xx_TIM.h'' they said

    uint32_t TIM_Period;            /*!< Specifies the period value to be loaded into the active

                                           Auto-Reload Register at the next update event.

                                           This parameter must be a number between 0x0000 and 0xFFFF.*/

    I think that the 0 value is not the problem !

    waclawek.jan
    Super User
    June 18, 2013
    Posted on June 18, 2013 at 13:29

    Well, then you'll have to wait until somebody more versed in the ''library'' explains you why did they say so. Until then, believe me, that it *is* wrong.

    Meantime, you might want to correct other errors in your code; besides those 3 I mentioned above you also neglect to start the timer's clock, and you also don't clear the ''init structs''.

    JW

    louati-amir
    Associate III
    June 18, 2013
    Posted on June 18, 2013 at 13:33

    ok thank you for help :) I will check the timer clk config from the librery but I didn't understand what you mind by clearing the ''init structs''?

    Tesla DeLorean
    Guru
    June 18, 2013
    Posted on June 18, 2013 at 13:43

    Switch the Prescaler and Period values

    Enable the interrupt in the NVIC

    For C++, make sure that the name of the IRQHandler is not mangled (check .MAP, and vector table association)
    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    louati-amir
    Associate III
    June 18, 2013
    Posted on June 18, 2013 at 17:17

    I aded some new ligne after checking all the finction in the ''stm32f4xx_TIM.c'' but it still don't work :s hear is the new code

    void TIM2_IRQHandler(void)

    {

      TIM_ClearFlag(TIM2,TIM_IT_Update);

      TIM_ClearITPendingBit(TIM2,TIM_IT_Update);

      n_ms++;

    }

    void delay(uint32_t h){

      n_ms=0;

      while(n_ms < h);

    }

    void init_timer2(void){

      TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;

      TIM_TimeBaseInitStruct.TIM_ClockDivision      = TIM_CKD_DIV4;

      TIM_TimeBaseInitStruct.TIM_CounterMode        = TIM_CounterMode_Up;

      TIM_TimeBaseInitStruct.TIM_Period             = 255;   

      TIM_TimeBaseInitStruct.TIM_Prescaler          = 0xFFFF;

    //---------------------------------------------------------

      RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, ENABLE);

      TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);

      TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

      TIM_GenerateEvent(TIM2,TIM_IT_Update);

      TIM_InternalClockConfig(TIM2);

    }

    Tesla DeLorean
    Guru
    June 18, 2013
    Posted on June 18, 2013 at 18:10

    I aded some new ligne after checking all the finction in the ''stm32f4xx_TIM.c'' but it still don't work :s hear is the new code

     

    Should I repeat my advice?
    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    louati-amir
    Associate III
    June 18, 2013
    Posted on June 18, 2013 at 18:25

    No you should't !

    I noteced that I forget the NVIC but it's always don't work ! and I switched the value of prescaler and periodique. even if I don't understand why ! For the cheking of IRQHandler I don't know how to do that all what I know : their is an example witch work with that name !

    void init_timer2(void){<
    br
    >
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;<
    br
    >
    TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV4;<
    br
    >
    TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;<
    br
    >
    TIM_TimeBaseInitStruct.TIM_Period = 0xFFFF; <
    br
    >
    TIM_TimeBaseInitStruct.TIM_Prescaler = 255;<
    br
    >
    //---------------------------------------------------------<
    br
    >
    // TIM_DeInit(TIM2);<
    br
    >
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, ENABLE);<
    br
    >
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);<
    br
    >
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);<
    br
    >
    TIM_GenerateEvent(TIM2,TIM_IT_Update);<
    br
    >
    TIM_InternalClockConfig(TIM2);<
    br
    >
    <
    br
    >
    NVIC_InitTypeDef NVIC_InitStructure; //interruption vector structure<
    br
    >
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;<
    br
    >
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;<
    br
    >
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//0->15 the lower the hiest priority<
    br
    >
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//0->15 the lower the hiest priority<
    br
    >
    NVIC_Init(&NVIC_InitStructure);<
    br
    >
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);<
    br
    >
    }

    Tesla DeLorean
    Guru
    June 18, 2013
    Posted on June 18, 2013 at 19:07

    // STM32 TIM2 Delay STM32F4 - sourcer32@gmail.com
    #include ''stm32f4xx.h''
    volatile uint32_t MilliSecondTick = 0;
    /**************************************************************************************/
    void RCC_Configuration(void)
    {
    /* --------------------------- System Clocks Configuration -----------------*/
    /* TIM2 clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    /* GPIOA/D clock enable */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOD, ENABLE);
    }
    /**************************************************************************************/
    void GPIO_Configuration(void)
    {
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    }
    /**************************************************************************************/
    void TIM2_Configuration(void)
    {
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    /* Time base configuration */
    TIM_TimeBaseStructure.TIM_Prescaler = ((SystemCoreClock / 1000000) / 2) - 1; // 1 MHz timebase
    TIM_TimeBaseStructure.TIM_Period = 1000 - 1; // 1 KHz update
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    /* TIM2 enable counter */
    TIM_Cmd(TIM2, ENABLE);
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
    }
    /**************************************************************************************/
    void NVIC_Configuration(void)
    {
    NVIC_InitTypeDef NVIC_InitStructure;
    /* Enable TIM2 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    }
    /**************************************************************************************/
    void TIM2_IRQHandler(void)
    {
    TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
    MilliSecondTick++;
    }
    /**************************************************************************************/
    void Delay(uint32_t ms)
    {
    uint32_t start = MilliSecondTick;
    while((MilliSecondTick - start) < ms);
    }
    /**************************************************************************************/
    int main(void)
    {
    RCC_Configuration();
    NVIC_Configuration();
    GPIO_Configuration();
    TIM2_Configuration();
    while(1) // Don't want to exit
    {
    if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)) // Test Button
    {
    GPIO_SetBits(GPIOD, GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15); // LED's ON
    Delay(100); // 100 ms Delay
    }
    else
    {
    GPIO_ResetBits(GPIOD, GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15); // LED's OFF
    }
    }
    }
    /**************************************************************************************/

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..