cancel
Showing results for 
Search instead for 
Did you mean: 

TIM2 Interrupt problem

louati-amir
Associate II
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);

  };

}
9 REPLIES 9
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 II
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 !

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 II
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''?

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 Venmo
Up vote any posts that you find helpful, it shows what's working..
louati-amir
Associate II
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);

}

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 Venmo
Up vote any posts that you find helpful, it shows what's working..
louati-amir
Associate II
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
>
}

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 Venmo
Up vote any posts that you find helpful, it shows what's working..