Hello,
The code below uses the capture compare feature of TIM1 channel 2 (channel 3 is configured but not used for now) to capture both falling and rising edges on PE11 (channel 2) and PE13 (channel3), but only the rising edge detection generates an interrupt. Can you see why? Thanks.
TIM_ICInitTypeDef TIM_ICInitStructure ; GPIO_InitTypeDef GPIO_InitStructure ; NVIC_InitTypeDef NVIC_InitStructure ; // TIM1 clock enable RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE) ; // GPIOA clock enable RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE) ; // TIM1 channel 2 pin (PE.11) configuration (alternate function) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF ; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz ; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD ; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOE, &GPIO_InitStructure) ; // TIM1 channel 3 pin (PE.13) configuration (alternate function) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF ; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz ; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD ; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOE, &GPIO_InitStructure) ; // Connect TIM pins to AF2 GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_TIM1) ; // Connect TIM pins to AF3 GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_TIM1) ; // Enable the TIM1 global Interrupt NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0 ; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1 ; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE ; NVIC_Init(&NVIC_InitStructure) ; // TIM1 configuration: Input Capture mode // The external signal is connected to TIM1 CH2 pin (PE.11) // The Rising edge is used as active edge, // The TIM1 CCR2 is used to compute the frequency value // An interrupt is generated on both rising and falling edges TIM_ICInitStructure.TIM_Channel = TIM_Channel_2 ; 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 = 0x5 ; TIM_ICInit(TIM1, &TIM_ICInitStructure) ; TIM_ICInitStructure.TIM_Channel = TIM_Channel_3 ; 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 = 0x0 ; TIM_ICInit(TIM1, &TIM_ICInitStructure) ; // assuming PCLK1 ticks at 42[MHz] -> slow down timer to 420 KHz // because TIM1 is a 16 bit counter, we can expect to be able to measure // a waveform of up to 156 milliseconds. TIM_PrescalerConfig(TIM1, 100, TIM_PSCReloadMode_Immediate) ; // TIM enable counter TIM_Cmd(TIM1, ENABLE) ; // Enable the CC2 Interrupt Request TIM_ITConfig(TIM1, TIM_IT_CC2, ENABLE) ; TIM_ITConfig(TIM1, TIM_IT_CC3, ENABLE) ;
The ISR looks like this:
void TIM1_CC_IRQHandler(void) { static unsigned int s_pending_rising_edge, s_rising_edge_capture_value, s_falling_edge_capture_value ; // Capture/Compare interrupt source ? if (TIM_GetITStatus(TIM1, TIM_IT_CC2) == SET) { // Clear TIM1 Capture compare interrupt pending bit TIM_ClearITPendingBit(TIM1, TIM_IT_CC2) ; if (s_pending_rising_edge == false) { // Falling edge detected. Get the Input Capture value s_falling_edge_capture_value = TIM_GetCapture2(TIM1) ; s_pending_rising_edge = true ; } else if (s_pending_rising_edge == true) { uint32_t l_waveform_width ; // Rising edge detected. Get the Input Capture value s_rising_edge_capture_value = TIM_GetCapture2(TIM1); // Capture computation if (s_rising_edge_capture_value > s_falling_edge_capture_value) { l_waveform_width = (s_rising_edge_capture_value - s_falling_edge_capture_value); } else if (s_rising_edge_capture_value < s_falling_edge_capture_value) { l_waveform_width = 0xFFFFFFFF - (s_rising_edge_capture_value - s_falling_edge_capture_value) ; } else { l_waveform_width = 0; } s_pending_rising_edge = false ; } } TIM_ClearFlag(TIM1, TIM_FLAG_CC2 | TIM_FLAG_CC3) ; }