Control AVR 8 bit Timer-Counter0 using AVR-GCC

Timers are an essential part of embedded systems. They make your life much more comfortable if used properly. Timers run independently to the main program flow so that they can do the job individually without disturbing precious calculations done by the CPU. You just set up the timer and let it run while your main program performs other tasks. Timers are easy to set up. In this post, an example is made for Atmega8 timers. Other AVR microcontroller models and even different brand chips have similar timers.

Atmega8 has two 8-bit timers/counters and one 16-bit timer counter with many abilities.

Standard 8-bit Timer/Counter0 features are:

  • Single channel counter;
  • Frequency generator;
  • External Event counter;
  • 10–bit clock Prescaler.

TCNT0 is an 8-bit timer counter register that keeps the current count number. The timer counter can be clocked by an external clock through pin T0 or from internal via pre-scaler. The timer counter increments (MAX value is 0xFF) and then restarts from BOTTOM=0x00. After the timer Overflows, the flag TOV0 is written to 1, and if TOIE0 bit in SREG is set, then timer overflow interrupt is executed. TOV0 acts as a ninth bit of counter register that is only set but not cleared. When this bit is combined with timer overflow interrupt – then it is automatically cleared. If you need to start the counter form different number rather than BOTTOM, then you can write any value to TCNT0 register at any time.

Prescaler may have values 1, 8, 64, 256, 1024. Like in the picture, you may see prescaling at eight clock cycles.

Timer counter prescaler is controlled by writing values to the TCCR0 register(refer to datasheet for specific values).

A prescaler counter may be reset by setting bit0 (PSR10) to one in the SFIOR register. This clears prescaler counter value, and this affects both 8-bit timers. PSR10 has cleared automatically after the timer reset is complete.

As this timer is simplest of all timers of AVR working with it is very simple:

#include <avr\io.h>
#include <avr\iom8.h>
#include <avr\interrupt.h>
#define outp(a, b) b = a

uint8_t led;
/* signal handler for timer interrupt TOV0 */
ISR(TIMER0_OVF_vect) {
    led++;
   }
int main(void) {
/* use PortB for output (LED) */
    outp(0xFF, DDRB);      
/*enable timer overflow interrupt*/
    outp((1<<TOV0), TIMSK);
/*set timer counter initial value*/
    TCNT0=0x00;
/*start timer without presscaler*/
	outp((1<<CS00), TCCR0);
/* enable interrupts */
	sei();       
/*Initial led value*/
    led =  0x00;
    for (;;) {
/* loop forever timer interupts will
change the led value*/
    outp(led, PORTB);
    }                      
}

You can find a good timer calculator here: https://eleccelerator.com/avr-timer-calculator/

One Comment:

  1. This is imported post from winavr.scienceprog.com
    Please let us know if you face any errors

Leave a Reply