2015-05-09 04:25 AM
I'm using analog hall sensor in my application. One of its tasks is to measure rpm. I also calculate angle, so it's connected to ADC input + I internally connected it to COMP3-. Comp out, if I pass it to PA8 looks ok. Next I want to link it to TIM15IC1, take input capture and reset timer. So I'll have signal period in CCR1 without using interrupts.
In stmstudio i can see timer resets and counts from 0, but CCR1 only sometimes takes right value. It looks like there is race condition and capture happens after timer reset. I tried any possible IC, PWMIC and input trigger modes, lines commented.///////////////////////////////////////////////////////////////////////////////////////////////////////////////// COMP3///////////////////////// COMP_InitStructure.COMP_NonInvertingInput = COMP_NonInvertingInput_IO2; COMP_InitStructure.COMP_InvertingInput = COMP_InvertingInput_IO2; COMP_InitStructure.COMP_Output = COMP_Output_TIM15IC1; COMP_InitStructure.COMP_OutputPol = COMP_OutputPol_Inverted; COMP_InitStructure.COMP_BlankingSrce = COMP_BlankingSrce_None; COMP_InitStructure.COMP_Hysteresis = COMP_Hysteresis_High; COMP_InitStructure.COMP_Mode = COMP_Mode_HighSpeed; COMP_Init(COMP_Selection_COMP3, &COMP_InitStructure); GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_7); COMP_Cmd(COMP_Selection_COMP3, ENABLE); ///////////////////////////////////////////////////////////////////////////////////////////////// ///////////////// TIM15 ///////////////////////// TIM_TimeBaseStructure.TIM_Prescaler = 999; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 0xffff; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM15, &TIM_TimeBaseStructure); //TIM_UpdateDisableConfig(TIM15, ENABLE); //TIM_UpdateRequestConfig(TIM15,TIM_UpdateSource_Regular); //TIM_SelectOnePulseMode(TIM15, TIM_OPMode_Single); TIM_ICInitTypeDef TIM_ICInitStructure; TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_ICInit(TIM15, &TIM_ICInitStructure); TIM_SelectInputTrigger(TIM15, TIM_TS_TI1FP1); TIM_SelectSlaveMode(TIM15, TIM_SlaveMode_Reset); //TIM_SelectMasterSlaveMode(TIM15,TIM_MasterSlaveMode_Enable); TIM_Cmd(TIM15, ENABLE);http://jpegshare.net/images/25/64/2564168d184940909eb8626485860ddf.png2015-05-09 05:30 AM
also i've found that line in standart library resets TIM15_SMCR SMS[3] but it shouldn't!
void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode){ /* Check the parameters */ assert_param(IS_TIM_LIST2_PERIPH(TIMx)); assert_param(IS_TIM_MSM_STATE(TIM_MasterSlaveMode)); /* Reset the MSM Bit */ TIMx->SMCR &= (uint16_t)~TIM_SMCR_MSM; //here it must be uint32_t /* Set or Reset the MSM Bit */ TIMx->SMCR |= TIM_MasterSlaveMode;}this command ''The effect of an event on the trigger input (TRGI) is delayed
'' but it didn't help me.2015-05-09 07:32 AM
You're using which STM32 part?
Does the CCR1 number make any more sense if you delta/difference the count between events rather than reset the counter every time? Might help you understand where it's glitching. If too fast for interrupt consider using the CC1 to trigger a DMA base recording of the value(s).2015-05-09 07:59 AM
stm32f3vct6, discoveryf3 board.
If I don't reset couner - everything works fine, difference looks right, but I hoped to make everything in HW, as documentation says.Don't think DMA could help - it seems that CCR1 gets its wrong value because timer resets faster than capture happens. It is all strange - manual and examples say that in PWM mode cpu can make capture and immideately reset couner, but not before capturing. The only difference is that I take IC1 from internal connection with COMP3, rather than from chip leg.2015-05-09 10:03 AM
The external pins have more synchronization and filtering.
DMA has a faster reaction time than you processing an IRQ, you'll also see how many times it resets faster than it was counting, or whatever the race condition is. You could also switch the timer into a counter mode. You could significantly drop the prescaler and this would give you much finer granularity, rather than just recording zero during the first 1000 cycles.