cancel
Showing results for 
Search instead for 
Did you mean: 

Timer

stephen5489
Associate II
Posted on October 18, 2013 at 04:13

Hi, I am makin a encoder interface on the et-arm stamp stm32, my problem is that maximun frequency I can get from the encoder is 30Hz and I just can measure at less 1190Hz (based in PWM_IN example) I am measuring the time betwen falling and rising voltage and this is my code. The code doesn't work could anyone please help me?

void RCC_ExIT_Configuration(void){

/* TIM2 clock enable */

 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

}

void GPIO_ExIT_Configuration(void){

//GPIO_InitTypeDef GPIO_InitStructure;

/* TIM2 channel 2 pin (PA.01) configuration */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);

}

void EXTI_Exp(void)

{

    // System Clocks Configuration

    //

RCC_ExIT_Configuration();

    //

    // Configure the GPIO ports

    //

    GPIO_ExIT_Configuration();

    /* TIM2 configuration: PWM Input mode ------------------------

       The external signal is connected to TIM2 CH2 pin (PA.01),

       The Rising edge is used as active edge,

       The TIM2 CCR2 is used to compute the frequency value

       The TIM2 CCR1 is used to compute the duty cycle value

    ------------------------------------------------------------ */

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

    /* Select the TIM2 Input Trigger: TI2FP2 */

    TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);

    /* Select the slave Mode: Reset Mode */

    TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);

    TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset);

    /* Enable the Master/Slave Mode */

    TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);

    /* TIM enable counter */

    TIM_Cmd(TIM2, ENABLE);

    /* Enable the CC2 Interrupt Request */

    //TIM_ITConfig(TIM2, TIM_IT_CC2 | TIM_IT_Trigger, ENABLE);

}

void TIM2_IRQHandler(void){

int IC2Value=0;

// Clear TIM2 Capture compare interrupt pending bit

//TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);

if (TIM_GetITStatus(TIM2, TIM_IT_CC2)== SET){

if(count!=0){

// Get the Input Capture value

IC2Value = TIM_GetCapture2(TIM2);

if ((IC2Value != 0))

{

// Frequency computation

Frequency = SystemCoreClock / IC2Value;

count+=(1/Frequency);

//Frequency2 = SystemCoreClock / IC2Value2;

}

else

{

//DutyCycle = 0;

Frequency = 0;

//Frequency2 = 0;

}

TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);

count=0;

}

}

else if(TIM_GetITStatus(TIM2, TIM_IT_Trigger)== SET){

count+=1/1190;

}

}

14 REPLIES 14
Posted on October 18, 2013 at 05:03

Not sure I can help you with this, the code doesn't look complete, there is a Format Code Block tool (Paintbrush [< >] icon) for pasting code into the forum, please use it. I'm also a bit confused about what supposed to be going on in the IRQ Handler.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
stephen5489
Associate II
Posted on October 18, 2013 at 05:36

void RCC_ExIT_Configuration(void){
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
}
void GPIO_ExIT_Configuration(void){
//GPIO_InitTypeDef GPIO_InitStructure;
/* TIM2 channel 2 pin (PA.01) configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void EXTI_Exp(void)
{
// System Clocks Configuration
//
RCC_ExIT_Configuration();
//
// Configure the GPIO ports
//
GPIO_ExIT_Configuration();
/* TIM2 configuration: PWM Input mode ------------------------
The external signal is connected to TIM2 CH2 pin (PA.01),
The Rising edge is used as active edge,
The TIM2 CCR2 is used to compute the frequency value
The TIM2 CCR1 is used to compute the duty cycle value
------------------------------------------------------------ */
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_PWMIConfig(TIM2, &TIM_ICInitStructure);
/* Select the TIM2 Input Trigger: TI2FP2 */
TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);
/* Select the slave Mode: Reset Mode */
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
/* Enable the Master/Slave Mode */
TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);
/* TIM enable counter */
TIM_Cmd(TIM2, ENABLE);
/* Enable the CC2 Interrupt Request */
//TIM_ITConfig(TIM2, TIM_IT_CC2 | TIM_IT_Trigger, ENABLE);
}
void TIM2_IRQHandler(void){
int IC2Value=0;
// Clear TIM2 Capture compare interrupt pending bit
//TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
if (TIM_GetITStatus(TIM2, TIM_IT_CC2)== SET){
if(count!=0){
// Get the Input Capture value
IC2Value = TIM_GetCapture2(TIM2);
if ((IC2Value != 0))
{
// Frequency computation
Frequency = SystemCoreClock / IC2Value;
count+=(1/Frequency);
//Frequency2 = SystemCoreClock / IC2Value2;
}
else
{
//DutyCycle = 0;
Frequency = 0;
//Frequency2 = 0;
}
TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
count=0;
}
}
else if(TIM_GetITStatus(TIM2, TIM_IT_Trigger)== SET){
count+=1/1190;
}
}

