2009-01-30 12:45 AM
TIM2 Input capture prescaler
2011-05-17 04:01 AM
Hello,
I measure the time between two rising signal edges with TIM2. To get the best resolution I'm trying to change the timer prescaler on the fly. Means that when the captured value is to small I will reduce the prescaler. But this is not working. I can change the prescaler but the values in the CCR1 does not change. When I choose a smaler prescaler in the initialisation routine in the beginning, it's ok. It seems that the preloades prescaler value is not overtaken. But when I read back the value the new one is there. Any ideas what is going wrong? Michael Here is the code: vu16 time_6steps; void TIM2_Configuration(void) { /* Clear the IT pending Bits */ ClrBit(TIM2->SR,TIM_SR_UIF); ClrBit(TIM2->SR,TIM_SR_TIF); ClrBit(TIM2->SR,TIM_SR_CC1IF); ClrBit(TIM2->SR,TIM_SR_CC2IF); /* ----- Time Base Configuration ----- */ TIM2->PSC = 2000; //TIM2->ARR = U16_MAX; //???necessary TIM2->RCR = 0; //Delete repitition counter register /* ----- Timer Mode Configuration -----*/ ClrBit(TIM2->CR2,TIM_SMCR_SMS); //Reset Mode ClrBit(TIM2->CR2,TIM_SMCR_SMS+1); ClrBit(TIM2->CR2,TIM_SMCR_SMS+2); SetBit(TIM2->CR2,TIM_CR2_TI1S); //Channel inputs are XOred SetBit(TIM2->SMCR,TIM_SMCR_TS); ClrBit(TIM2->SMCR,TIM_SMCR_TS+1); SetBit(TIM2->SMCR,TIM_SMCR_TS+2); //Filtered Timer Input 1 (TI1FP1) ClrBit(TIM2->CR1,TIM_CR1_DIR); //Counter Mode upcounting ClrBit(TIM2->CR1,TIM_CR1_CMS); //Counter Mode edge aligned ClrBit(TIM2->CR1,TIM_CR1_CMS+1); //Counter Mode edge aligned ClrBit(TIM2->CR1,TIM_CR1_OPM); //Counter Mode one pulse disable ClrBit(TIM2->CR1,TIM_CR1_ARPE); //Counter Mode auto reload preload register disable (ARR not bufferd) /* ----- Channel Configuration ----- */ /* --- Channel 1 --- */ //Input capture ClrBit(TIM2->CCER,TIM_CCER_CC1P); //Trigger at rising edge SetBit(TIM2->CCMR1,TIM_CCMR1_CC1S); //Triggerinput is TI1 ClrBit(TIM2->CCMR1,TIM_CCMR1_CC1S+1); ClrBit(TIM2->CCMR1,TIM_CCMR1_IC1F); ClrBit(TIM2->CCMR1,TIM_CCMR1_IC1F+1); //Input Filter ClrBit(TIM2->CCMR1,TIM_CCMR1_IC1F+2); ClrBit(TIM2->CCMR1,TIM_CCMR1_IC1F+3); ClrBit(TIM2->CCMR1,TIM_CCMR1_IC1PSC); //Input prescaler ClrBit(TIM2->CCMR1,TIM_CCMR1_IC1PSC+1); SetBit(TIM2->CCER,TIM_CCER_CC1E); //Enable Capture CH1 /* --- Channel 2 --- */ //Input capture SetBit(TIM2->CCER,TIM_CCER_CC2P); //Trigger at falling edge ClrBit(TIM2->CCMR1,TIM_CCMR1_CC2S); //Triggerinput is TI1 SetBit(TIM2->CCMR1,TIM_CCMR1_CC2S+1); ClrBit(TIM2->CCMR1,TIM_CCMR1_IC2F); ClrBit(TIM2->CCMR1,TIM_CCMR1_IC2F+1); //Input Filter ClrBit(TIM2->CCMR1,TIM_CCMR1_IC2F+2); ClrBit(TIM2->CCMR1,TIM_CCMR1_IC2F+3); ClrBit(TIM2->CCMR1,TIM_CCMR1_IC2PSC); //Input prescaler ClrBit(TIM2->CCMR1,TIM_CCMR1_IC2PSC+1); SetBit(TIM2->CCER,TIM_CCER_CC2E); //Enable Capture CH2 /* --- Channel 3 --- */ //Output compare mode ClrBit(TIM2->CCMR2,4); //Output compare mode frozen, no effect of comparisions ClrBit(TIM2->CCMR2,5); //Register CCMR3, Bits OC1M 0-2 ClrBit(TIM2->CCMR2,6); /* ----- Interrupt source -----*/ //SetBit(TIM2->DIER,TIM_DIER_UIE); //Enable update Interrupt //SetBit(TIM2->DIER,TIM_DIER_TIE); //Enable trigger Interrupt SetBit(TIM2->DIER,TIM_DIER_CC1IE); //Enable capture CH1 Interrupt SetBit(TIM2->DIER,TIM_DIER_CC2IE); //Enable capture CH2 Interrupt //SetBit(TIM2->DIER,TIM_DIER_CC3IE); //Enable capture CH3 Interrupt } ############################################### void adjust_prescaler(void) { if(time_6steps { TIM2->PSC = 100; //new prescaler } } ############################################# void TIM2_IRQHandler(void) { if(CheckBit(TIM2->SR,TIM_SR_CC1IF)) //rising edge? { time_6steps = TIM2->CCR1; TIM2->CNT=0; //clear Counter } ClrBit(TIM2->SR,TIM_SR_CC1IF); ClrBit(TIM2->SR,TIM_SR_CC2IF); /* Generate TIM1 COM event by software */ SetBit(TIM1->EGR,TIM_EGR_COMG); }