[ Curiosity,Experimentation ]

Random stuff from the parallel universe of Ones and Zeroes

Archive for July, 2010

Programming the Timers in AVR [avr-gcc]

Posted by appusajeev on July 16, 2010

All the Atmel® AVR microcontrollers have TIMERs as an inbuilt peripheral . They can be used to generate PWM(Pulse Width Modulation)waves, for generating accurately timed pulses and for registering the timestamp of external events(Input capture mode). ATMEGA 16 and ATMEGA 8(which we focus on in this post) microcontrollers have 3 inbuilt timers in them, one 16 bit timer and two 8 bit timers. These timers run independent of the program being executed and are capable of generating interrupts. Here i will be explaining about the 16 bit timer 1 of ATMEGA 8 and the same applies to ATMEGA 16 as well.

A timer (also called as counter) is simply a device that counts upon receiving clock pulses. The timer increments (or decrements in certain cases)its count with each clock tick it receives.  A timer is usually specified by the maximum value to which it can count (called MAX) beyond which it overflows and resets to zero(BOTTOM). Thus an 8-bit timer/counter can count from 0 through 255 and a 16-bit timer/counter can count from 0 through 65,535.
The speed of counting can be controlled by varying the speed of clock input to it. This is done by prescaling the clock of the microcontroller. By prescaling, we feed a fraction of the CPU clock to the timer.

Timer speed =F_CPU / prescaler

where F_CPU is the AVR CPU clock speed.Normal prescaler values are 1,8,64,256 and 1024. For example, for a 1MHZ clock, if prescaler is 64, then timer speed is  1000000/64=15625 i.e.  in one second,  the timer can count from 0 to 15625.
When the timer reaches the maximum value it can count, it is said to overflow and it automatically resets to 0 and starts counting again. We can set an interrupt to occur when the timer overflows.
When the timer 1 overflows, TOV1 bit will be set in the TIFR (Timer Interrupt Flag Register) register which will be cleared automatically when the corresponding ISR executes or it can be cleared by setting TOV1 bit to 1(odd, but that’s how ATMEL guys want us to clear it !).

Starting the timer

A counter starts counting as soon as it is set to use a clock source, by setting a suitable prescaler value bits CS10,CS11 and CS12 in the TCCR1B (Timer Counter Control Register 1 B )register . The instantaneous value of the timer is available anytime in the TCNT (Timer Count) register. Refer datasheet for more information on various bits in the register.

Timer in Compare Mode (CTC mode)

The timer used in above mode is of not much use as such. The AVR timer can be operated in a mode called CTC mode or Clear on Timer Capture mode in which we can set the timer to compare its count with a certain value set in OCR1A (Output Compare Register 1 A) register or OCR1B register and generate an interrupt or manipulate the OC1A or OC1B pin whenever a match occurs (i.e. when TCNT=OCR1A or TCNT=OCR1B).CTC mode can be used to generate accurate timings and square waves of desired frequency.
CTC mode can be enabled by setting WGM 12 bit=1 in TCCR1B register.
When TCNT=OCR1A, the timer resets and starts from 0 again. The value of OCR1A can be changed anytime and the change in the output will be reflected immediately.

toggling OC1A pin in CTC mode

toggling OC1A pin in CTC mode

When a match occurs we can either Set,Clear or toggle the OC1A/OC1B  pin.The action of OC1A pin can be set by setting suitable values for COM1A0 and COM1A1 bits in TCCR1A (Timer Counter Control Register 1 A) register (refer datasheet).

Whenever a compare match occurs, the OCF1A bit will be set in the TIFR(Timer Interrupt Flag Register) which will automatically be cleared when the associated ISR fires or else we have to manually clear it by setting it to 1.

The following example demonstrates CTC mode of Timer 1. An LED is connected to t0 PB1 pin(pin 15) of Atmega8 which flashes at 1 hz.

Atmega8 Timer 1 in CTC toggle mode

Atmega8 Timer 1 in CTC toggle mode

Generating Square Waves

With the OC1A pin set to toggle by setting COM1A0=1 in TCCR1A register, this mode can be used to generate a square wave of required frequency(50% duty cycle only though) by setting a suitable value in the OCR1A register.
As said above, the value of OCR1A can be changed anytime and the change in the output will be reflected immediately

The frequency of the square wave generated is given by

f = F_CPU / (2.prescaler.(1+OCR1A))

Generating Square waves in CTC mode

Generating Square waves in CTC mode

For eg, to generate a 50Hz square wave, set OCR1A=291

Timers and interrupts

AVR timers can generate 3 types of interrupts- Overflow, Compare match and Input Capture (Input capture is a mode in which we can have the value of the  TCNT register copied to the ICR register whenever  a rising/falling edge is found on the ICP1 pin of the ATMEGA) and we can execute a user specified ISR for these as demonstrated.
To enable interrupts, first we have to enable compare match interrupt for  timer 1 by setting OCIE1A (Output Compare A Match Interrupt Enable) bit in the TIMSK register and then we have to enable global interrupts with the sei() macro. For handling overflow interrupts, set TOIE1 bit in TIMSK register to 1.

The following example demonstrates the use of interrupts. The interrupt service routine(ISR) toggles the LED connected to pin 1 of port B.

Timer 1 Interrupt Handling

Timer 1 Interrupt Handling

Posted in avr-gcc | Tagged: , , | 14 Comments »