SAMD21 Interrupt Timer overflow calculation

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am using ASF to configure an Interrupt Timer overflow. I cant seem to find the formula for calculating how many times the overflow will occur per second and how to set the period.

I want to fire an event every 4 seconds. How do I calculate the period to do this?

void configure_tc(void)
{
	struct tc_config config_tc;
	tc_get_config_defaults(&config_tc);
	config_tc.counter_size = TC_COUNTER_SIZE_8BIT;
	config_tc.clock_source = GCLK_GENERATOR_1;
	config_tc.clock_prescaler = TC_CLOCK_PRESCALER_DIV1024;
	config_tc.counter_8_bit.period = ??? ; 

	tc_init(&tc_instance, CONF_TC_MODULE, &config_tc);
	tc_enable(&tc_instance);

}

From what I have read online is the formula is

 

(1 / clock freq) * Prescaler * Timer/Counter Size = # times overflow occurs

So, from the config_clocks.h, I see my clock is running at 1.2 mHz and per the data sheet, for the Timer/Counter size is 255 for 8 but configuration:

 

#  define CONF_CLOCK_XOSC_EXTERNAL_FREQUENCY      12000000UL

My calculation:

(1/1200000) * 1024 * 255 = .2174

Is this calculation correct? The overflow will occur approximately 5 times a second?

 

If that is the case, setting what should I set my period too to fire every second or every 4 seconds?

config_tc.counter_8_bit.period = ?? ;

 

 

"When all else fails, read the directions"

Last Edited: Sat. Apr 29, 2017 - 05:29 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The default clock speed of my SAMD21 xplained pro is 8MHz not 1.8mhz.

 

so

 

(1/8000000) * 255 * 1024 = 0.03264

An overflow will occur every ~0.032 second

Drop in x for the desired period and 4 seconds for the desired interrupt:

4 = x * 0.03264
4/0.03264 = x
x = ~122.54

So I set my period to 123, which should product an interrupt every 4.01472 second.

void configure_tc(void)
{
	struct tc_config config_tc;
	tc_get_config_defaults(&config_tc);
	config_tc.counter_size = TC_COUNTER_SIZE_8BIT;
	config_tc.clock_source = GCLK_GENERATOR_1;
	config_tc.clock_prescaler = TC_CLOCK_PRESCALER_DIV1024;
	config_tc.counter_8_bit.period = 123 ; 

	tc_init(&tc_instance, CONF_TC_MODULE, &config_tc);
	tc_enable(&tc_instance);

}

Which produces an interrupt every 3.875s:

 

Close but no cigar. I am thinking, that calling:

 

port_pin_toggle_output_level(LED0_PIN);

is costing me time, so i skip the ASF code and toggle the port:

 

REG_PORT_OUTTGL1 = PORT_PB30; 

Which now produces:

 

Am I loosing time when (4.01472 - 3.906) 0.10872 of a second executing code? or are my calculations wrong?

"When all else fails, read the directions"

Last Edited: Sat. Apr 29, 2017 - 09:34 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

0 is also a count. Thus subtract 1 from your compare value.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
0 is also a count. Thus subtract 1 from your compare value.

Thanks for the answer. Do you mean add 1 to the compare value?

 

By adding 1, I get better results:

(1/8000000) * 255 * 1024 = 0.03264

Since I am using an 8 bit counter, I will only calculate 1 second

 

1/0.03264 = 30.63725490196078

The register is not a floating point register, so we round to 31 and add 1. That is a period of 32 for 1 second.

 

 

Pretty close smiley. Now to get my desired event to fire @4 seconds

 

32 * 4 = 128

Setting the period to 128:

 

Again. very very close!

 

Thanks for the help!

 

"When all else fails, read the directions"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your calculation is not right. 

Value of Gclk is 32Khz not 8 Mhz

GCLK_GENERATOR_1 = 32000Hz

prescaler = 1024;

 

so Timer frequency will be = 32000/1024 = 31.25

Time = 1/Frequency = 1/31.25 = 0.032;

 and Your Overflow value is 123, hence overflow will occur at every 0.032 * 123 = 3.963 Seconds

 

This is how it will work. Hope it will help

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello @ PhillyNJ

Can you tell me how did you enable the interrupts ?

how can you make an interrupt come when the timer overflow? 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@kamlesh321123

 

I tried this equation but it does not work correctly, for a 8 bit counter in samda1

the calculated time using the equation is: 

-max value =255

-clock input to the timer = 8MHZ

-prescaler= 256

-Time to trigger an interrupt = Prescaler * 255 /Clock frequency = 8.16 msec

the real time is 10 usec.