cancel
Showing results for 
Search instead for 
Did you mean: 

TIM2 CNT restart problem

issamnnl
Associate II
Hi,
I am struggling with TIM2 to restart its CNT from zero without using hal.
I am using nucleo-f446
TIM2 clock frequency is 21MHz (no prescaler, 1/4clock division)
CNT set for upcounting.
I want to use TIM2 to write a simple us_delay function, so I need to restart its CNT 
whenever us_delay is called. No matter what I do, I can't make it work, here is the code
I am using:
TMR2_Start = 1; //start counter
TMR2_URS = 1; //Only counter overflow/underflow sets UIF bit
TMR2_UDIS = 1; //disable update event generation
TIM2->ARR = 2100; //set 100us delay (tim2 clock frequency = 21MHz)
TMR2_UDIS = 0; //enable update event generation
TMR2_UG = 0x1; //restart counter
while (TMR2_UIF == 0){          //wait until TMR2_UIF is set
}
I put a breakpoint right before while loop is executed, I can see that CNT is enabled,
URS set, delay value loaded to ARR. However CNT is not reset to zero, it has a random
value, sometimes as high as 0x1A9C, plus the UIF and the Capture/Compare flags are
all set for unknown reasons.
Also, TIM2->CNT = 0 does not help
1 ACCEPTED SOLUTION

Accepted Solutions

Timer keeps running when the program stops at the breakpoint, unless you set the respective bit in freeze register.

JW

View solution in original post

8 REPLIES 8
mƎALLEm
ST Employee

Hello,

I didn't understand something in your code,

How are you setting/resetting bits with this code in the TIM2 register??:

TMR2_Start = 1; //start counter
TMR2_URS = 1; //Only counter overflow/underflow sets UIF bit
TMR2_UDIS = 1; //disable update event generation
TMR2_UG = 0x1; //restart counter

How you defined these variables?

And why you don't use the registers to directly set/reset the bits (TIM2->register = xx) ?

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Post edited by ST moderator to be inline with the community rules for the code sharing. In next time please use </> button to paste your code and a linker script content. Please read this post: How to insert source code.
I use bitbanding:

#define BitBanding(RegAdr, BitNumber) ((uint32_t *)(((uintptr_t)(&RegAdr)-0x40000000)*0x20+BitNumber*4+0x42000000))

//TMR2

#define TMR2_Start *((volatile unsigned long *) BitBanding(TIM2->CR1, 0)) //tmr2 start bit

#define TMR2_UIF *((volatile unsigned long *) BitBanding(TIM2->SR, 0)) //tmr2 Update interrupt flag

#define TMR2_UG *((volatile unsigned long *) BitBanding(TIM2->EGR, 0)) //tmr2 Update generation

#define TMR2_URS *((volatile unsigned long *) BitBanding(TIM2->CR1, 2)) //tmr2 Update request source

#define TMR2_UDIS *((volatile unsigned long *) BitBanding(TIM2->CR1, 1)) //tmr2 Update disable

#define TMR2_ARPE *((volatile unsigned long *) BitBanding(TIM2->CR1, 7)) //tmr2 Auto-reload preload enable

 


@issamnnl wrote:

I use bitbanding:

 

That's an info that you should provide in your first post.

Try using the registers for now and ensure all is working fine before using bit banding.

In next time please use </> button to share your code.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Here is a version with no bitbanding, same problem ... countrer shows random values, UIF and the Capture/Compare flags are all set, they remain set even after SR register is clear

TIM2->CR1 &= ~TIM_CR1_CEN;	//stop counter
TIM2->PSC = 20;				//tim2 clock frequency = 1MHz
TIM2->ARR = 100;			//set 100us delay
TIM2->EGR |= TIM_EGR_UG;	//Re-initialize the counter and generates an update of the registers
TIM2->CR1 |= TIM_CR1_CEN;	//start counter
TIM2->SR = 0;				//clear all flags
while (!(TIM2->SR & TIM_SR_UIF));  //wait 100us until UIF bit is set

 

gbm
Principal

1. Stop the timer.

2. Generate update event (no need to reload PSC and ARR every time - might be loaded once).

3. Clear the flags.

4. Start the timer.

BTW. To get 100 us delay, set ARR to 100-1.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice

Timer keeps running when the program stops at the breakpoint, unless you set the respective bit in freeze register.

JW

Thank you, I thought it automatically freezes at breakpoints, now I don't see random counter values and the UIF flag sets only at overflow, and I can reset to zero normally.

However I noticed that the time delay is shorter than expected (about 1/3), I am not sure if I am setting the clock frequency correctly. I have APB1 timer clock at 84Mhz, than 1/4 clock division, finanlly PSC = 20, so counter clock should be 1MHz??

Edit: ok it works normally when I disable division an set PSC = 83

 

 

you are right, it should be 99. thanks