cancel
Showing results for 
Search instead for 
Did you mean: 

TIMER 3 Interrupt

sanju
Senior
Posted on April 25, 2018 at 13:01

Hi all,

This is a question regarding STM32F0 TIM3.

I have written this code in keil compiler

/***** main.c*****/

&sharpinclude<stm32f0xx.h>

&sharpinclude<stm32f030x8.h>

void GPIO_Init(void); 

void TIM3_Init(void);

int main()

{

 GPIO_Init();         // Intializing PA5

 TIM3_Init(); 

 while(1)

 {

 } 

}

void GPIO_Init()

 // Enable clock for GPIOA

 RCC->AHBENR |= (1<<17);

 

 //Configuration of PA5

 GPIOA->MODER |= (1<<10);             // PA5 as general purpose output mode

 GPIOA->OTYPER &= ~(1<<5);            // PA5 as output push pull

 GPIOA->OSPEEDR |= ((1<<10)|(1<<11)); // PA5 at high speed

 GPIOA->PUPDR &= ~((1<<10)|(1<<11));  // PA5 as no pull-up, pull-down

 GPIOA->ODR = 0;            // PA5 as Output Low

}

void TIM3_Init()

{

 RCC->APB1ENR |= (1<<1);        // Enable clock for TIM3

 TIM3->PSC = 999;           // Int clk divided by 1000(999+1)

 TIM3->ARR = 7999;           // Counts from 0 to 7999

 TIM3->DIER = 1;            // Update interrupt enable

 __NVIC_SetPriority(TIM3_IRQn, 0);   // Set TIM3 interrupt vector priority to 0

 __NVIC_EnableIRQ(TIM3_IRQn);     // Enable TIM3 interrupt vector

 TIM3->CR1 = 1;            // Enable TIM3 counter

 

}

void ISR()

{

   TIM3->SR = 0;

   GPIOA->ODR ^= (1<<5);      // Toggle PA5 Output

}

/**** it.c*****/

void ISR(void);

void TIM3_IRQHandler(void)

{

 ISR();

}

Here system clock freq and timer clock freq is 8Mhz(internal oscillator).

when I run this code I found that my led on PA5 toggles per second that should be as per code.

But there is an problem in output that when microcontroller is done reset by a reset button the PA5 Is immediately high and then toggles @ per second i.e. the tim3 generate a update interrupt when it is enabled. I want that first interrupt should come after timer completion means 1 sec. so that when I reset the microcontroller output can be at low and after 1 sec it toggles( goes high)  and so on.

'My question is why microcontroller is making High to the UIF bit TIM3->SR reg. when TIM3 counting is enabled. I think it should be after timer completion'.

Waclawek.Jan

‌

ELMHIRI.Syrine

‌

null
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on April 29, 2018 at 17:18

No, the counter does not need to be enabled. The problem is in timing between setting the Update event through EGR, and clearing the status flag.

https://community.st.com/0D50X00009XkaBtSAJ

 

JW

View solution in original post

7 REPLIES 7
Posted on April 26, 2018 at 01:19

The value you write into the prescaler is not active immediately, only after the first period, as the register you are writing into is only a 'shadow' which gets copied into the active prescaler only upon Update (i.e. the first overflow).

The trick is in 'forcing' and update by writing one into TIMx_EGR.UG after you have written the TIMx_PSC value, but that also sets the update flag and would immediately trigger and interrupt; so you need to do this and then also clearing the bits in the TIMx_SR, before you enable the interrupts.

JW

Posted on April 27, 2018 at 06:20

 ,

 ,

I have updated the code as you suggested , kindly see the highlighted portion in the below code

/***** main.c*****/

♯ include<,stm32f0xx.h>,

 ,

♯ include<,stm32f030x8.h>,

 ,

void GPIO_Init(void), ,

 ,

void TIM3_Init(void),

int main()

 ,

{

 ,

 ,GPIO_Init(), , , , , , , , , // Intializing PA5

 ,

 ,TIM3_Init(), ,

 ,

 ,while(1)

 ,

 ,{

 ,} ,

 ,

}

