2026-02-13 2:23 AM - last edited on 2026-02-13 2:26 AM by mƎALLEm
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
}Solved! Go to Solution.
2026-02-13 10:35 AM
Timer keeps running when the program stops at the breakpoint, unless you set the respective bit in freeze register.
JW
2026-02-13 2:34 AM
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) ?
2026-02-13 2:38 AM - last edited on 2026-02-13 2:48 AM by mƎALLEm
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
2026-02-13 2:51 AM - edited 2026-02-13 5:06 AM
@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.
2026-02-13 10:13 AM
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
2026-02-13 10:34 AM
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.
2026-02-13 10:35 AM
Timer keeps running when the program stops at the breakpoint, unless you set the respective bit in freeze register.
JW
2026-02-13 12:53 PM - edited 2026-02-13 1:01 PM
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
2026-02-13 1:02 PM
you are right, it should be 99. thanks