Timer0 Overflow Int

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

I am writing the code for atmega8515. I am trying to rotate the LEDS. My timer overflow occurs for every 32.768 ms. Here I have attached my code. But all the LEDS are glowing (dim). what is wrong with my code?Any help? Should I need to increase/decrease the overflow rate?WHen I include the rotate code inside the ISR it is working fine. Why it is not rotating when put the code inside the for loop.

#include 



volatile uint8_t led, k, switches, i = 1 , j = 1;
  			/* uint8_t is the same as unsigned char */

int main(void)
{



	DDRB = 0xff;				/* use all pins on PortB for output */
	DDRD = 0x00;

	led = 1;					/* init variable representing the LED state */
	PORTB = 0XFF;
	
	cli( );

	TCCR0|=(1<<CS02) |(1<<CS00);

 //Enable Overflow Interrupt Enable
   TIMSK|=(1<<TOIE0);

 //Initialize Counter
   TCNT0=0x00;


      sei( );

	for ( ; ;)
	{
		
			PORTB = ~led;		
			led <<= 1;		
			if (!led)		
			{
				led = 1;
			} 
			
			
	}	

}


ISR(TIMER0_OVF_vect)
{
	TCNT0=0x00;

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

Your ISR does absolutely nothing (the timer is already at 0 from the overflow, so setting it to 0 is useless). And there is nothing in your main loop that pays attention to the interrupt, it just merrily sets PORTB to the current led value. The only thing that your interrupt does is to occasionally slightly vary the timing of the the main loop.

Regards,
Steve A.

The Board helps those that help themselves.

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

OP: Can you explain what this is supposed to do line by line.
If you can explain it, you will probably have answered your own question.

 for (; ;) 
    { 
        
          PORTB = ~led;       
          led <<= 1;       
          if (!led)       
          { 
             led = 1; 
          } 
           
           
    }

Charles Darwin, Lord Kelvin & Murphy are always lurking about!
Lee -.-
Riddle me this...How did the serpent move around before the fall?

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

Yeah not to mention that stuff like if(!led) doesn't even work. Well at least not in avr-gcc. I had that issue once and from then on I've just put the full thing if(led != 0).

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

Quote:
Yeah not to mention that stuff like if(!led) doesn't even work.
Why would you say that? It is perfectly valid C code and will work with any ANSI C compliant compiler.
Quote:
I've just put the full thing if(led != 0).
But (!led) is not at all the same as (led != 0).

Regards,
Steve A.

The Board helps those that help themselves.

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

I have chan it like this. if (led == 0) though the result is same. LEDS are not rotating . All the LEDS are glowing(dim). any idea?
ged

Koshchi wrote:
Quote:
Yeah not to mention that stuff like if(!led) doesn't even work.
Why would you say that? It is perfectly valid C code and will work with any ANSI C compliant compiler.
Quote:
I've just put the full thing if(led != 0).
But (!led) is not at all the same as (led != 0).

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

Quote:
All the LEDS are glowing(dim). any idea?
Everything is running so fast, your eye can't see the change?

--greg
Still learning, don't shout at me, educate me.
Starting the fire is easy; the hardest part is learning how to keep the flame!

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

led = 0x01;
PORTB = ~led; This will make the first led to glow.(0xfe)

led <<= 1; here led value 0x01 is left shifted by 1.So led = 0x02

if (!led ) here it checks if led is == 0.if yes led becomes one to start the next rotation. I am sorry , I do understand my code. I have no clue , why it is not cycling the LEDS & all are glowing when this part is included inside the for loop? Could you explain me?

LDEVRIES wrote:
OP: Can you explain what this is supposed to do line by line.
If you can explain it, you will probably have answered your own question.

 for (; ;) 
    { 
        
          PORTB = ~led;       
          led <<= 1;       
          if (!led)       
          { 
             led = 1; 
          } 
           
           
    }

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

Thanks for your reply.
Yes. I understood that. Here if you see my code it overflows for every 32ms. Tell me what I should do to cycle it properly.
But when I include the cycling part inside the ISR it is just perfect. Could you explain me that.

gregsmithcts wrote:
Quote:
All the LEDS are glowing(dim). any idea?
Everything is running so fast, your eye can't see the change?

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

Yes there is nothing in my main loop. I am just half way though my implementation. Any suggestions?

Koshchi wrote:
Your ISR does absolutely nothing (the timer is already at 0 from the overflow, so setting it to 0 is useless). And there is nothing in your main loop that pays attention to the interrupt, it just merrily sets PORTB to the current led value. The only thing that your interrupt does is to occasionally slightly vary the timing of the the main loop.

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

Quote:

Any suggestions?

Set a flag in the ISR when the timer overflows. In main you have a loop constantly checking that flag, and when it is set you
i) do the LED shifting dance, and
ii) clear the flag.

