Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

ATmega328 Timer 0 ms delay and Timer 1 us delay

Status
Not open for further replies.

imranahmed

Advanced Member level 3
Joined
Dec 4, 2011
Messages
817
Helped
3
Reputation
6
Reaction score
3
Trophy points
1,298
Location
Karachi,Pakistan
Activity points
6,492
Please let me know I wrote 2 functions for generating delay of 1ms by timer 0 and 1us delay for timer 1 but it is not working properly why please check it and give comments, I calculate using MikroElektronica Timer Calculator.
Code:
/// Timer 1 Code for us delay ///

void initTimer1() {

  //set timer 1 into CTC mode by placing 1 into WGM12.  all others are zero
  TCCR1A &= ~(1 << WGM10);
  TCCR1A &= ~(1 << WGM11);
  TCCR1B |= (1 << WGM12);
  TCCR1B &= ~(1 << WGM13);
  // calculate OCR1A for a 1us delay.  OCR1A = (Td * fclk)/ Ps
  // prescaler of 8
  // OCR1A = (1e-6 * 16e6)/8
  // OCR1A = 2
  //start the clock with prescaler 8 and OCR1A = 2
  TCCR1B &= ~((1 << CS12) | (1 << CS10));
  TCCR1B |=  (1 << CS11);
  OCR1A = 2;
}
void delayUs(unsigned int delay) {

  unsigned int count = 0;

  // set the counter flag down
  TIFR1 |= (1 << OCF1A);

  // clear the count register
  TCNT1 = 0;

  // enter a loop to compare count with delay value needed
  while (count < delay) {

    if (TIFR1 & (1 << OCF1A)) { //increment every time the timer raises a flag (counting 1 us flags)

      count++;

      TIFR1 |= (1 << OCF1A);  //set timer to start counting again
    }
  }

}

Code:
/// Timer 0 Code for ms delay///

void initTimer0() {
  // set the timer mode to be "CTC"
  TCCR0A &= ~(1 << WGM00);
  TCCR0A |=  (1 << WGM01);
  TCCR0B &= ~(1 << WGM02);
  OCR0A = 249;
 
}

/* This delays the program an amount specified by unsigned int delay.
  Use timer 0. Keep in mind that you need to choose your prescalar wisely
  such that your timer is precise to 1 millisecond and can be used for
  100-200 milliseconds
*/
void delayMs(unsigned int delay) {
  for (int x = 0 ; x <= delay ; x++) {
    OCR0A = 249;
    TCCR0A = 0x28;
    TCCR0B |= 0x04;
  }
}
 

You were on the right track for your timer delays. The timer1 Us delay could be modified with a pre-scale of 1, and an OCR1A = 14 to give better
Us resolution. The Timer 0 delay looks like it was never completed. The format can basically follow the Timer1 format you used. A prescale of 64
along with the OCR0A = 249 you gave seems to give the correct results.

Below is the code you gave with the changes above and a main() function to test the output using a scope on a PORTB pin.

Code:
#include <avr/io.h>  // (atmel studio 6 include)

void delay();
void delayMs(unsigned int delay);
void delayUs(unsigned int delay);
void initTimer1();
void initTimer0();

int main()
{
    DDRB = 0xFF;
    initTimer1();
    initTimer0();
 
    while(1)
      {
      PORTB = 0xff;
      delayMs(5);
   
      PORTB = 0x00;
      delayMs(5);

   /* PORTB = 0xff;
      delayUs(5);
 
      PORTB = 0x00;
      delayUs(5);  */
      }
    return(1);
}



/// Timer 1 Code for us delay ///

void initTimer1() {

  //set timer 1 into CTC mode by placing 1 into WGM12.  all others are zero
  TCCR1A &= ~(1 << WGM10);
  TCCR1A &= ~(1 << WGM11);
  TCCR1B |= (1 << WGM12);
  TCCR1B &= ~(1 << WGM13);
  // calculate OCR1A for a 1us delay.  OCR1A = (Td * fclk)/ Ps
  // prescaler of 1
  // OCR1A = (1e-6 * 16e6)/8    
  // OCR1A = 2
  //start the clock with prescaler 1 and OCR1A = 14
  TCCR1B &= ~(1 << CS12);
  TCCR1B |=  (1 << CS10);
  TCCR1B &= ~(1 << CS11);
  OCR1A = 14;
}


void delayUs(unsigned int delay)
{
unsigned int count = 0;

  TIFR1 |= (1 << OCF1A);  // set the counter flag down

  TCNT1 = 0;  // clear the count register

  // enter a loop to compare count with delay value needed
  while (count < delay)
    {
    if (TIFR1 & (1 << OCF1A))
      { //increment every time the timer raises a flag (counting 1 us flags)
      count++;
      TIFR1 |= (1 << OCF1A);  //set timer to start counting again
      }
  }
}


/// Timer 0 Code for ms delay//