void GPIO_Init()

 ,

{ ,

 ,

 ,// Enable clock for GPIOA

 ,

 ,RCC->,AHBENR |= (1<,<,17),

 ,

 ,

 ,

 ,//Configuration of PA5

 ,

 ,GPIOA->,MODER |= (1<,<,10), , , , , , , , , , , , , // PA5 as general purpose output mode

 ,

 ,GPIOA->,OTYPER &,= ~(1<,<,5), , , , , , , , , , , , // PA5 as output push pull

 ,

 ,GPIOA->,OSPEEDR |= ((1<,<,10)|(1<,<,11)), // PA5 at high speed

 ,

 ,GPIOA->,PUPDR &,= ~((1<,<,10)|(1<,<,11)), , // PA5 as no pull-up, pull-down

 ,

 ,GPIOA->,ODR = 0, , , , , , , , , , , , // PA5 as Output Low

 ,

}

void TIM3_Init()

 ,

{

 ,

 ,RCC->,APB1ENR |= (1<,<,1), , , , , , , , // Enable clock for TIM3

 ,

 ,TIM3->,PSC = 999, , , , , , , , , , , // Int clk divided by 1000(999+1)

TIM3->,EGR = 1, , , , , , , , , , , , , , // Forcing to generate a update

TIM3->,SR = 0, , , , , , , , , , , , , , , , // Clearing the UIF bit

 ,

 ,TIM3->,ARR = 7999, , , , , , , , , , , // Counts from 0 to 7999

 ,

 ,TIM3->,DIER = 1, , , , , , , , , , , , // Update interrupt enable

 ,

 ,__NVIC_SetPriority(TIM3_IRQn, 0), , , // Set TIM3 interrupt vector priority to 0

 ,

 ,__NVIC_EnableIRQ(TIM3_IRQn), , , , , // Enable TIM3 interrupt vector

 ,

 ,TIM3->,CR1 = 1, , , , , , , , , , , , // Enable TIM3 counter

 ,

 ,

 ,

}

void ISR()

 ,

{

 ,

 , , ,TIM3->,SR = 0,

 ,

 , , ,GPIOA->,ODR ^= (1<,<,5), , , , , , ,// Toggle PA5 Output

 ,

}

 ,

 ,

 ,

/**** it.c*****/

void ISR(void),

 ,

void TIM3_IRQHandler(void)

 ,

{

 ,

 ,ISR(),

 ,

}

/*******************************code end here*******************************/

But it again generate a interrupt as timer counter enabled i.e. without any delay led toggles when reset button is pressed.

but if I ,change the TIM3_Init function as

void TIM3_Init()

 ,

{

 ,

 ,RCC->,APB1ENR |= (1<,<,1), , , , , , , , // Enable clock for TIM3

 ,

 ,TIM3->,PSC = 999, , , , , , , , , , , // Int clk divided by 1000(999+1)

TIM3->,CR1 = 1, , , , , , , , , , , , , , // Enable Counter

TIM3->,EGR = 1, , , , , , , , , , , , , , // Forcing to generate a update

TIM3->,SR = 0, , , , , , , , , , , , , , , , // Clearing the UIF bit

TIM3->,CR1 = 0, , , , , , , , , , , , , ,// Disable the counter

TIM3->,CNT = 0, , , , , , , , , , , , , // Put counter value to 0 so that it can again start from 0

 ,

 ,TIM3->,ARR = 7999, , , , , , , , , , , // Counts from 0 to 7999

 ,

 ,TIM3->,DIER = 1, , , , , , , , , , , , // Update interrupt enable

 ,

 ,__NVIC_SetPriority(TIM3_IRQn, 0), , , // Set TIM3 interrupt vector priority to 0

 ,

 ,__NVIC_EnableIRQ(TIM3_IRQn), , , , , // Enable TIM3 interrupt vector

 ,

 ,TIM3->,CR1 = 1, , , , , , , , , , , , // Enable TIM3 counter again

 ,

 ,

 ,

}

 ,

