cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F373 Timer questions

ing
Associate II
Posted on June 24, 2014 at 16:58

Hello,

I have a timer performing input capture on one channel. Can I set another channel OF THE SAME TIMER as an output with a frequency double of the captured input signal frequency?

-------------

I am not 100% clear on how the input capture works, but I expect that (also seeing the code examples) the timer starts counting at the System Clock frequency, and then the input signal frequency is calculated based on the distance in timer counts, and computed as:

TIM2Freq = (uint32_t) (SystemCoreClock / Capture);

....so I'd expect that if I set another channel in utput compare with a prescaler = Capture/2-1 it should be feasible....?

Can you clarify on this point?

Thanks a lot!!!

#timers #stm32f3
5 REPLIES 5
Posted on June 24, 2014 at 17:52

There is only one counting element in each TIM, to generate a frequency on a secondary channel you'd need to advance the TIMx->CCRx at each interrupt, and perhaps use toggle mode. This would tend to limit the max frequencies you could achieve safely.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ing
Associate II
Posted on June 24, 2014 at 18:11

Thanks for replying!!!!

Actually I am stuck on the fact it seems that there is not any easy way to set a dependent timer - or channel - to a frequency DOUBLE of the master timer...is it possible to do it? 

So far, the only idea that came up to my mind is to set up two timers, a master and a slave.

The master is configured in input capture and will compute the input frequency in its interrupt.

The slave will be set during this interrupt with a prescaler = captured frequency/ 2 and then enabled.

It is a complicated and suboptimal solution. Is there some better way?

BTW, I need this to drive two different (L and R) MEMS MP34DT01 microphones and read their output at double frequency on the same pin ... 

Posted on June 24, 2014 at 18:42

You might be able to use DMA on the CCx trigger to load a value into a different timer, whose prescaler is set at the desired ratio, ie the other timer you run twice as fast, or slow

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ing
Associate II
Posted on June 26, 2014 at 20:23

Hello again,

I eventually managed to get the signal out on the output pin, PA10, also thanks to this:

https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Discovery/External%20trigger%20for%20TIMER%203&currentviews=242

However, I tried several configuration, (PWM input, external clock input, ...) but no matter what, I cannot detect BOTH EDGES of the input signal and obtain a double frequency in output. 

Do you have some suggestions for me?

Here's the code:

static void TIM_Config(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;

  NVIC_InitTypeDef NVIC_InitStructure;

  TIM_ICInitTypeDef  TIM_ICInitStructure;

  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

  TIM_OCInitTypeDef  TIM_OCInitStructure;

  

  /* TIM2 clock enable */

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

  /* GPIOA clock enable */

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

  

  /* TIM2 channel 3 pin (PA.09) configuration */

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* Connect TIM pins to AF10 */

  GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_10);

  

  /* GPIOA Configuration: PA10(TIM2 CH4) as alternate function push-pull ------*/

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //NOPULL;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* Connect TIM pins to AF10 */

  GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_10);

  

  /* Time base configuration */

  TIM_TimeBaseStructure.TIM_Period = 1; //65535;

  TIM_TimeBaseStructure.TIM_Prescaler = 0;

  TIM_TimeBaseStructure.TIM_ClockDivision = 0;

  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

  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(TIM2, &TIM_ICInitStructure);

  TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);

  // enable hall sensor

  // T1F_ED will be connected to  HallSensoren Imputs

  // TIM2_CH1,TIM2_CH2,TIM2_CH3 

  TIM_SelectHallSensor(TIM2, ENABLE);

  // HallSensor event is delivered with singnal TI1F_ED

  // (this is XOR of the three hall sensor lines)

  // Signal TI1F_ED: falling and rising edge of the inputs is used 

  //TIM_SelectInputTrigger(TIM2, TIM_TS_TI1F_ED); //CONTAINED TIM_TIxExternalClockConfig

 

  /* Select the TIM2 Input Trigger: TI2FP2 */

  TIM_SelectInputTrigger(TIM2, TIM_TS_TI1F_ED);

  // Slave Mode selection: Trigger Mode 

  TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_External1);

  

  /* Select the slave Mode: Reset Mode */

  //TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);

  //TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Enable);

  

//  // External Trigger set to External Clock, Mode 1

//  //TIM_ETRClockMode1Config (TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);

//

//  // Input Trigger selection 

//  TIM_TIxExternalClockConfig (TIM2, TIM_TS_TI1F_ED, TIM_ICPolarity_BothEdge, 0) ;

  //----------------- Timer PWM output - 

  

 

  /* Master Configuration in PWM1 Mode */

  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

  TIM_OCInitStructure.TIM_Pulse = 1; //(TIM_TimeBaseStructure.TIM_Period/2);  //HALF Period

  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  TIM_OC4Init(TIM2, &TIM_OCInitStructure);

  

  TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);

  

  TIM_ARRPreloadConfig(TIM2, DISABLE);

  TIM_CtrlPWMOutputs(TIM2, ENABLE);

 

  /* TIM enable counter */

  TIM_Cmd(TIM2, ENABLE);

  

  /* Enable the CC3 Interrupt Request */

  //TIM_ITConfig(TIM2, TIM_IT_CC3, ENABLE);

}

Thanks a lot!

Omar BOUZOURRAA
Associate II
Posted on October 26, 2017 at 12:33

Hello 

,

You can generate one signal and measure another with the same timer but with limitations. Let's talk about TIM4 for example. It has 4 independant channels but all the channels have only one counter and one Auto Reload register, that means the Timer can run with only one Time base frequency. 

You should set the ARR register to its maximum value (In the case of TIM4 ARR_MAX = 0xFFFF). For more accurate measurement, you should set the prescaler at zero. This configuration is needed for input capture mode. So go and configure one channel in input capture mode. Now the corresponding CCR register is read only and it contains information about measured signal period (frequency). Go now and configure onother channel in PWM output mode for example. At that time you can only modify the duty cycle (modifying the corresponding CCR register which will be writtable only) but if you change frequency (ARR register) the measurement may be affected. 

But there is a way to reduce limitations !

1) Configure TIM4_CH1 in input mode 

2) Configure sensitive edge

3) Configure TIM4_CH1 to be connected to TI1FP1

4) Enable slave mode in reset mode (it will be reset counter value every sensitive edge detected on TI1FP1)

Now I suppose that measured signal cannot set ARR register to more than 0x0FFF.

5) Set PSC at zero and ARR at 0x0FFF.

6) Configure TIM4_CH2 in PWM output mode and select PWM mode (Mode1 or mode 2 as you lioke)

7) Now at the fly, you can modify CCR2 value as you like but it shoul wbe always kower than 0x0FFF. You can also modify the frequency of your PWM signal by modifying  ARR value, but here you shoul pay attention : you should not assign to ARR a value lower than 0x0FFF.

😎 Enable TIM4_CNT and TIM4_CH1 and TIM4_CH2 by enabling theit corresponding GPIO Pins. (That's done only by calling HAL_TIM_Start() twice, to enable channel 1 and channel2.

By the way

🙂

 If you understood me, in your case, you can only generate a signal twice lower than the measured one but the opposite is not possible  

Good luck, and if you have some questions don't hesitate