2013-03-06 04:06 AM
Hello everybody!
I'm using timer TIM7 on STM32F407 to generate an interrupt on overflow. It works fine except one thing. When I enable the counter at first time it rises an interrupt immediately, right after setting the CEN bit in TIM7_CR1 register. Following iterations are ok.Does anybody know what's the problem?Initialization codevoid TIM7_Init(void){ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE); TIM7->CR1 |= TIM_CR1_OPM | TIM_CR1_URS; //One-pulse mode and Update generation only on Counter Overflow TIM7->DIER |= TIM_DIER_UIE; // Interrupt generation on Counter Overflow TIM7->PSC = 1600; //With HSI frequency 16MHz gives a 100us period NVIC_InitStruct.NVIC_IRQChannel = TIM7_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; NVIC_Init(&NVIC_InitStruct);}PushButton Handlervoid EXTI0_IRQHandler(void){ for (volatile uint32_t cnt=200000; cnt!=0; cnt--); //wait until bounce stops EXTI_ClearITPendingBit(EXTI_Line0); //reset pending state GPIO_ToggleBits(GPIOD, GPIO_Pin_12); //LED TIM7->ARR = 10000; //delay 1s TIM7->CR1 |= TIM_CR1_CEN; //start counting}Overflow handlervoid TIM7_IRQHandler(void){ TIM7->SR &= 0xFFFFFFFE; //reset UIF flag GPIO_ToggleBits(GPIOD, GPIO_Pin_15); //LED} #stm32f4-timer-tim7-interrupt2013-03-06 06:00 AM
Do you reset the chip using the hardware reset/poweron, or are you resetting it from some form of a debugger?
I'd reset the timer explicitly in RCC after enabling its clock, to be sure. > TIM7->SR &= 0xFFFFFFFE; //reset UIF flag Don't &=, do =, as all bits in TIMx_SR are of rc_w0 type, so you could inadvertently clear a bit which has been set meantime. It won't matter in the code as you presented it, but it's a good practice for future when you will manipulate multiple flags. Also, it might be perhaps a better style to stick to either using the ''peripheral library'', or directly the registers, not mixing them. JW2013-03-06 08:10 PM
Thanks for reply!
I'm reseting the chip both ways: with debugger and with hardware using NRST pin. The result is same. Also I tried to reset UIF flag in SR register and NVIC pending bit right after setting the CEN bit in CR1 register. Unfortunately, it has no any effect.2013-03-15 07:46 AM
void EXTI0_IRQHandler(void)
{ for (volatile uint32_t cnt=200000; cnt!=0; cnt--); //wait until bounce stops EXTI_ClearITPendingBit(EXTI_Line0); //reset pending state GPIO_ToggleBits(GPIOD, GPIO_Pin_12); //LED TIM7->ARR = 10000; //delay 1s TIM7->CR1 |= TIM_CR1_CEN; //start counting } void TIM7_IRQHandler(void) { // TIM7->SR &= 0xFFFFFFFE; //reset UIF flag if (TIM7->SR & 1) { GPIO_ToggleBits(GPIOD, GPIO_Pin_15); //LED } else { GPIO_ToggleBits(GPIOD, GPIO_Pin_14); //LED } TIM7->SR = 0xFFFE; //reset UIF flag } static void TIM7_Init(void) { NVIC_InitTypeDef NVIC_InitStruct; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE); TIM7->PSC = 1600; //With HSI frequency 16MHz gives a 100us period TIM7->EGR = TIM_EGR_UG; // generate update to force the prescaler to be accepted TIM7->CR1 |= TIM_CR1_OPM | TIM_CR1_URS; //One-pulse mode and Update generation only on Counter Overflow TIM7->SR = 0; // clear all status (namely the update flag) TIM7->DIER |= TIM_DIER_UIE; // Interrupt generation on Counter Overflow NVIC_InitStruct.NVIC_IRQChannel = TIM7_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; NVIC_Init(&NVIC_InitStruct); }2013-03-15 07:58 AM
Just one more minor thing:
TIM7->PSC = 1600; //With HSI frequency 16MHz gives a 100us period It should be 1599. Not that it matters when used with HSI which is much more imprecise than that (and also jitters like hell :) ), just I like things to be done precisely. JW