Question
TIM4 Missing Update Interrupt
Posted on December 06, 2011 at 10:12
The follow ISR capture an event incoming on TIM4_CCP2, and
each 8 of this events the register oldCCP is subtracted from CCR2, this value is strored in loop_buf[cyc][lb_index], the value of CCR2 updates oldCCP, and also cyc and lb_index are updated. Each update event the counter cntr0 increase of 0x00010000, in order to manage time intervals greater than 16bits. Sometimes a missed rollover event occur, so losing the MSB of the captured value. I' ve tried to swap the ISR each other, without fixing the problem. brief hardware and settings description: microcontroller: STM32F103V8Tb compiler: IAR 5.4_2 (maximum balanced compression) Incoming signal: square wawe at 30KHz and dutycycle 23% interrupts enabled: - Systick every 50 microseconds preemption pr. 1, subpriority 0 - Adconv1 watchdog preemption pr. 1, subpriority 0 - TIM4 preemption pr. 0, subpriority 0 TIM4 settings: TIM_TimeBaseInitStruct.TIM_Prescaler = 0; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period = 0xFFFF; TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStruct); TIM_SetClockDivision(TIM4,TIM_CKD_DIV1); TIM_UpdateDisableConfig(TIM4, DISABLE); TIM_ICInitStruct.TIM_Channel = TIM_Channel_2; TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Falling; TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV8; TIM_ICInitStruct.TIM_ICFilter = 5; TIM_ICInit(TIM4, &TIM_ICInitStruct); /******************************************************************* unsigned int loop_buf[2][8]; //2-dimensions filtering vector unsigned int lb_index[2]; //pointer index on loop_buf unsigned int oldCCP[2]; //previous CCP value char s_frq[2] = {2, 1}; //frequency selection (don't care) int cyc =0; //allowed values: 0 and 1 void TIM4_IRQHandler(void) { static int contaeventi=, cntRO[2]={0,0}; short pinO; //ISR for capture event if(TIM_GetFlagStatus(TIM4, TIM_FLAG_CC2)) { TIM4->SR = 0xFFFB; if(--contaeventi<N_meas[cyc]) { if(contaeventi==0) { cntRO[cyc]=cntRO[cyc+TIM4->CCR2; if(TIM4->CCR2==0) cntRO[cyc]=cntRO[cyc]+0x00010000; loop_buf[cyc][lb_index[cyc]]=(cntRO[cyc]-oldCCP[cyc]); cntRO[cyc]=0; lb_index[cyc]=(lb_index[cyc]+1)&7; cyc = (~cyc)&1; pinO = ((short)((~s_frq[cyc])&3)<<11)|((short)((2-cyc)&3)<<9); GPIOD->BRR = pinO; GPIOD->BSRR = (~pinO)&0x1E00; contaeventi=((3*N_meas[cyc])>>1)+2; } } else oldCCP[cyc]=TIM4->CCR2; } //ISR for TIM4_CNT rollover event if(TIM_GetFlagStatus(TIM4, TIM_FLAG_Update)) { TIM4->SR=0xFFFE); cntRO[cyc]=cntRO[cyc]+0x00010000; if(cntRO[cyc]==0) cntRO[cyc]=0xFFFF0000; } } #tim4-missing-update-interrupt