AnsweredAssumed Answered

stm32f4 Discovery pwm input problem

Question asked by wang.xueyi on Jun 10, 2013
Latest reply on Jun 11, 2013 by Clive One
Hi,

I got a problem with pwm input example. I tried the example with one pwm input to clculate frequency and duty cycle. It works great!

In my case, I need two input channels. So I just connect another PB3 which is TIM2 channel 2 and copy the setting for PB7. 

Problem is I can calculate the frquency which means CCR2 works but duty cycle(CCR1) always read 0. 

Attached please find the initial, setting and  IRQHandler program.

Thanks.

void TIM4_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;

  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  //TIM_OCInitTypeDef  TIM_OCInitStructure;
 
  /* TIM4 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

  /* GPIOB clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
 
  /* Compute the prescaler value */
  PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 28000000) - 1;

  /* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = 0xffff;
  TIM_TimeBaseStructure.TIM_Prescaler = 1680-1;//PrescalerValue;
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
 
  /* TIM4 chennel2 configuration : PB.07 */
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP ;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
 
  /* Connect TIM pin to AF2 */
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_TIM4);

  /* Enable the TIM4 global Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

}
void TIM2_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;

  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  //TIM_OCInitTypeDef  TIM_OCInitStructure;
 
  /* TIM2 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

  /* GPIOB clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
 
  /* Compute the prescaler value */
  PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 28000000) - 1;

  /* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = 0xffff;
  TIM_TimeBaseStructure.TIM_Prescaler = 1680-1;//PrescalerValue;
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
 
  /* TIM4 chennel2 configuration : PB.03 */
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP ;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
 
  /* Connect TIM pin to AF2 */
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_TIM2);

  /* Enable the TIM4 global Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

}
void TIM4_Capture(void)
{
  /* TIM4 configuration: PWM Input mode ------------------------
     The external signal is connected to TIM4 CH2 pin (PB.07),
     The Rising edge is used as active edge,
     The TIM4 CCR2 is used to compute the frequency value
     The TIM4 CCR1 is used to compute the duty cycle value
  ------------------------------------------------------------ */

  TIM4_ICInitStructure.TIM_Channel = TIM_Channel_2;
  TIM4_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  TIM4_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM4_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  TIM4_ICInitStructure.TIM_ICFilter = 0x0;

  TIM_PWMIConfig(TIM4, &TIM4_ICInitStructure);

  /* Select the TIM4 Input Trigger: TI2FP2 */
  TIM_SelectInputTrigger(TIM4, TIM_TS_TI2FP2);

  /* Select the slave Mode: Reset Mode */
  TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset);
  TIM_SelectMasterSlaveMode(TIM4,TIM_MasterSlaveMode_Enable);

  /* TIM enable counter */
  TIM_Cmd(TIM4, ENABLE);

  /* Enable the CC2 Interrupt Request */
  TIM_ITConfig(TIM4, TIM_IT_CC2, ENABLE);
}

void TIM2_Capture(void)
{
  /* TIM4 configuration: PWM Input mode ------------------------
     The external signal is connected to TIM4 CH2 pin (PB.07),
     The Rising edge is used as active edge,
     The TIM4 CCR2 is used to compute the frequency value
     The TIM4 CCR1 is used to compute the duty cycle value
  ------------------------------------------------------------ */

  TIM4_ICInitStructure.TIM_Channel = TIM_Channel_2;
  TIM4_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  TIM4_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM4_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  TIM4_ICInitStructure.TIM_ICFilter = 0x0;

  TIM_PWMIConfig(TIM2, &TIM2_ICInitStructure);

  /* Select the TIM4 Input Trigger: TI2FP2 */
  TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);

  /* Select the slave Mode: Reset Mode */
  TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
  TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Enable);

  /* TIM enable counter */
  TIM_Cmd(TIM2, ENABLE);

  /* Enable the CC2 Interrupt Request */
  TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);
}

void TIM4_IRQHandler(void)
{
  RCC_ClocksTypeDef RCC_Clocks;
  RCC_GetClocksFreq(&RCC_Clocks);

  /* Get the Input Capture value */
  IC2Value = TIM_GetCapture2(TIM4);

  if (IC2Value != 0)
  {
    /* Duty cycle computation */
    DutyCycle = (TIM_GetCapture1(TIM4) * 100) / IC2Value;

    /* Frequency computation
       TIM4 counter clock = (RCC_Clocks.HCLK_Frequency)/2 */

    Frequency = (RCC_Clocks.HCLK_Frequency)/2 / IC2Value;
    //Frequency=Frequency/1680;
   
    SerialPutChar(0xff);
   
    SerialPutChar(0x01);
   
    // Input Capture value
    temp= IC2Value>>8;
    SerialPutChar(temp);
    temp= IC2Value;
    SerialPutChar(temp);
   
    // duty cyele
    temp= DutyCycle>>8;
    SerialPutChar(temp);
    temp= DutyCycle;
    SerialPutChar(temp);
   
    // Frequency
    temp= Frequency>>8;
    SerialPutChar(temp);
    temp= Frequency;
    SerialPutChar(temp);
   
    // sum check
    temp=(unsigned char)(DutyCycle+Frequency+IC2Value);
   
    SerialPutChar(temp);
   
    SerialPutChar(0xee);
   
    GPIO_ToggleBits(GPIOD, GPIO_Pin_13);
   
    /* Clear TIM4 Capture compare interrupt pending bit */
    TIM_ClearITPendingBit(TIM4, TIM_IT_CC2);
  }
  else
  {
    DutyCycle = 0;
    Frequency = 0;
  }
}

void TIM2_IRQHandler(void)
{
  RCC_ClocksTypeDef RCC_Clocks;
  RCC_GetClocksFreq(&RCC_Clocks);

  /* Get the Input Capture value */
  IC2Value2 = TIM_GetCapture2(TIM2);

  if (IC2Value2 != 0)
  {
    /* Duty cycle computation */
    DutyCycle2 = (TIM_GetCapture1(TIM2) * 100) / IC2Value2;

    /* Frequency computation
       TIM4 counter clock = (RCC_Clocks.HCLK_Frequency)/2 */

    Frequency2 = (RCC_Clocks.HCLK_Frequency)/2 / IC2Value2;
    //Frequency2=Frequency2/1680;
   
    SerialPutChar(0xff);
   
    SerialPutChar(0x02);
   
    // Input Capture value
    temp2= IC2Value2>>8;
    SerialPutChar(temp2);
    temp2= IC2Value2;
    SerialPutChar(temp2);
   
    // duty cyele
    temp2= DutyCycle2>>8;
    SerialPutChar(temp2);
    temp2= DutyCycle2;
    SerialPutChar(temp2);
   
    // Frequency
    temp2= Frequency2>>8;
    SerialPutChar(temp2);
    temp2= Frequency2;
    SerialPutChar(temp2);
   
    // sum check
    temp2=(unsigned char)(DutyCycle2+Frequency2+IC2Value2);
   
    SerialPutChar(temp2);
   
    SerialPutChar(0xee);
   
    GPIO_ToggleBits(GPIOD, GPIO_Pin_14);
   
    /* Clear TIM4 Capture compare interrupt pending bit */
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
  }
  else
  {
    DutyCycle2 = 0;
    Frequency2 = 0;
  }
}

Outcomes