cancel
Showing results for 
Search instead for 
Did you mean: 

Use a pin for PWM capture input AND counter

laurent2
Associate II
Posted on February 12, 2015 at 09:28

Dear all,

Do you know if it is possible to get from a single pin a capture PWM input (and get the frequency) and on the same pin, to be able to count the number of pulse ?

Currently I have ''capture PWM input'' on TIM2 working fine, but how connect the input to another timer while the Alternative Function is already used ?

BR,

Laurent

#counter #gpio #pwm-input-timer
4 REPLIES 4
Posted on February 12, 2015 at 10:10

Use the input as TRGO source (TIMmaster_CR2.MMS = 011), and in slave timer use it as TRGI (TIMslave_SMCR.TS set to the appropriate Internal Trigger) and set slave timer's slave mode to External Clock Mode 1 (TIMmaster_SMCR.SMS=111).

Only CH1 can be used in this way.

JW

laurent2
Associate II
Posted on February 12, 2015 at 10:35

Thank you Jan,

(FYI, I'm using a STM32F072)

First I've tried to use TIM1 for PWM capture input and fail with lot of efforts and lot of examples (for example the AF of TIM1CH1 selection set my PWM signal to 0).

At the end, I've moved the signal on TIM2 and it works fine at the first time.

I will check again but I'm a little unwilling to retry TIM1.

Last way, send the signal to a second IO connected inside to another TIM, or integrate the frequency by software.

Thanks again.

BR,

Laurent

laurent2
Associate II
Posted on February 17, 2015 at 14:50

Dear Jan,

I've try this (following your advices) but it doesn't work. Do you have an idea :

PWM_in on TIM15 CH1   // working fine

TIM2 used as counter, trigger from TIM15

void TIM2_Config(void)

{

  TIM_DeInit(TIM2);// TIM2 Configuration

//    TIM_SelectOutputTrigger(TIM15, TIM_TRGOSource_Enable);  //  ??

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // TIM2 Periph clock enable

  // Time base configuration

  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);

  TIM_TimeBaseStructure.TIM_Prescaler = 1; //

  TIM_TimeBaseStructure.TIM_Period = 0xFFFFFFFF; //TIM2 is 32-bit counter

  TIM_TimeBaseStructure.TIM_ClockDivision = 0x1;

  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

  TIM_ICInitTypeDef        TIM_ICInitStructure;

  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; // Rising/Falling/BothEdge

  TIM_ICInitStructure.TIM_ICSelection =  TIM_ICSelection_TRC;   // TIM_ICSelection_DirectTI;

  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;

  TIM_ICInitStructure.TIM_ICFilter = 0x0;

  TIM_ICInit(TIM2, &TIM_ICInitStructure);

  TIM2->CR2&= (~TIM_CR2_MMS);

  TIM2->CR2|= (TIM_CR2_MMS_0 | TIM_CR2_MMS_1);

  TIM2->SMCR&= (~TIM_SMCR_TS);

  TIM2->SMCR|= (TIM_SMCR_TS_0);   // 001 = TIM2 slave trigged by TIM15

  TIM2->SMCR&= (~TIM_SMCR_SMS);

  TIM2->SMCR|= (TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_2);   // 7 = TIM_SlaveMode_External1

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

}

and I test with :

void Measure_to_LS1(void)

{

    LS1_CStr(''Speed='');    LS1_UIntx(MesureF);    LS1_CStr(''\r\n'');

    LS1_CStr(''TIM2='');    LS1_UIntx(TIM_GetCounter(TIM2));    LS1_CStr(''\r\n\r\n'');  //TIM2->CNT

    LS1_CStr(''TIM2 C1='');    LS1_UIntx(TIM_GetCapture1(TIM2));    LS1_CStr(''\r\n'');

    LS1_CStr(''TIM2 C2='');    LS1_UIntx(TIM_GetCapture2(TIM2));    LS1_CStr(''\r\n'');

    LS1_CStr(''TIM2 C3='');    LS1_UIntx(TIM_GetCapture3(TIM2));    LS1_CStr(''\r\n'');

    LS1_CStr(''TIM2 C4='');    LS1_UIntx(TIM_GetCapture4(TIM2));    LS1_CStr(''\r\n'');

}

I get on the serial LS1 :

Speed=11704

TIM2=0

TIM2 C1=0

TIM2 C2=0

TIM2 C3=0

TIM2 C4=0

Speed is correct (depending on the PWM frequency), but nothing on TM2.

Any advices ?

BR,

Laurent

Posted on February 17, 2015 at 19:16

I don't speak the ''library'' gobbledygook, but:

- you need to set TRGO through setting TIMx_CR2.MMS in the *master* i.e. TIM15

- why prescaler in TIM2?

- why input capture in TIM2?

JW