cancel
Showing results for 
Search instead for 
Did you mean: 

How ARR value impact on timer input capture result?

HB
Associate II

Hello guys,

I have just started working with stm32 controllers. I am trying to capture the frequency of signal using timer 2 input capture mode.

I am getting absolutely correct frequency if i use ARR = 65535 but when i use ARR = 0xffffffff (As timer 2 is 32bit) i am getting wrong result.

I am using this reference equation

Frequency = TIM_CLOCK / ((C2-C1)*(prescaler+1))

Where C2 = capture value 2 // Both Rising edge

C1 = capture value 1

TIM_CLOCK = 1Mhz

TIMER_PSC = 16-1

SYSTEM_CLOCK = 16Mhz

Please help if i am missing something.

26 REPLIES 26

@Community member​ Yes i have read that.

Please note that i am not changing ARR after timer started.

#include "stm32f401xc.h"

void Gpio_Init(void);

void Timer_Init(void);

//-----------------------Main start----------------------------

int main()

{

volatile uint32_t C1, C2;

Gpio_Init();

Timer_Init();

while(1)

{

TIM1->CNT = 0;

//Polling method

while((TIM1->SR & (1 << 1)) == 0);

C1 = TIM1->CCR1; //Capture 1

while((TIM1->SR & (1 << 1)) == 0);

C2 = TIM1->CCR1; //Capture 2

}

}//----------------------Main end------------------------------

//F01-GPIO Init

void Gpio_Init(void)

{

//1 Enable clock to gpio

RCC->AHB1ENR |= (1 << 0); //Port A

//2 Gpio mode

GPIOA->MODER &= ~(1U << 16);

GPIOA->MODER |= (1 << 17); //PA8 alternate func mode

//3 Alter function define

GPIOA->AFR[1] |= (1 << 0); //AF == TIM1_CH1

}

//F02-Timer Init

void Timer_Init(void)

{

//1 Timer clock enable

RCC->APB2ENR |= (1 << 0);

//2 Stop timer

TIM1->CR1 &= ~(1U << 0);

//3 Set timer prescaler 

TIM1->PSC = 16-1;

//4 Set autoreload value

TIM1->ARR = 65535;

//5 Select timer configurations

TIM1->CR1 &= ~(1U << 7); //Autoreoad disable 

TIM1->CR1 &= ~(1U << 4); //Upcount

//6 Input channel select 

TIM1->CR2 &= ~(1U << 7); //TIM1_CH1 as TI1

TIM1->CCMR1 &= ~(3U << 0); //Clear CC1S bits

TIM1->CCMR1 |= (1 << 0); //IC1 is mapped on TI1

//7 Select filter value

TIM1->CR1 &= ~(3U << 8); //tDTS == tCK_CNT(prescaler)

TIM1->CCMR1 &= ~(0xfU << 4); //No filter

//8 Select edge

TIM1->CCER &= ~((1U << 1)|(1U << 3));

//9 Select prescalers for capture

TIM1->CCMR1 &= ~(3U << 2);

//10 Capture enable

TIM1->CCER |= (1 << 0);

//11 Timer run

TIM1->CR1 |= (1U << 0);

}

Thank you

After you've set TIM1->PSC, do

TIM1->EGR = TIM_EGR_UG;

JW

Use uint16_t/uint32_t for 16/32-bit timers respectively. And, to deal with overflow properly, the result of the subtraction must also be of the same type.

Piranha
Chief II

Better set TIM_EGR_UG after both the PSC and ARR registers are set.

> TIM1->ARR = 65535;

No need to explicitly set the maximum value as that is the default value after reset.

HB
Associate II

@Community member​  @Piranha​ Tried both the things but still result is same.

Post code and concrete numbers.

JW​

HB
Associate II

Output 1: ARR 65535

0693W00000UFPV9QAP.pngOutput 2: ARR 0xFFFFFFFF

0693W00000UFPVOQA5.png

HB
Associate II

Please note that I have not changed ARR once the timer start.

And the code?

JW

HB
Associate II

#include "stm32f429xx.h"

//Function Prototypes

void Gpio_Init(void);

void Timer_Init(void);

//-------------------------Main start-------------------------

int main()

{

volatile uint32_t time1, time2, time3;

volatile float fre, per, Toff, Duty;

Gpio_Init();

Timer_Init();

while(1)

{

TIM2->CNT = 0;

while((TIM2->SR & (1 << 1)) == 0);

time1 = TIM2->CCR1;

while((TIM2->SR & (1 << 1)) == 0);

time2 = TIM2->CCR1;

while((TIM2->SR & (1 << 1)) == 0);

time3 = TIM2->CCR1;

//Frequency calculations 1Mhz Timer clock so 1us per clock pulse

per = (float)(time3 - time1); //To convert in ms divide it by 1000

fre = (float)1 / per;

fre *= 1000000;

//Duty cycle calculations

Toff = (float)(time3 - time2);

Duty = (float)(((per-Toff)*100)/per);

time1 = 0; time2 = 0; time3 = 0;

}

}//-----------------------Main end---------------------------

//F01-GPIO config

void Gpio_Init(void)

{

//1 Enable clock 

RCC->AHB1ENR |= (1 << 0); //Port A

//2 Pin mode

GPIOA->MODER &= ~(1U << 10);

GPIOA->MODER |= (1 << 11); //PA5 as alterenate function

//3 Alternate function decide

GPIOA->AFR[0] |= (1 << 20);

}

//F02-Timer config

void Timer_Init(void)

{

//1 Enable clock

RCC->APB1ENR |= (1 << 0); //Timer 2

//2 Stop timer

TIM2->CR1 &= ~(1U << 0);

//3 Prescaler for timer

TIM2->PSC = 16 - 1;

//4 Select autoreload value

TIM2->ARR = 65535; //Not working for 0xffffffff? Ask 

//5 Timer config

TIM2->CR1 &= ~(1U << 7); //Autoreload disable

TIM2->CR1 &= ~(1U << 4); //Upcounter

//6 Timer channel config

TIM2->CCMR1 |= (1 << 0); //Tim1_CH1 as TI1

//7 Edge select

TIM2->CCER |= (1U << 1)|(1U << 3); //Both edges for PWM input

//TIM2->CCER &= ~((1U << 1)|(1U << 3)); //Rising edge

//8 Input capture enable 

TIM2->CCER |= (1 << 0);

//9 Timer run

TIM2->CNT = 0;

TIM2->CR1 |= (1 << 0);

}