Time Delays in ATmega 16


There are three ways to create a time delay inAVR C.
􀁹 Using the AVR timers
􀁹 Using a simple for loop
􀁹 Using predefined C functions

Generally, we use timer/counter to generate time delays, waveforms or to count events. Also, the timer is used for PWM generation, capturing events etc.

In AVR ATmega16 / ATmega32, there are three timers:

Timer0: 8-bit timer
Timer1: 16-bit timer
Timer2: 8-bit timer

Basic registers and flags of the Timers

TCNTn: Timer / Counter Register

Every timer has timer/counter register. It is zero upon reset. We can access value or write a value to this register. It counts up with each clock pulse.

TOVn: Timer Overflow Flag

Each timer has Timer Overflow flag. When timer overflows, this flag will get set.

TCCRn : Timer Counter Control Register

This register is used for setting the modes of timer/counter.

OCRn : Output Compare Register

The value in this register is compared with the content of the TCNTn register. When they are equal,

Let us see Timer0 to understand the timers in ATmega16 / ATmega32

Timer0
First, we need to understand the basic registers of the Timer0

1.TCNT0: Timer / Counter Register 0
            It is an 8-bit register. It counts up with each pulse.

2. TCCR0: Timer / Counter Control register 0

            This is an 8-bit register used for the operation mode and the clock source selection.

Read about reach flag at : Electronic wings

Creating Delay Using Timer0

Steps to Program Delay using Timer0
1. Load the TCNT0 register with initial value (let’s take 0x25).
2. For normal mode and pre-scaler option of the clock, set the value in TCCR0 register. As soon as clock prescaler value gets selected, the timer / counter starts to count, and each clock tick causes the value of timer / counter to increment by 1.
3.Timer keeps counting up, so keep monitoring for timer overflow i.e. TOV0 (Timer0 Overflow) flag to see if it is raised.
4. Stop the timer by putting 0 in the TCCR0 i.e. the clock source will get disconnected and the timer / counter will get stopped.
5. Clear the TOV0 flag. Note that we have to write 1 to the TOV0 bit to clear the flag.
6. Return to the main function.


*
  Generating delay using ATmega16 Timer0
  http://www.electronicwings.com
*/ 


#include <avr/io.h>

void T0delay();

int main(void)
{
 DDRB = 0xFF;  /* PORTB as output*/
     while(1)    /* Repeat forever*/
     {
  PORTB=0x55;
  T0delay();   /* Give some delay */
  PORTB=0xAA;
  T0delay();
     }
}

void T0delay()
{
 TCNT0 = 0x25;    /* Load TCNT0*/
 TCCR0 = 0x01;    /* Timer0, normal mode, no pre-scalar */
 while((TIFR&0x01)==0);  /* Wait for TOV0 to roll over */
 TCCR0 = 0;
 TIFR = 0x1;    /* Clear TOV0 flag*/
}

The time delay generated by above code
As Fosc = 8 MHz
T = 1 / Fosc = 0.125 μs
Therefore, the count increments by each 0.125 μs.
In above code, the number of cycles required to roll over are:
0xFF - 0x25= 0xDA i.e. decimal 218
Add one more cycle as it takes to roll over and raise TOV0 flag: 219
Total Delay = 219 x 0.125 μs = 27.375 μs

Program for 10 ms Delay Using Timer0

Example
Let us generate a square waveform having 10 ms high and 10 ms low time:
First, we have to create a delay of 10 ms using timer0.
*Fosc = 8 MHz
Use the pre-scalar 1024, so the timer clock source frequency will be,
8 MHz / 1024 = 7812.5 Hz
Time of 1 cycle = 1 / 7812.5 = 128 μs
Therefore, for a delay of 10 ms, number of cycles required will be,
10 ms / 128 μs = 78 (approx)
We need 78 timer cycles to generate a delay of 10 ms. Put the value in TCNT0 accordingly.
Value to load in TCNT0 = 256 – 78 (78 clock ticks to overflow the timer
= 178 i.e. 0xB2 in hex
Thus, if we load 0xB2 in TCNT0 register, the timer will overflow after 78 cycles i.e. precisely after a delay of 10 ms.
CODE
/*
  Generating a delay of 10 ms using ATmega16 Timer0 
  www.electronicwings.com
 */ 


#include <avr/io.h>

void T0delay();

int main(void)
{
 DDRB = 0xFF;  /* PORTB as output */
 PORTB=0;
     while(1)    /* Repeat forever */
     {
  PORTB= ~ PORTB;
  T0delay();
     }
}

void T0delay()
{
 TCCR0 = (1<<CS02) | (1<<CS00); /* Timer0, normal mode, /1024 prescalar */
 TCNT0 = 0xB2;    /* Load TCNT0, count for 10ms */
 while((TIFR&0x01)==0);  /* Wait for TOV0 to roll over */
 TCCR0 = 0;
 TIFR = 0x1;    /* Clear TOV0 flag */
}

Ref:[1]Prof.Gaurav Verma
    [2]http://www.electronicwings.com/avr-atmega/atmega1632-timer



Comments

Popular Posts