2014-02-19 08:16 AM
HI,
I'm trying to configure TIMER1 CHANNEL2 for InputCapture to measure a pulse from some external hardware. My init code looks like this:////////////////////////////////////////////////
// Enable Timer1 clock and release reset RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1,DISABLE);TIM_InternalClockConfig(TIM1);
RCC_GetClocksFreq(&RCC_Clocks);
Int32U Tim1Clock = RCC_Clocks.PCLK2_Frequency ;
if(RCC_Clocks.HCLK_Frequency != RCC_Clocks.PCLK2_Frequency)
{ Tim1Clock = 2*RCC_Clocks.PCLK2_Frequency ; } // Time base configuration TIM_TimeBaseStructure.TIM_Prescaler = 1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);// Channel 2 Configuration in InputCapture
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; 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 TIM1 global Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); At the moment I just want to catch the rising edge to calculate frequency but in the next revision I want to time between a rising and the next falling edge. My interrupt handler is not getting called. I have a logic analyser on the pins and can see the signals so I know the hardware is working OK. I think I have missed something silly and hope someone can kindly point me in the right direction. Many thanks, Richard.2014-02-20 08:17 AM
Point taken.
Pick a TIM unit supporting the feature set desired. I'd still probably opt for using two channels looking at opposite edges, and unless there was a specific reason interrupt on just one of them. The CCx latches the value, which can be read subsequently. ie at the falling edge you can determine the high time interval by delta-ing the prior rising edge measurement with the falling edge one just interrupted on.2014-02-20 08:19 AM
I have library version 2.0.3 with my dev kit :(
2014-02-20 08:40 AM
For Servo type signals, the PWM mode works well.
/**************************************************************************************/
// Portion from
// STM32 RC Servo Demo for 168 MHz STM32F4 Discovery - sourcer32@gmail.com
/**************************************************************************************/
volatile uint16_t Reading[2]; // Readings from PB4 TIM3_CH1 (1us units)
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);
Reading[0] = TIM_GetCapture1(TIM3); // Period (us) ~20000
Reading[1] = TIM_GetCapture2(TIM3); // Duty/Width (us) ~1500 or whatever (600-2400 us)
}
}
/**************************************************************************************/
void TIM3_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* TIM3 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* GPIO clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
/* Configure GPIO input for timer */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; // PB4 TIM3_CH1
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Connect TIM3 pins to AF */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, GPIO_AF_TIM3);
/* Enable the TIM3 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_Init(&NVIC_InitStructure);
/* Time base configuration - SystemCoreClock = 168000000 for 168 MHz board ABP1 @ 42 MHz (DIV4) */
TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t) (((SystemCoreClock / 1000000) / 2) - 1); // Shooting for 1 MHz, (1us)
TIM_TimeBaseStructure.TIM_Period = 0xFFFF; // Maximal
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/* Configure PWM Input Capture */
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; // PB4 TIM3_CH1
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_PWMIConfig(TIM3, &TIM_ICInitStructure);
/* Select the TIM3 Input Trigger: TI1FP1 */
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);
/* Select the slave Mode: Reset Mode */
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);
/* TIM Interrupts enable */
TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE);
/* TIM3 enable counter */
TIM_Cmd(TIM3, ENABLE);
}
/**************************************************************************************/