void initTimer0() {

    //set timer 0 into CTC mode by placing 1 into WGM01.  all others are zero
    TCCR0A &= ~(1 << WGM00);  // 0
    TCCR0A |= (1 << WGM01);   // 1
    TCCR0B &= ~(1 << WGM02);  // 0
 
     //start the clock with prescaler 64 and OCR0A = 249

    TCCR0B |= (1 << CS00);
    TCCR0B |= (1 << CS01);
    TCCR0B &= ~(1 << CS02);
    OCR0A = 249;
}

/* This delays the program an amount specified by unsigned int delay.
  Use timer 0. Keep in mind that you need to choose your prescalar wisely
  such that your timer is precise to 1 millisecond and can be used for
  100-200 milliseconds
*/


void delayMs(unsigned int delay)
{
    unsigned int count = 0;
 
    TIFR0 |= (1 << OCF0A);  // set the counter flag down

    TCNT0 = 0;  // clear the count register

    // enter a loop to compare count with delay value needed
    while (count < delay)
      {
      if (TIFR0 & (1 << OCF0A))
        { //increment every time the timer raises a flag (counting 1 us flags)
        count++;
        TIFR0 |= (1 << OCF0A);  //set timer to start counting again
        }
      }
}
 
Last edited:
You were on the right track for your timer delays. The timer1 Us delay could be modified with a pre-scale of 1, and an OCR1A = 14 to give better
Us resolution. The Timer 0 delay looks like it was never completed. The format can basically follow the Timer1 format you used. A prescale of 64
along with the OCR0A = 249 you gave seems to give the correct results.

Below is the code you gave with the changes above and a main() function to test the output using a scope on a PORTB pin.

Code:
#include <avr/io.h>  // (atmel studio 6 include)

void delay();
void delayMs(unsigned int delay);
void delayUs(unsigned int delay);
void initTimer1();
void initTimer0();

int main()
{
    DDRB = 0xFF;
    initTimer1();
    initTimer0();

    while(1)
      {
      PORTB = 0xff;
      delayMs(5);
  
      PORTB = 0x00;
      delayMs(5);

   /* PORTB = 0xff;
      delayUs(5);

      PORTB = 0x00;
      delayUs(5);  */
      }
    return(1);
}



/// Timer 1 Code for us delay ///

void initTimer1() {

  //set timer 1 into CTC mode by placing 1 into WGM12.  all others are zero
  TCCR1A &= ~(1 << WGM10);
  TCCR1A &= ~(1 << WGM11);
  TCCR1B |= (1 << WGM12);
  TCCR1B &= ~(1 << WGM13);
  // calculate OCR1A for a 1us delay.  OCR1A = (Td * fclk)/ Ps
  // prescaler of 1
  // OCR1A = (1e-6 * 16e6)/8   
  // OCR1A = 2
  //start the clock with prescaler 1 and OCR1A = 14
  TCCR1B &= ~(1 << CS12);
  TCCR1B |=  (1 << CS10);
  TCCR1B &= ~(1 << CS11);
  OCR1A = 14;
}


void delayUs(unsigned int delay)
{
unsigned int count = 0;

  TIFR1 |= (1 << OCF1A);  // set the counter flag down

  TCNT1 = 0;  // clear the count register

  // enter a loop to compare count with delay value needed
  while (count < delay)
    {
    if (TIFR1 & (1 << OCF1A))
      { //increment every time the timer raises a flag (counting 1 us flags)
      count++;
      TIFR1 |= (1 << OCF1A);  //set timer to start counting again
      }
  }
}


/// Timer 0 Code for ms delay//

void initTimer0() {

    //set timer 0 into CTC mode by placing 1 into WGM01.  all others are zero
    TCCR0A &= ~(1 << WGM00);  // 0
    TCCR0A |= (1 << WGM01);   // 1
    TCCR0B &= ~(1 << WGM02);  // 0

     //start the clock with prescaler 64 and OCR0A = 249

    TCCR0B |= (1 << CS00);
    TCCR0B |= (1 << CS01);
    TCCR0B &= ~(1 << CS02);
    OCR0A = 249;
}

/* This delays the program an amount specified by unsigned int delay.
  Use timer 0. Keep in mind that you need to choose your prescalar wisely
  such that your timer is precise to 1 millisecond and can be used for
  100-200 milliseconds
*/


void delayMs(unsigned int delay)
{
    unsigned int count = 0;

    TIFR0 |= (1 << OCF0A);  // set the counter flag down

    TCNT0 = 0;  // clear the count register

    // enter a loop to compare count with delay value needed
    while (count < delay)
      {
      if (TIFR0 & (1 << OCF0A))
        { //increment every time the timer raises a flag (counting 1 us flags)
        count++;
        TIFR0 |= (1 << OCF0A);  //set timer to start counting again
        }
      }
}

Thank you very much I will check it now let you know. But I want to make Timer0 as Timer1 uses CTC mode.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top