Configuring Timer1 Overflow Interrupts

Hi all - been trying to get some Timer1-related stuff working for my arduino project (just got into this about a week ago) but I'm having a little trouble understanding a few things about timer1. Here's the ideal setup:

I want to use Timer1 as a global timer that is always running, that allows me to synchronize when certain events happen in the system. - Is it possible to slow down the speed of the timer so it doesn't overflow so quickly? Or is this inherent to the timer? I may want it at full speed later on, but for debugging, it might be nice to have it run at a more human-friendly speed :D - If this isn't possible, how might you recommend using this timer1 as a global timer? Perhaps incrementing some variable every time it overflows or something? - Also, is it possible to reset or write values to Timer1? Like if I had a global clock reset signal, could that reset Timer1 to 0? - Is the value of the timer able to be read as well?

So.. those are my questions. In addition, I just don't really understand how these timer interrupts or this whole timer1 thing works. Internet tutorials/example code are a bit cryptic, as is the data sheet. Any help, guideance, and/or example code you guys could give me would be stupendous. Thanks!

Yes the datasheet is not fun to read. I have been working with timer1 for a little more that a week now (on and off). My advice is to read it again and again and again

Timer1 is flexible and it can count input pulses (from a pin) and pulses from the internal clock. The pulses from the internal clock (16 mHz) can be "scaled down" with a prescaler, down to i think 1024 i.e 1024 clock cycles per count on timer1 You can get a interrupt from overflow and you can set it to give a interrupt after the count of your own choosing. You can set it to set a output pin state when it has reached its top value (of your choosing). But it seems that you cannot get both an interrupt and change state on the output pin at the same time (which i pesonally wanted it to to)

In CTC-mode it, which i belive you want, automatically resets (zeroes) the timer count when it has reached its top value.

example // setting up the timer: TCCR1A = 0; // Reset control registers timer1 /not needed, safety TCCR1B = 0; // Reset control registers timer1 // not needed, safety TIMSK1 = B00000011; //timer1 output compare match and overflow interrupt enable OCR1A = 65530; // Set TOP/compared value (your value) (maximum is 65535 i think) TCCR1B = B00001010; // prescaling=8 CTC-mode (two counts per microsecond)

TCCR1A =B01000000; //set OCR1A on compare match (output high level level) DDRB |=B00000010; // SET OC1A=PB1= digital pin 9 to output// OC1A = PB1 (Arduino digital pin #9) // SEEMS THAT GETTING BOTH A INTERRUPT (TIMER1_COMPA_vect) AND a output pinchange isnt possible.. I havent managed // to anyway

ISR(TIMER1_OVF_vect) { // Interrupt service run when Timer/Counter1 OVERFLOW Serial.println("Timer1 overflow"); }

ISR(TIMER1_COMPA_vect) // Interrupt service run when Timer/Counter1 reaches OCR1A (your own top value) { next three rows i used when checking the timer function //Serial.println("OCR1A COMPARE MATCH"); //Serial.println("TRCNT1= "); //Serial.println(TCNT1);

}

You might want to take a look at some of the [u]Reference Diagrams[/u] at http://web.alfredstate.edu/weimandn. Unfortunately there's no diagram for Timer/Counter1 overflow but you may gain some insight into its operation from the diagrams that are there.

Don

heya dottore11,

The alfredstate.edu link above has helped me decode much of the information about Timer1 and makes a great supplement to the datasheet. Also, the Timer1 library is a great wrapper for accessing features of the timer.

To slow down the speed of the timer you can use the setPeriod(long microseconds) method. The value passed to setPeriod should be at least twice the max delay between two events (pin changes or whatever you are measuring). The Timer1 lib causes the timer to count up then down, if you read the timer value on the down stroke then it will give you erroneous results.

I’m not sure what you mean as to “using this timer1 as a global timer”. The timer is global in the sence that it’s variables (aka registers) have global scope. It’s all about how you set up the timer for your use.

The actual count for timer1 is available by reading TCNT1. There are functions in the Timer1 lib that start, stop and reset the counter. The value in TCNT1 is in ticks of the timer, from 0-65536. To get this into microseconds you first multiply by the prescaler value (x1, x8, x64, x265, or x1024) to get the total number of clock cycles this represents, then divide by the number of clock cycles a microsecond, (F_CPU / 1000000). There are a couple of handy macros defined by wiring.h here:

#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
#define clockCyclesToMicroseconds(a) ( ((a) * 1000L) / (F_CPU / 1000L) )
#define microsecondsToClockCycles(a) ( ((a) * (F_CPU / 1000L)) / 1000L )

Also, heres a little snippet of code that I use to read timer1’s value in microsecs:

ulong readTimer1()		//returns the value of the timer in microseconds
{							//rember! phase and freq correct mode counts up to then down again
	switch (Timer1.clockSelectBits)
	{
	case 1:// no prescalse
		return ((TCNT1 * 1000L) / (F_CPU / 1000L));
		break;
	case 2:// x8 prescale
		return ((TCNT1 * 1000L) / (F_CPU / 1000L))<<3;
		break;
	case 3:// x64
		return ((TCNT1 * 1000L) / (F_CPU / 1000L))<<6;
		break;
	case 4:// x256
		return ((TCNT1 * 1000L) / (F_CPU / 1000L))<<8;
		break;
	case 5:// x1024
		return ((TCNT1 * 1000L) / (F_CPU / 1000L))<<10;
		break;
	default:
		return 0;
	}
}