cancel
Showing results for 
Search instead for 
Did you mean: 

weird problem with clocks and timers

enrico239955_st
Associate II
Posted on May 27, 2014 at 12:04

Hi all,

at the moment I am trying to configure the update interrupt of timer 2 like this. The update interrupt should occur every 4ms. With the following code everything is fine, the pin is toggling every 4 ms.

TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
// TIM clock enable
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// Time base configuration
TIM_TimeBaseStructure.TIM_Prescaler = 9; 
// (9+1) * 1/84MHz = 119ns
TIM_TimeBaseStructure.TIM_Period = 33600; 
// 119ns * 33600 = 4ms
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
// Enable the TIM Interrupt
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// enable it and timer
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM2, ENABLE);
...
void
TIM2_IRQHandler(
void
){
GPIOD->ODR ^= GPIO_Pin_15; 
//toggle
// tim update
if
((TIM2->SR & TIM_IT_Update) != (uint16_t)RESET){
TIM2->SR = (uint16_t)~TIM_IT_Update;
}
}

but if I try to do the same with timer 1, the frequency is not as expected but veeeeery slow (600ms)

TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
// TIM clock enable
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM1, ENABLE);
// Time base configuration
TIM_TimeBaseStructure.TIM_Prescaler = 19; 
// (19+1) * 1/168MHz = 119ns
TIM_TimeBaseStructure.TIM_Period = 33600; 
// 119ns * 33600 = 4ms
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
// Enable the TIM Interrupt
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// enable it and timer
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM1, ENABLE);
...
void
TIM1_UP_TIM10_IRQHandler(
void
){
GPIOD->ODR ^= GPIO_Pin_15; 
//toggle
// tim update
if
((TIM1->SR & TIM_IT_Update) != (uint16_t)RESET){
TIM1->SR = (uint16_t)~TIM_IT_Update;
}
}

Does somebody has an explanation for this behavior?
11 REPLIES 11
chen
Associate II
Posted on May 27, 2014 at 12:58

Hi

You have not said which STM32 processor you are using.

I think that TIM1 and TIM2 are on different peripheral bus (AHB and APB) and therefore may be clocked by a different clock rate, hence you are getting different periods from each timer.

Please refer to the reference manual.

enrico239955_st
Associate II
Posted on May 27, 2014 at 13:14

Its a STM32F407VG.

Yes they are on different peripherals, thats why I set different prescaler. So the output should be the same, but the output is significant different! It seems that TIM1 is running with a very slow clock, but I did not change the clock between these two examples! I also tried different periods and different boards. Everywhere the same result.
chen
Associate II
Posted on May 27, 2014 at 13:53

''Yes they are on different peripherals, thats why I set different prescaler. ''

Sorry, did not spot that.

Timer1 is a special timer, it is a 32bit timer (TIM2 is a general purpose timer - only 16bit). Please check the reference manual for other difference - may explain another difference which is cause of you r problem.

enrico239955_st
Associate II
Posted on May 27, 2014 at 14:30

The Tim1 is a 16bit timer, tim2 is a 32bit timer :) but my prescaler or period value is within 16bit, so it should not lead to an overflow.

I already studied the refman, thats why I posted in this forum. Maybe an expert from stm can help me.

Posted on May 27, 2014 at 15:34

Crappy cut-n-paste job...

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
// TIM clock enable
RCC_APB2PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // APB2 @ 84 MHz, TIM1CLK @ 168 MHz
// Time base configuration
TIM_TimeBaseStructure.TIM_Prescaler = 20-1; // 168/20 = 8.4 MHz
TIM_TimeBaseStructure.TIM_Period = 33600-1; // 8.4 MHz / 33600 = 250 Hz
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
// Enable the TIM Interrupt
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// enable it and timer
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM1, ENABLE);
...
void TIM1_UP_TIM10_IRQHandler(void)
{
// tim update
if (TIM1->SR & TIM_IT_Update)
{
TIM1->SR = ~TIM_IT_Update;
GPIOD->ODR ^= GPIO_Pin_15; //toggle
}
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
enrico239955_st
Associate II
Posted on May 27, 2014 at 18:22

thats almost what i posted in my first posting. did you read that? And THAT exactly is my problem: i initialised tim1 correct, but the behavior is not as expected!

chen
Associate II
Posted on May 27, 2014 at 18:48

Hi

''

thats almost what i posted in my first posting. did you read that? And THAT exactly is my problem: i initialised tim1 correct, but the behavior is not as expected!

'' You have not understood what clive1 is telling you. He is telling you that your calcualted values for Tim1 prescaler are wrong. Copying and pasting the same prescaler values from Tim2 is not going to give you the same timer period for Timer 1. Look carefully at the comments that clive1 has put in!
enrico239955_st
Associate II
Posted on May 28, 2014 at 14:08

I did not copy the prescaler values from tim2 to tim1 because I know that they are on different peripherals with different clocks. So if my first posting (and the code) is read carefully one can see that I adjusted the prescaler value and the proposal of clive1 is almost what I already tried (1. posting). I still can not recognize what clive1 would say to me because I did not simply copied the values. Even if I had: I would get a period of factor 2 but not with the difference 4ms -> 600ms. So it seem that something is really weird. Maybe one of you could try to initialize tim1 with the correct code and check this with an oscilloscope. If the code is working as expected please post it here.

Posted on May 28, 2014 at 14:26

You probably have set TIM1_RCR to nonzero.

Set explicitly all members of

TIM_TimeBaseStructure

or use

TIM_TimeBaseStructInit(

TIM_TimeBaseStructure

). This is the deserved punishment for using the ''library''... ;) JW