Don't forget to declare the flag volatile.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

Quote:
I have no clue , why it is not cycling the LEDS
But it IS cycling the LEDs, doing exactly what you told it to do. If you want to SEE the LEDs cycle, then slow it down.

Regards,
Steve A.

The Board helps those that help themselves.

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

Thanks it worked. Here is my modified implementation with some switch. Inside the ISR Iam reading the PORTD. If read value is zero, cycle the LEDS.else some switch is pressed, here I want to rotate the LEDS untill the pressed switch. That's not happening here.

What's going wrong in my else loop?Any help?
ISR(TIMER0_OVF_vect)
{

switches = ~PIND;

if(switches == 0)
{

led <<= 1;
if (!led)
{
led = 1;
}

}
else
{
switch (switches)
{
case 0x01: k = 0x01;
break;

case 0x02: k = 0x02;
break;

case 0x04: k = 0x04;
break;

case 0x08: k = 0x08;
break;

case 0x10: k = 0x10;
break;

case 0x20: k = 0x20;
break;

case 0x40: k = 0x40;
break;

case 0x80: k = 0x80;
break;

}

for(k ; k!= 0;k--)
{

k >>= 1;
}
led = k;
}
PORTB = ~led;
}

JohanEkdahl wrote:
Quote:

Any suggestions?

Set a flag in the ISR when the timer overflows. In main you have a loop constantly checking that flag, and when it is set you
i) do the LED shifting dance, and
ii) clear the flag.

Don't forget to declare the flag volatile.


[/code:1]
</pre></blockquote>
</div>
<p>[code:1]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
for(k ; k!= 0;k--)
{
   k >>= 1;
}
led = k; 

First, you are changing k twice in the loop, so it certainly will not do whatever it is you are trying to do. Second, if and when it does exit the loop, k will always be 0 (since that is the one and only condition you have set to exit the loop), so led will be set to 0.

Regards,
Steve A.

The Board helps those that help themselves.

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

I am in a confusion where to put PORTB = ~led. When I do like this
for(k ; k!= 0;k--)
{
PORTB = ~K;
k >>= 1;
}

This should be fine. But When I do PORTB = ~K inside for loop, it's like first when none of the switches are pressed, cycling of the LED IS justperfect. When I Press the switch, all the LEDS are off. When i release the switch, again the cycling starts. But I want to cycle the LEDS UNTILL THE pressed switch.
ISR(TIMER0_OVF_vect)
{

switches = ~PIND;

if(switches == 0)
{

PORTB = ~led;
led <<= 1;
if (!led)
{
led = 1;
}

}
else
{

for(k ; k!= 0;k--)
{
PORTB = ~k;
k >>= 1;
}

}

}

Koshchi wrote:

for(k ; k!= 0;k--)
{
   k >>= 1;
}
led = k; 

First, you are changing k twice in the loop, so it certainly will not do whatever it is you are trying to do. Second, if and when it does exit the loop, k will always be 0 (since that is the one and only condition you have set to exit the loop), so led will be set to 0.

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

Quote:
This should be fine.
No, it is not fine. Again, you are changing k twice in the loop (k >> 1 and k--). It does not do what you want it to do.

Regards,
Steve A.

The Board helps those that help themselves.

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

Why do you use the code tag sometimes, but not other times ? Use it EVERY time.

OP wrote:
All the LEDS are glowing(dim)
Speed kills:

for(; ; ){

        PORTB = ~led;
         _delay_ms( 500 );// Or whatever number you want.   
         
         led <<= 1;      
         if ( led == 0 ){

            led = 1;
         }  
       
} // End for(;;)

Change your first posted code to this, in main() NOT the ISR, and it will work. Get rid of the ISR, for now. BUT to use the ISR, just do what people have already told you for making it work with the ISR. It makes no sense for you to add all that extra code when you see yourself that the LED code does work ( in the ISR ), so that's a clue: don't change THAT code ! :wink:

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

Last Edited: Wed. May 4, 2011 - 08:32 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Change your first posted code to this, in main() NOT the ISR, and it will work.
But that defeats the purpose of using the ISR in the first place.

Regards,
Steve A.

The Board helps those that help themselves.

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