In simple words before generating the Forced update by setting the TIM3->,EGR.UG bit first I am enabling the counter and then generate a ,forced update ,and clear the UIF bit in TIM3_SR reg. then

Disable the counter for a moment till the other other settings are done (ARR, UIE, Interrupt priority, tim3 vector enabled) and then again the counter enabled, So doing this, the code is working ok, means if I press the reset button after 1 sec led toggles not immediately.

Am I doing ,Right?

Posted on April 28, 2018 at 09:47

This is a mystery for me. The first variant should work well.

Can you please try to put after setting PSC some irrelevant code which would delay setting of EGR, for example

TIM3->PSC = 999;           // Int clk divided by 1000(999+1)

 TIM3->CCR1 = 0; // not needed but makes some delay

TIM3->EGR = 1;              // Forcing to generate a update

Thanks

JW

Posted on April 28, 2018 at 10:22

yes, tried this but unfortunately it is not working.

void TIM3_Init()

{

 RCC->APB1ENR |= (1<<1);        // Enable clock for TIM3

 TIM3->PSC = 999;           // Int clk divided by 1000(999+1)

TIM3->CCR1=0;              // some delay

TIM3->EGR = 1;              // Forcing to generate a update

TIM3->SR = 0;                // Clearing the UIF bit

 TIM3->ARR = 7999;           // Counts from 0 to 7999

 TIM3->DIER = 1;            // Update interrupt enable

 __NVIC_SetPriority(TIM3_IRQn, 0);   // Set TIM3 interrupt vector priority to 0

 __NVIC_EnableIRQ(TIM3_IRQn);     // Enable TIM3 interrupt vector

 TIM3->CR1 = 1;            // Enable TIM3 counter

 

}

even i wrote  TIM3->CCR1 = 0; continue 10 times to give more delay but its not having any effect.

I have seen in debugging that it generate the update i.e. sets the UIF. it means this Update event does not update the PSC. This update also generates if we don't write any delay statement after writing to PSC.

What i have learned here that to get the PSC updated  on update event , counter should be enabled i.e. TIM3->CR1 = 1;

Thanks

henry.dick
Senior II
Posted on April 28, 2018 at 18:52

'

when microcontroller is done reset by a reset button the PA5 Is immediately high

 ... i.e. the tim3 generate a update interrupt when it is enabled.'

the notion that TIMER3 caused PA5 high is not established. You may want to go through the datasheet and see what the reset state of the pin is. and if there are external parts that are pulling the pin high. 

if i were you, i would try to be really sure that PA5 goes immediately high after a reset, and then try to pin down that problem. otherwise, you are simply chasing ghosts.

Posted on April 29, 2018 at 17:18

No, the counter does not need to be enabled. The problem is in timing between setting the Update event through EGR, and clearing the status flag.

https://community.st.com/0D50X00009XkaBtSAJ

 

JW

Posted on May 02, 2018 at 12:03

Sorry for late reply actually I was on holiday.

Thanks for your suggestion, I have tried code by putting some delay between TIM3->EGR = 1;  and  TIM3->SR = 0;  

see this

void TIM3_Init()

{

 RCC->APB1ENR |= (1<<1);        // Enable clock for TIM3

 TIM3->PSC = 999;           // Int clk divided by 1000(999+1)

TIM3->EGR = 1;              // Forcing to generate a update

TIM3->CCR1=0;              // some delay

_NOP;                                       /

_NOP;                                       /

_NOP;                                       /

_NOP;                                       /

TIM3->SR = 0;                // Clearing the UIF bit

 TIM3->ARR = 7999;           // Counts from 0 to 7999

 TIM3->DIER = 1;            // Update interrupt enable

 __NVIC_SetPriority(TIM3_IRQn, 0);   // Set TIM3 interrupt vector priority to 0

 __NVIC_EnableIRQ(TIM3_IRQn);     // Enable TIM3 interrupt vector

 TIM3->CR1 = 1;            // Enable TIM3 counter

 

}

and it works.

Thanks