Solved=>Strange Timer0 in pooling Normal mode

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Many a times big problems get solved quickly but the tiny problems like this one below eat-up the head ;)

This code is for blinking LEDs every second.
I know better and perfect ways to generate 1 second, but I am behind perfecting this code. This code is based on ATmega32 running at 4MHz external crystal.

The actual output looks like blinking thrice in one second. Its strange. And if the volatile keyword removed then it blinks 8 times in one second.

The value 15686 may not be 100% perfect but its not off the goal by major difference.

Here is the code:

#include 

#define LEDPORT PORTB
#define LEDDDR  DDRB
#define LED1	4
#define LED2	5
#define LED3	6
#define LED4	7

volatile long count=0;	
volatile int status=0;
    
int main(void)
{
    
	//Set 4,5,6,7th bit of DDRB to high
	//This makes it as output pin
	LEDDDR=_BV(LED1) | _BV(LED2) | _BV(LED3) | _BV(LED4);
	
	//Start Timer 0
    TCCR0=0x01;
	while(1)    
	{		
        for(count=0;count<15686;count++)
		{			    
            while(bit_is_clear(TIFR,TOV0));            
		}	
        if(status==0)
        {
            LEDPORT=0x00;
            status=1;
        }
        else
        {         
            LEDPORT=0xff;
            status=0;
        }
	}	
return 0;
}

Can any one point my mistake?

YB

Last Edited: Sun. Jan 4, 2009 - 06:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Who is clearing the TOV0 after it is set? You are not clearing it, the mega32 is not clearing it, I'm not clearing it, no one else here is clearing it, so it must still be set after the first overflow.

Quote:
I know better and perfect ways to generate 1 second
Then we will let you experiment in peace. Now put your lab coat and thinking cap back on, and go to work.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Who is clearing the TOV0 after it is set? You are not clearing it, the mega32 is not clearing it, I'm not clearing it, no one else here is clearing it, so it must still be set after the first overflow.

I have tried this before the original post.
I tried TIFR=0x00; just after the "for loop"
But had same result.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I tried TIFR=0x00; just after the "for loop"
Now go read the datasheet to see how its supposed to be cleared (thinking cap stays on, lab coat optional).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

curtvm wrote:
Quote:
I tried TIFR=0x00; just after the "for loop"
Now go read the datasheet to see how its supposed to be cleared (thinking cap stays on, lab coat optional).

Datasheet:

Bit 0 – TOV0: Timer/Counter0 Overflow Flag
The bit TOV0 is set (one) when an overflow occurs in Timer/Counter0. TOV0 is cleared
by hardware when executing the corresponding interrupt handling vector. Alternatively,
TOV0 is cleared by writing a logic one to the flag.

Quote:
Alternatively,
TOV0 is cleared by writing a logic one to the flag.

Which flag this datasheet pointing to?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Solved Finally:
Here are the steps:
Start Loop=>
Select clock Frequency (This starts Timer0)
Wait for TOV0 to overflow
Stop Timer0
Clear Overflow Flag
Loop back=>

Thus the modified part of the code is:

       for(count=0;count<15625;count++)
       {
	 TCCR0=0x01;			    
         while(bit_is_clear(TIFR,TOV0));            
	 TCCR0=0x00;
	 TIFR = _BV(TOV0);
	}

Thanks for the help curtvm.

YB

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There's no need to stop the timer to clear the interrupt flag.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jayjay1974 wrote:
There's no need to stop the timer to clear the interrupt flag.

I have not used interrupts.

Your point is valid. Even if using pooling, no need to stop the timer.

Modified loop here :

while(1)    
	{	
		TCCR0=0x01;			    
        for(count=0;count<15625;count++)
		{			
            while(bit_is_clear(TIFR,TOV0));            		
			TIFR = _BV(TOV0);
		}	
		
		
		
        if(status==0)
        {
            LEDPORT=0x00;
            status=1;
        }
        else
        {
            LEDPORT=0xff;
            status=0;
        }
	}