and in the IRQ I'm trying to count how much times the timer overflow before that next rising or falling edge came. And why the code is incomplete?
stephen5489
Associate II
Posted on October 22, 2013 at 14:04

Clive, colud you please tell me what's the flag used in overflow?

Posted on October 22, 2013 at 15:46

And why the code is incomplete?

You use variables you don't define, and will not compile? Static analysis requires enough context to review the internal correctness, dynamic analysis requires it to run.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
stephen5489
Associate II
Posted on October 22, 2013 at 21:28

#include ''stm32f10x_gpio.h''
#include ''stm32f10x_rcc.h''
#include ''stm32f10x_usart.h''
#include ''stm32f10x_tim.h''
#include ''stm32f10x_flash.h''
#include ''misc.h''
#include ''stm32f10x_exti.h''
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
#define EXTI9_5_IRQChannel ((u8)0x17)
uint16_t PrescalerValue = 0;
//int DutyCycle = 0;
int Frequency = 0;
int Frequency2 = 0;
float count;
void RCC_ExIT_Configuration(void){
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
}
void GPIO_ExIT_Configuration(void){
//GPIO_InitTypeDef GPIO_InitStructure;
/* TIM2 channel 2 pin (PA.01) configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void EXTI_Exp(void)
{
// System Clocks Configuration
//
RCC_ExIT_Configuration();
//
// Configure the GPIO ports
//
GPIO_ExIT_Configuration();
/* TIM2 configuration: PWM Input mode ------------------------
The external signal is connected to TIM2 CH2 pin (PA.01),
The Rising edge is used as active edge,
The TIM2 CCR2 is used to compute the frequency value
The TIM2 CCR1 is used to compute the duty cycle value
------------------------------------------------------------ */
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_PWMIConfig(TIM2, &TIM_ICInitStructure);
/* Select the TIM2 Input Trigger: TI2FP2 */
TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);
/* Select the slave Mode: Reset Mode */
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
/* Enable the Master/Slave Mode */
TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);
/* TIM enable counter */
TIM_Cmd(TIM2, ENABLE);
/* Enable the CC2 Interrupt Request */
//TIM_ITConfig(TIM2, TIM_IT_CC2 | TIM_IT_Update, ENABLE);
}

void TIM2_IRQHandler(void){
int IC2Value=0;
// Clear TIM2 Capture compare interrupt pending bit
//TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
if (TIM_GetITStatus(TIM2, TIM_IT_CC2)== SET){
if(count!=0){
// Get the Input Capture value
IC2Value = TIM_GetCapture2(TIM2);
if ((IC2Value != 0))
{
// Frequency computation
Frequency = SystemCoreClock / IC2Value;
count+=(1/Frequency);
//Frequency2 = SystemCoreClock / IC2Value2;
}
else
{
//DutyCycle = 0;
Frequency = 0;
//Frequency2 = 0;
}
TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
count=0;
}
}
else if(TIM_GetITStatus(TIM2, TIM_IT_Trigger)== SET){
count+=1/1190;
}
}
/*****************************************************************************************************/
void Send_Data(void){
extern char Data_Tx[31];
extern int Frequency = 0;
char *Tx=Data_Tx;
extern float count;
sprintf(Data_Tx, ''%s%f%c'', ''kk'', count, '#');
GPIO_SetBits(LED_PORT,GPIO_Pin_10);
while(*Tx){
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)==RESET);
USART_SendData(USART1, *Tx++);
}
while((USART_GetFlagStatus(USART1, USART_FLAG_TC)!=SET)){
}
GPIO_ResetBits(LED_PORT,GPIO_Pin_10);
}

code compile without any warning or error but it's not working just how I like to do, for example when the microprocessor send the ''count'' variable I just can see kk on hyperterminal. this is all the code I can gave you hope it being enough.
Posted on October 22, 2013 at 22:12

What is the target frequency range you are looking to measure?

Having the counter wrap is problematic, you might want to adjust the timebase, and consider if input capture would be and option instead of PWM capture.

Most of the time you are writing zero to count, the only time it isn't is for a ''Trigger'' interrupt that is not enabled, and should probably be ''Update''

72 MHz / 65536 is 1098.633

Does %f work here? Do you have the right library linked? What's the tool chain?
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
stephen5489
Associate II
Posted on October 23, 2013 at 18:48