It's just to show the OP whats wrong with his OP ( I did say take ISR out as it has no purpose in my code ). THEN to use the ISR, OP needs to increase OVF time and use a flag, as he/she's ALREADY been told ( but hasn't done :? ).

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

That's right.Thanks for pointing my mistake. I dont want use simple delay loop for rotating. I want to use the timer instead of the delay loop.

Koshchi wrote:
Quote:
This should be fine.
No, it is not fine. Again, you are changing k twice in the loop (k >> 1 and k--). It does not do what you want it to do.

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

Time for a cup of tea!
You now have all the answers to the problems you've currently encountered.
Look again at all the code(s) you've posted, and look again at all the (very good) advice you've been given.
Next time you post your code(s) I expect to see a fully working program which does everything you want it to! (All the answers have already been given).
Like I said, have a cup of tea and review what you have discovered and learned.
And never forget, drawing a picture/flowchart/timing diagram etc.. works wonders for your understanding of what is 'actually' happening.

Long live the pencil!

--greg
Still learning, don't shout at me, educate me.
Starting the fire is easy; the hardest part is learning how to keep the flame!

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

Milk, how many sugars?

Charles Darwin, Lord Kelvin & Murphy are always lurking about!
Lee -.-
Riddle me this...How did the serpent move around before the fall?

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

indianajones11 wrote:
It's just to show the OP whats wrong with his OP ( I did say take ISR out as it has no purpose in my code ). THEN to use the ISR, OP needs to increase OVF time and use a flag, as he/she's ALREADY been told ( but hasn't done :? ).

Here is my code with your suggestions. It is working partly. It is cycling the LEDS when none of the switches are pressed. When i press some switch, one of the LEDs is on as long as push the switch(which means that cycling stops at one LED on as long as i is press the switch). Cycling continues after I release my hand out of the switch. But this cycling should happen from 0 to whichever switch is pressed.

In my code, If I press the switch 3, case 0x04 gets executed, the cycling should happen untill the 3 rd LED. but it just stopS at SOME LED ON.Could anyone help me?[/code]int main(void)
{

DDRB = 0xff; /* use all pins on PortB for output */
DDRD = 0x00;

led = 1; /* init variable representing the LED state */
PORTB = 0XFF;

cli( );

TCCR0|=(1<<CS02) |(1<<CS00);

//Enable Overflow Interrupt Enable
TIMSK|=(1<<TOIE0);

//Initialize Counter
TCNT0=0;

// GICR = BIT(INT0);
// MCUCR = BIT(ISC01) | BIT(ISC00);

sei( );

for ( ; ;)
{

if(ovrflow) {

PORTB = ~led;

if(switches)
{

switch (switches)
{
case 0x01:
break;

case 0x02:
break;

case 0x04:
if(j < 3) {

j++;
led <<= 1;

if(led == 0x04)
led = 1;

}

break;

case 0x08:
break;

case 0x10:
break;

case 0x20:
break;

case 0x40:
break;

case 0x80:
break;

}

} //if (switches)

else
{
led <<= 1;
if (led == 0)
{
led = 1;
}
}

ovrflow = 0;

} // if ovrflow

} //for

} //main

ISR(TIMER0_OVF_vect)
{

switches = ~PIND;

ovrflow = 1;
}

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

Here is my new code to rotate the LEDS. But the problem here is , it is not cycling when I press the switch. It just stops at one LED on, when I release the switch again cycling starts. I press the switch 3, it executes case 0x04, there i have the routine to roate the LEDS untill 3rd LED.that's not happening here.Why?



int main(void)
{

	DDRB = 0xff;				/* use all pins on PortB for output */
	DDRD = 0x00;

	led = 1;					/* init variable representing the LED state */
	PORTB = 0XFF;
	
	cli( );

	TCCR0|=(1<<CS02) |(1<<CS00);

 //Enable Overflow Interrupt Enable
   TIMSK|=(1<<TOIE0);

 //Initialize Counter
   TCNT0=0;


  // MCUCR = BIT(ISC01) | BIT(ISC00);

   sei( );

	for ( ; ;)
	{
 
		if(ovrflow) {

		PORTB = ~led;

		if(switches)
		{
		
			
   			switch (switches)
			{
			case 0x01:
				   break;

			case 0x02:
				   break;

			case 0x04:
					if(j < 3) {

					j++;
					led <<= 1;

					if(led == 0x04)
					led = 1;
					
					}

					break;
					
			case 0x08:
				   break;

			case 0x10: 
				   break;

			case 0x20: 
				   break;

			case 0x40: 
				   break;

			case 0x80: 
				   break;
		
			}
						 	 
		
 		} //if (switches)

		else
		{
			led <<= 1;		
			if (led == 0)		
			{
				led = 1;
			} 
		} 
		
		ovrflow = 0;

		}	// if ovrflow		
	
	} //for

}  //main




ISR(TIMER0_OVF_vect)
{
	
	switches  = ~PIND;

	ovrflow = 1;
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Go back into your code and put meaningful comments at strategic places ! HOW many leds and switches do you have, we never were told that ? What are the specs for this app ? Don't press, LEDs rotate and if a switch IS pressed, what... ?

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

And note that your code will work only if one switch at a time is pressed. If more than one is pressed, then it will fail.

Regards,
Steve A.

The Board helps those that help themselves.