Using timer 1
ECE3400

The Arduino environment uses the Mega328 timer0, but does not touch timer1.
Timer1 is a 16 bit counter that can be set to perfrom several different functions.

Timer1 functions

 

There are various ways of timing intervals (and therefore frequency):

(1) Using input capture:
Before the Arduino initialization code, write an interrupt service routine to copy timer 1 into a register and subtract to get a period.
Note that the subtract is correct even if the counter overflows (once) between readings. Time resolution is 0.0625 microsecond.
The logic-level input must be on Arduino pin 8. This uses the input-capture pin (ICP1) feature of timer1.

//**********************************************************
// timer 1 capture variables for computing sq wave period	  
volatile unsigned int T1capture, lastT1capture, period ; 
// timer 1 capture ISR
ISR (TIMER1_CAPT_vect)
begin
    // read timer1 input capture register
    T1capture = ICR1 ; 
    // compute time between captures
    period =  T1capture - lastT1capture;
    lastT1capture = T1capture ;
end

//**********************************************************   

In the initialization section set up the timer (section 16 of datasheet, and especially 16.11)

//set up timer1 for full speed and
//capture an edge on analog comparator pin B.3 
// Set capture to positive edge, full counting rate
TCCR1B = (1<<ICES1) + 1; 
// Turn on timer1 interrupt-on-capture
TIMSK1 = (1<<ICIE1) ;
// turn off other timer1 functions
TCCR1A = 0;
In the loop section, just read the period variable.

(2) Using external interrupt with timer1:
Enable an external interrupt in the Arduino interface and set up timer1 to run continuously.

TCCR1B = 1; 
// turn off other timer1 functions
TCCR1A = 0;

Each time the external interrupt happens, read the timer register (TCNT1) and subtract.
This method is less accurate than method 1 because of the time it takes to execute the interrupt.

(3) Using external interrupt with Arduino timer:
Enable an external interrupt in the Arduino interface and read the Arduino microsecond function when the interrupt occurs.
This method is the easiest, and much less accurate then either of the above methods.
The time resolution cannot be better than 4 microcseconds.