Does %f work here? Do you have the right library linked? What's the tool chain?

the toolchain is arm-none-eabi-c++, about the library I use (#include <stdio.h>) and I'm sure it works because I used the same function before for send different variables e.g int, char and string.

What is the target frequency range you are looking to measure?

the frequency range I'm capturing is 14-30Hz.

Most of the time you are writing zero to count, the only time it isn't is for a ''Trigger'' interrupt that is not enabled, and should probably be ''Update''

About those mistakes in the code, you were totaly right I changed the code but it still doesn't works.

I going to try make it by input capture instead PWM capture, and could you please explain what do you mean about? (Having the counter wrap is problematic) I don't understand it

Posted on October 23, 2013 at 19:02

The counter is 16-bit wide, you have it clocking at 72 MHz, it will wrap ~1100 times a second.

You might want to configure the time base to something more appropriate for the range you wish to measure. Perhaps 500 KHz?

14 Hz would be ~35714 ticks, 30 Hz would be ~16667 ticks

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
stephen5489
Associate II
Posted on October 25, 2013 at 02:34

Hi Clive.

I've been programming and change the configuration from PWM input to input capture but I still can't get it works. what I need is measure the frequency of a input square signal which can have any frequency in a range from 15 to 30 hz. below I'll show you how I configured timer and handler funtion.


void
RCC_ExIT_Configuration(
void
){


/* TIM2 clock enable */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

}


void
GPIO_ExIT_Configuration(
void
){


//GPIO_InitTypeDef GPIO_InitStructure;


/* TIM2 channel 2 pin (PA.01) configuration */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;


GPIO_Init(GPIOA, &GPIO_InitStructure);



}


void
NVIC_TimeConfiguration(
void
)

{

NVIC_InitTypeDef NVIC_InitStructure;


//

// Enable the TIM2_HandlerIRQ Interrupt

//

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}


void
EXTI_Exp(
void
)

{


// System Clocks Configuration

//

RCC_ExIT_Configuration();


//

// Configure the GPIO ports

//

GPIO_ExIT_Configuration();


NVIC_TimeConfiguration();


/* Time base configuration */

TIM_TimeBaseStructure.TIM_Period = 0xffff;

TIM_TimeBaseStructure.TIM_Prescaler = 0xffff;

TIM_TimeBaseStructure.TIM_ClockDivision = 0;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;


TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);


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


/* Select the TIM2 Input Trigger: TI2FP2 */

TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);


/* Select the slave Mode: Reset Mode */

TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);


/* Enable the Master/Slave Mode */

TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);


/* TIM enable counter */

TIM_Cmd(TIM2, ENABLE);


/* Enable the CC2 Interrupt Request */

TIM_ITConfig(TIM2, TIM_IT_CC2 | TIM_IT_Update, ENABLE);

}



void
TIM2_IRQHandler(
void
){


int
IC2Value=0;


if
(TIM_GetITStatus(TIM2, TIM_IT_Update)==SET){

count+=1/163;

TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

}

else
if
(TIM_GetITStatus(TIM2, TIM_IT_CC2)==SET){

IC2Value = TIM_GetCapture2(TIM2);

if
((IC2Value != 0))
// | (IC2Value2 != 0))

{

// Frequency computation

Frequency = SystemCoreClock / IC2Value;

count+=1/Frequency;

}

else

{

Frequency = 0;

}

TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);

}

}


void
Send_Data(
void
){


extern
char
Data_Tx[31];

char
*Tx=Data_Tx;


sprintf(Data_Tx, 
''%s%0.4f%c''
, 
''kk''
, count, 
'#'
);

GPIO_SetBits(LED_PORT,GPIO_Pin_10);

while
(*Tx){

while
(USART_GetFlagStatus(USART1, USART_FLAG_TXE)==RESET);

USART_SendData(USART1, *Tx++);

}

while
((USART_GetFlagStatus(USART1, USART_FLAG_TC)!=SET)){

}

GPIO_ResetBits(LED_PORT,GPIO_Pin_10);

}

and I replaced the toolchain fromarm-none-eabi-gcc-4.5.1 toarm-none-eabi-gcc-4.6.2 From: clive1 Posted: Wednesday, October 23, 2013 7:02 PM Subject: Timer

The counter is 16-bit wide, you have it clocking at 72 MHz, it will wrap ~1100 times a second.

You might want to configure the time base to something more appropriate for the range you wish to measure. Perhaps 500 KHz? 14 Hz would be ~35714 ticks, 30 Hz would be ~16667 ticks