cancel
Showing results for 
Search instead for 
Did you mean: 

Timer in PWM Capture Mode

sorena
Associate II
Posted on November 23, 2015 at 15:16

Hello every One
I am trying to read PWM signal parameters (Frequency & Duty Cycle) with timer 2 of STM32f4 IC. According to data sheet There is two modes of reading PWM signal.
1- capture mode which reads Pulse widths
2- Pairing Mode with use of two ICs configuration.
Since I am not expert in working with stm32f4, I provided the code mentioned below to read Frequency & Duty Cycle, with the help of other codes written in this forum.
First of all I want to know : Is that possible to read Duty Cycle with the first mode or not, and if yes how it should be done.?!
Secondly when i run the below code I can not read frequency and Duty Cycle as correct as should be. The entrance signal has the frequency of 45 Hz and a duty of 40 percent. \
I think the problem is with the time base configurations in which the prescaler and period should be defined.
I will be Please if someone can help me to overcome above issues.
Thanks.
Soren




void TIM2_IRQHandler(void)
{
RCC_ClocksTypeDef RCC_Clocks;
RCC_GetClocksFreq(&RCC_Clocks);
if (TIM_GetITStatus(TIM2, TIM_IT_CC1)!= RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
IC2Value_ = TIM_GetCapture1(TIM2);
if (IC2Value_ != 0) {
DutyCycle_ = (TIM_GetCapture2(TIM2) * 100) / IC2Value_;
Frequency_ = (RCC_Clocks.HCLK_Frequency)/2 / IC2Value_;
} else {
/* Reset data */
DutyCycle_ = 0;
Frequency_ = 0;
}
}
}
/* --------------------------------------PWM Input --------------------------------------*/
TIM_ICInitTypeDef TIM_ICInitStruct;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
// /* --------------------------------------Timer2--------------------------------------*/
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* GPIOC clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB, ENABLE);
/* TIM2 GPIO pin configuration : CH1=PA0, C2=PA1, CH3=PB10, CH4=PB11 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
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_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10| GPIO_Pin_11;
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_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Connect pins to TIM3 AF2 */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2 );
GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2 );
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_TIM2 );
GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_TIM2 );
/* Intrupt Config */
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);
/* 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 = 0xFFFFFFFF; // Maximal
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* Enable capture*/
TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;
TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStruct.TIM_ICFilter = 0;
TIM_ICInit(TIM2, &TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0;
TIM_ICInit(TIM2, &TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStruct.TIM_ICFilter = 0;
TIM_ICInit(TIM2, &TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0;
TIM_ICInit(TIM2, &TIM_ICInitStructure);
TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);
// /* Select the TIM2 Input Trigger: TI2FP2 */
// TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);
TIM_SelectInputTrigger(TIM2, TIM_TS_TI1FP1);
// /* Select the slave Mode: Reset Mode */
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Enable);
/* Enable TIM2 */
TIM_Cmd(TIM2, ENABLE);
/* Enable CC1-4 interrupt */
TIM_ITConfig(TIM2,TIM_IT_CC1|TIM_IT_CC2|TIM_IT_CC3| TIM_IT_CC4, ENABLE);

#stm32f4-timer #mucapture #pwm
14 REPLIES 14
sorena
Associate II
Posted on December 15, 2015 at 12:46

Hi Clive

Finally I have succeeded to read DC & Freq from 4 channels of a timer simultaneously with input capture mode... 

The key point is changing of polarity three times in interrupt handler function. 

first time you read rising edge, then change the polarity to falling , then read falling edge and change the polarity to bothedge and read rise2 and again change the polarity to rising. 

Calculating the pulse width and period is now possible. 

Meanwhile reading low frequencies with input capture mode is possible only with 32bit timers. ....

Thanks for the sample codes here and in other topics..

  

javadpoostini
Associate II
Posted on April 07, 2016 at 10:19

Hello Clive

Thank you for useful code on reading PWM input signal using Timer 2.

I have used the same code for Timer2,5,3 & 4 while trying to read a Radio Control receiver's signal using stm32f4.

While Reading the four signals, I have submitted an issue in timers 3 & 4 readings. Timers 2 & 5 are working great and successfully read PWM signal of 

45.8 frequency and 4 to 8 duty cycles and have stable readings.

While using timers 3 & 4; I ave gotten some chattering in freq. and duty. readings such that it randomly reads the freq. value wrongly up to 49 & 100 & etc .... & duty cycle also randomly changes to unknown values.

What the problem may be ?

Does the problem relates to software or hardware issues?

What do you think?

Thank you in advance for your Help.

 

Posted on April 07, 2016 at 14:21

I would.probably look at if they are 16-bit vs 32-bit, and making sure the math is constrained properly.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
javadpoostini
Associate II
Posted on April 07, 2016 at 15:24

''making sure the math is constrained properly''

 

What do you really mean? What I have to check?

Posted on April 07, 2016 at 17:36

What do you really mean?

If you do 32-bit unsigned math on 16-bit unsigned numbers, you need to be conscious that they wrap within different number spaces.

Also when measuring a long period, make sure the time base, via the prescaler, can accommodate the measurement, and how in the absence of signals might overflow.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..