Timer/Counter Modified from Dr. Lam Phung’s Slides
Timers in AVR Many computer applications require accurate timing. Examples include recording the time when an event occurs, calculating the time difference between events, performing tasks at specific or periodic times, creating accurate time delays, generating waveforms of certain shape, period, or duty cycle
Timer terminology Input Capture: Output Compare: An input signal is connected to a pin, called input capture, of the timer. When a preset event (rising edge, falling edge, change) occurs on this pin, the current timer value is stored in a register. Output Compare: A timer typically has a pin, called output compare. When the timer reaches a preset value, the output compare pin can be automatically changed to logic 0 or logic 1.
Overview of Timers in ATmega8535 ATmega8535 has three timers: Timer 0, Timer 1 and Timer 2. Each timer is associated with a counter and a clock signal. The counter is incremented by 1 in every clock cycle of the timer. The clock signal of a timer can come from the internal system clock or an external clock source.
Overview of Timers in ATmega8535 When the internal system clock is used, a prescaler can be applied to make the timer count at a slower rate. Example: Consider a system clock of 1Mhz (i.e. 1μs per cycle). Suppose that a timer prescaler of 64 is used. Then, timer will increment every 64μs.
Overview of Timers in ATmega8535
Registers
Timer/Counter Control Register – TCCR0 Bit 7 – FOC0: Force Output Compare The FOC0 bit is only active when the WGM00 bit specifies a non-PWM mode. However, for ensuring compatibility with future devices, this bit must be set to zero when TCCR0 is written when operating in PWM mode.
Timer/Counter Control Register – TCCR0 Bit 2:0 – CS02:0: Clock Select The three Clock Select bits select the clock source to be used by the Timer/Counter.
Timer/Counter Register – TCNT0 The Timer/Counter Register gives direct access, both for read and write operations, to the Timer/Counter unit 8-bit counter. Writing to the TCNT0 Register blocks (removes) the Compare Match on the following timer clock. Modifying the counter (TCNT0) while the counter is running, introduces a risk of missing a Compare Match between TCNT0 and the OCR0 Register.
Output Compare Register – OCR0 The Output Compare Register contains an 8-bit value that is continuously compared with the counter value (TCNT0). A match can be used to generate an output compare interrupt, or to generate a waveform output on the OC0 pin.
Timer/Counter Interrupt Mask Register – TIMSK Bit 1 – OCIE0: Timer/Counter0 Output Compare Match Interrupt Enable When the OCIE0 bit is written to one, and the I-bit in the Status Register is set (one), the Timer/Counter0 Compare Match interrupt is enabled. The corresponding interrupt is executed if a Compare Match in Timer/Counter0 occurs (i.e., when the OCF0 bit is set in the Timer/Counter Interrupt Flag Register – TIFR).
Timer/Counter Interrupt Mask Register – TIMSK Bit 0 – TOIE0: Timer/Counter0 Overflow Interrupt Enable When the TOIE0 bit is written to one, and the I-bit in the Status Register is set (one), the Timer/Counter0 Overflow interrupt is enabled. The corresponding interrupt is executed if an overflow in Timer/Counter0 occurs (i.e., when the TOV0 bit is set in the Timer/Counter Interrupt Flag Register – TIFR).
Example using Timer/Counter Setting Up Timer/Counter0 : TCCR0 Prescaler @ 1024, Waveform Generator Off, Output Compare off. Prescaler @ 1024 CS02:0 = 5 (101) // Prescaler = FCPU/1024 TCCR0|=(1<<CS02)|(1<<CS00);
Example using Timer/Counter Setting Up Timer/Counter0 : TCCR0 Enable Overflow Interrupt Not like setting up external interrupt But still need to enable global interrupt in SREG //Enable Overflow Interrupt Enable TIMSK|=(1<<TOIE0);
Example using Timer/Counter ISR for Timer0 Overflow @ 61.03515625 Hz ISR(TIMER0_OVF_vect) { //This is the interrupt service routine for TIMER0 OVERFLOW Interrupt. //CPU automatically call this when TIMER0 overflows. //Increment our variable N++; if(N==61) PORTC=~PORTC; //Invert the Value of PORTC N=0; }
// File: timer0.c // Date modified: 17 Sept 2012 // By: Yudi Gondokaryono #include <avr/io.h> // avr header file for IO ports #include <avr/interrupt.h> // avr header file for interrupts volatile uint8_t N; int main(void) { // Prescaler = FCPU/1024 TCCR0|=(1<<CS02)|(1<<CS00); //Enable Overflow Interrupt Enable TIMSK|=(1<<TOIE0); //Initialize Counter TCNT0=0; //Initialize our variable N=0; //Port C[3,2,1,0] as output DDRC|=0x0F; PORTC=0x0F; // Turn off LEDs