2015-10-29 03:06 PM
Hi,
It seems there is a problem when I try the example project regarding using TIM input capture mode to measure pulse width. In example project, the both edge triggering mode is used. My question is how to set it up to make sure that the rising edge is triggered first and then trigger on falling edge. This way the difference of counter values will give correct pulse with of measured pulse signal. I am relatively new to STM32 device, could someone help to explain this? Thanks, --Ningint main(void)
{ /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f0xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f0xx.c file *//* Initialize the TFT-LCD */
#ifdef USE_STM320518_EVAL STM320518_LCD_Init(); #else STM32072B_LCD_Init(); #endif /* USE_STM320518_EVAL */ /* Clear the TFT-LCD */ LCD_Clear(LCD_COLOR_WHITE); /* DAC Channel1 configuration */ DAC_Config(); /* COMP1 Configuration */ COMP_Config(); /* TIM2 Configuration in input capture mode */ TIM_Config();/* Infinite loop */
while (1) { if (DisplayActive != 0) { /* Compute the pulse width in us */ MeasuredPulse = (uint32_t)(((uint64_t) Capture * 1000000) / ((uint32_t)SystemCoreClock)); /* Display measured pulse width on Glass LCD and color LCD */ DisplayOnLCD(MeasuredPulse); DisplayActive = 0; } } }/**
* @brief Configures TIM2 channel 4 in input capture mode * @param None * @retval None */ static void TIM_Config(void) {/* Init Structure definition */
TIM_ICInitTypeDef TIM_ICInitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure;/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); /* TIM2 Time base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_ClearFlag(TIM2, TIM_FLAG_Update); /* TIM2 Channel4 Input capture Mode configuration */ TIM_ICStructInit(&TIM_ICInitStructure); TIM_ICInitStructure.TIM_Channel = TIM_Channel_4; /* TIM2 counter is captured at each transition detection: rising or falling edges (both edges) */ TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0; TIM_ICInit(TIM2, &TIM_ICInitStructure); /* TIM2 IRQChannel enable */ NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Enable capture interrupt */ TIM_ITConfig(TIM2, TIM_IT_CC4, ENABLE); /* Enable the TIM2 counter */ TIM_Cmd(TIM2, ENABLE); /* Reset the flags */ TIM2->SR = 0; }/******************************************************************************/
/* STM32F0xx Peripherals Interrupt Handlers */ /******************************************************************************/ /** * @brief This function handles TIM2 global interrupt. * @param None * @retval None */ void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_CC4) == SET) { if (CaptureCounter == 0) { IC4Value1 = TIM_GetCapture4(TIM2); CaptureCounter = 1; } else if (CaptureCounter == 1) { CaptureCounter = 0; IC4Value2 = TIM_GetCapture4(TIM2);if (IC4Value2 > IC4Value1)
{ Capture = (IC4Value2 - IC4Value1) - 1; } else { Capture = ((0xFFFF - IC4Value1) + IC4Value2) - 1; } DisplayActive = 1; } TIM_ClearITPendingBit(TIM2, TIM_IT_CC4); } }2015-10-29 03:54 PM
Seems to be a lot of code missing, that deals with the initialization.
The code computing the delta is wrong, probably ST's fault, but it is. Review 16-bit unsigned math. So pair Channel 3 & 4 to capture opposite edges. Then you'll get both edges and know which one is which. CH3 would be in indirect mode. Consider PWM Input mode on CH1 or CH2, if your design permits. If the signal is slow enough you could read the state of the pin in the interrupt. You could also check the duty if the signal won't be 50/50