Interrupt to toggle LED

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

I have programmed a switch to Toggle the LED every time it is pressed. It is working but when I connect the power or RESET it toggles ON then OFF fast at the beginning. This appeared in simulation in Proteus and when I flashed it on Atmega32 also.

What could be the problem in my code ?

 

#include <avr/io.h>
#include <avr/interrupt.h>

ISR ( INT0_vect )
{
  PORTD ^= (1 << PD6);
}

void INT0_Init (void)
{
  DDRD &= (1 << PD2);
  MCUCR |= (1 << ISC00) | (1 << ISC01);
  GICR |= (1 << INT0);
  SREG |= (1 << 7);
}

int main ()
{
  INT0_Init();

  DDRD |= (1 << PD6);
  PORTD |= (1 << PD6);

  while (1)
  {

  }
}

 

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

You have no switch debounce. The LED may toggle any number of times as the button is pushed.

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

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

Using ext int with buttons that bounce is a very bad idea. Suggest you Google "ganssle bounce" for the complete explanation. 

 

Bottom line ; if you want to read buttons in an interrupt do it in a TIMER interrupt, not an external pin interrupt! 

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

Yes I know, But It toggles at start every time without even pressing button

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

This is somewhat a mess:

 

Why do you need a separate init code routine?---there is barely anything in your main anyhow, put it there

You don't have PD6 as part of it anyhow.

Also for initializations, use = for your registers, not &=  |=, etc...keep it simple.

 

What size pullup resistor are you using for your switch??

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

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

10 kohm

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

Looking at Table 13-2. Interrupt 0 Sense Control:
 

You have set INT0 for The rising edge of INT0 generates an interrupt request.

Surely you want The falling edge of INT0 generates an interrupt request.

 

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

Well if it does it in proteus, then why not use the debug facilities there and single step your program and watch what (and why) it flashes upon power up?

After all, that is what a simulator is for!

 

Jim

 

 

FF = PI > S.E.T

 

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

If you want to clear DDRD2, use

void INT0_Init (void)
{
  DDRD &= ~(1 << PD2);

 

I, also, suspect that this is a bouncing push-switch.   You can add a simple capacitor to the push switch like this:

 

Try rewriting the code so that the LED goes on when the switch is pressed and off when the switch is released.  Try changing the MCUCR from inside the Ext Interrupt IRQ.  Try lots of things and keep a log of the results.

 

Last Edited: Mon. Jan 3, 2022 - 02:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think after debugging on proteus that the problem is that the connection of LED used is a ( Negative LOGIC ) so as the ports are 0 by default the current passes through the LED until the port is set to be 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
  DDRD |= (1 << PD6);
  PORTD |= (1 << PD6);

This would result in one very very brief flash, so short your eye would hardly see it.

 

So perform an experiment. Simply swap the order of those lines, re-compile and re-run the code. Observe any flash or lack of flash.