Go Down

Topic: Delay with timer/counter2 is too short (Read 862 times) previous topic - next topic

eladp

Hello all,

I'm trying to use the following delay functions (which I've copied from a sample) with my duemilanove.
The problem is that if I do a delay_ms(1000) it only waits 0.25ms.
I've tried to look at the Atmega docs and don't understand the problem.
The "TCCR2B = (1<<CS21);" command should set the timer clock at 1MHz, right? So the code should work.
Any thoughts?

Here is the code (this is not the entire code, there are other SPI related stuff in there which I omitted) :

//General short delays
void delay_ms(uint16_t x)
{
    for (; x > 0 ; x--)
        delay_us(1000);
}

//General short delays
void delay_us(uint16_t x)
{
    while(x > 256)
    {
        TIFR2 = (1<<TOV2); //Clear any interrupt flags on Timer2
        TCNT2 = 0; //256 - 125 = 131 : Preload timer 2 for x clicks. Should be 1us per click
        while( (TIFR2 & (1<<TOV2)) == 0);

        x -= 256;
    }

    TIFR2 = (1<<TOV2); //Clear any interrupt flags on Timer2
    TCNT2= 256 - x; //256 - 125 = 131 : Preload timer 2 for x clicks. Should be 1us per click
    while( (TIFR2 & (1<<TOV2)) == 0);
}

void setup()
{
  // initialize the serial communications:
  Serial.begin(9600);
  TCCR2B = (1<<CS21);

  char count = 0;

  while (1)
  {
    Serial.println(count, DEC);
    delay_ms(1000);
    count++;
  }
}

Coding Badly

Quote
I'm trying to use the following delay functions...


Why?  What's wrong with delay and delayMicroseconds?

eladp

Nothing.
These functions work correctly.

I did see a recommendation somewhere to use the timer2 for delays if one needs to do other stuff (instead of just busy waiting).
Also, as I am having problems with my SPI communication to the BMA180 (for which this sample code was supplied), I want to
know if that may be related to some kind of timing issues (and to generally understand the timing in the Atmega328).


Coding Badly

Got it.

Code: [Select]
void setup()
{
...
  TCCR2B = (1<<CS21);


I strongly suggest that you set both TCCR2A and TCCR2B.  Do not assume the configuration registers are the way you want them to be.  Ideally, you should disable the timer first...

Code: [Select]
  TCCR2B = 0;
  TCCR2A = /* put code here to configure the timer*/;
  TCCR2B = /* put code here to configure and start the timer*/;

eladp

Thanks for the prompt reply.
I'll try later and update on the result.

eladp

When I also zeroed TCCR2B I got a delay_ms(1000) of 0.5s.

Can this be explained by the fact that my Duemilanove is 16Mhz (and maybe the sample was taken from an 8Mhz one)?

Coding Badly

Yes.  The timers are driven from the processor clock.  If the processor clock speed is doubled, the timers also run twice as fast.

eladp

So I can close the file on this one.
Thanks Coding Badly for the tip.

Go Up