2009-05-19 02:37 AM
TIM1 Input Capture
2011-05-17 04:11 AM
Does anyone have a good example of simple input capture using timer 1?
(I have been struggling for quite awhile on something that should be really simple.) Here is my senario PE9 TIM1_CH1 has between 10-100Hz signal PE11 TIM1_CH2 has between 15-100Hz signal PE13 TIM1_CH3 has between 15-100Hz signal PE11 TIM1_CH4 has between 50-200Hz signal RCC_APB2 = 72Mhz Code snippets (can't seem to get an interrupt on TIM1_CC_IRQHandler) What am I missing? // 16Mhz crystal void RCC_Configuration(void) { /* RCC system reset(for debug purpose) */ RCC_DeInit(); /* Enable HSE */ RCC_HSEConfig(RCC_HSE_ON); //jjb // RCC_HSEConfig(RCC_HSE_OFF); /* Wait till HSE is ready */ HSEStartUpStatus = RCC_WaitForHSEStartUp(); if(HSEStartUpStatus == SUCCESS) { /* Enable Prefetch Buffer */ FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); /* Flash 2 wait state */ FLASH_SetLatency(FLASH_Latency_2); /* HCLK = SYSCLK */ RCC_HCLKConfig(RCC_SYSCLK_Div1); /* PCLK2 = HCLK */ RCC_PCLK2Config(RCC_HCLK_Div1); /* PCLK1 = HCLK/2 */ RCC_PCLK1Config(RCC_HCLK_Div2); /* PLLCLK = 8MHz * 9 = 72 MHz */ RCC_PLLConfig(RCC_PLLSource_HSE_Div2, RCC_PLLMul_9); /* Enable PLL */ RCC_PLLCmd(ENABLE); /* Wait till PLL is ready */ while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) { } /* Select PLL as system clock source */ RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); /* Wait till PLL is used as system clock source */ while(RCC_GetSYSCLKSource() != 0x08) { } } RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3 | RCC_APB1Periph_TIM4 | RCC_APB1Periph_I2C1 | RCC_APB1Periph_USART2 | RCC_APB1Periph_USART3 , ENABLE ); RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG | RCC_APB2Periph_TIM1 | RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO , ENABLE ); } ____________________________________________________________ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = FAN1_4_TACH | FAN5_8_TACH | FAN9_12_TACH | PUMP_TACH; // PE9,11,13,14 GPIO_Init(TACH_READ_PORT, &GPIO_InitStructure); // pE9 GPIO_PinRemapConfig(GPIO_FullRemap_TIM1, ENABLE); __________________________________________________________ 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(TIM1, &TIM_ICInitStructure); /* Enable the CCxInterrupt Request */ TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE); TIM_ITConfig(TIM1, TIM_IT_CC2, ENABLE); TIM_ITConfig(TIM1, TIM_IT_CC3, ENABLE); TIM_ITConfig(TIM1, TIM_IT_CC4, ENABLE); __________________________________ /* Enable the TIM1 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); ________________________________________ void TIM1_CC_IRQHandler(void) { vu16 IC2Value = 0; vu16 DutyCycle = 0; vu32 Frequency = 0; static ccIT; if (TIM_GetITStatus(TIM1, TIM_IT_CC1)){ ccIT = 1; } if (TIM_GetITStatus(TIM1, TIM_IT_CC2)){ ccIT = 2; } if (TIM_GetITStatus(TIM1, TIM_IT_CC3)){ ccIT = 4; } if (TIM_GetITStatus(TIM1, TIM_IT_CC4)){ ccIT = 8; } /* Clear TIM1 Capture compare interrupt pending bit */ TIM_ClearITPendingBit(TIM1, TIM_IT_CC4); /* Get the Input Capture value */ IC2Value = TIM_GetCapture4(TIM1); if (IC2Value != 0) { /* Duty cycle computation */ DutyCycle = (TIM_GetCapture1(TIM1) * 100) / IC2Value; /* Frequency computation */ Frequency = 72000000 / IC2Value; } else { DutyCycle = 0; Frequency = 0; } }2011-05-17 04:11 AM
Hi ,
since the STM8S and STM32 Timers are very similar, I advice you to take a look on the STM8S Firmware Timer example named ''TIM1_Input_Capture''. Amin --------------------- /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ u32 TIM1ClockFreq = 2000000; u32 LSIClockFreq = 0; u16 ICValue1 =0, ICValue2 =0; /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ /* Public functions ----------------------------------------------------------*/ /** * @brief Example firmware main entry point. * @par Parameters: * None * @retval void None * @par Required preconditions: * None */ void main(void) { TIM1_ICInit( TIM1_CHANNEL_1, TIM1_ICPOLARITY_FALLING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV8, 0x0); /* Enable CC1 interrupt */ TIM1_ITConfig(TIM1_IT_CC1, ENABLE); /* Enable TIM1 */ TIM1_Cmd(ENABLE); /* Clear CC1 Flag*/ TIM1_ClearFlag(TIM1_FLAG_CC1); /* Connect LSI to COO pin*/ GPIO_Init(GPIOE, GPIO_PIN_0, GPIO_MODE_OUT_PP_LOW_FAST); CLK_CCOConfig(CLK_OUTPUT_LSI); CLK_CCOCmd(ENABLE); /* wait a capture on CC1 */ while((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1); /* Get CCR1 value*/ ICValue1 = TIM1_GetCapture1(); TIM1_ClearFlag(TIM1_FLAG_CC1); /* wait a capture on cc1 */ while((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1); /* Get CCR1 value*/ ICValue2 = TIM1_GetCapture1(); TIM1_ClearFlag(TIM1_FLAG_CC1); /* Compute LSI clock frequency */ LSIClockFreq = (8 * TIM1ClockFreq) / (ICValue2 - ICValue1); /* Insert a break point here */ while (1); }2011-05-17 04:11 AM
Thanks