External Interrupt Not Reseting

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

Hi,

 

I am trying to debug my ATmega324P TQFP INT0 interrupt.  I have configured the MCU so INT0 (PD2)  is triggered on an incoming logic low event and therefore I have used a pull-up resistor.  

 

The problem I have is the INT0 I/O pin after the first event is pulled low and will not reset high.  I have confirmed this by putting a scope on the I/O pin.

 

I have included my code below, and cross referenced with the datasheet, but I do not think I have made a mistake.  Can anybody see any problem, or am I implementing my interrupt incorrectly?

 

Thanks,

 

Tuurbo46

 

#define F_CPU 8000000UL  
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <avr/interrupt.h>

 

int8_t Data;

 

ISR(INT0_vect) 
{            
    Data = 1;
}

 

int main(void)
{

DDRB = (1 << DDRB4);    // Set LED as output
PORTB = 0b00000000;     // Set LED state to zero

 

DDRD =  (0 << DDRD2);   // Set INT0 as input
PORTD = (1 << PORTD2);  // Set INT0 pull up resistor
        
EIMSK |= (1 << INT0);                              // Enable INT0                          
EICRA |= (0 << ISC01) | (0 << ISC00 );   // Trigger on logic low
sei();
     
     while(1)
     {
         if (Data)             
         {
              Data = 0;
                                            
              PORTB ^= PORTB4;  // Toggle led state
                                          
         }
     }
}

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

Tuurbo46 wrote:
The problem I have is the INT0 I/O pin after the first event is pulled low and will not reset high.

I'm very confused.  Surely you have a button or switch connected to INT0 pin, and it pulls it low?  So you have to release your button/switch for it to go high.  That could be tested without any program in the AVR... (Why not use the internal pullup?)

 

Lessee -- INT0 is PD2 on that model, right?

 

Tuurbo46 wrote:
EICRA |= (0 << ISC01) | (0 << ISC00 ); // Trigger on logic low

ORing with 0 does nothing.

 

You have chosen to use "low-level" interrupt.  You realize that this will keep triggering as long as the low condition is met.  So you will get n fast toggles of your output pin, in between servicing the cascading interrupts.  So at one mainline instruction per interrupt servicing, you will toggle about 1 out of 10 interrupt services, or maybe about every 100 cycles.

 

Tuurbo46 wrote:
int8_t Data;

Volatile -- http://www.nongnu.org/avr-libc/u...

 

Skip the low-level interrupt for now, until you understand what is going on.

When the external interrupt is
enabled and is configured as level triggered, the interrupt will trigger as long as the pin is held low.

 

If you are using a button/switch, then remember that "buttons bounce" so you are likely to get several edges each press.

 

Other than that...  ;)

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Hi theusch,

 

I have an I2C device that I am trying to read data from, and when data is ready is sends a low level interrupt.

 

INT0 is PD2 on that model, right?  Yes that is correct.

 

I have set the pull-up resistor above I think.  

 

OK I will resort back to a switch and have another go.

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

Tuurbo46 wrote:
I have an I2C device that I am trying to read data from, and when data is ready is sends a low level interrupt.

So simply use falling edge to trigger your read.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Don't forget any variable shared between main and an IRQ must be declared volatile!  i.e. "Data"

 

 

 

Jim

 

 

FF = PI > S.E.T

 

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

Hi,

 

Thanks for your tips.

 

Now I nearly have the MCU reading the external I2C interrupt device correctly.  However it misfires sometimes for no reason.  If this is noise, would an external pull-up resistor be a better solution with a 100n in parallel.  If I use an external pull-up, do I set INT0 (PD2) to 0, instead of 1 which is the internal pull-up setting?

 

Thanks,

 

Tuurbo46.

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

pull-ups (or down) are only really needed on lines that may float (that is "open circuit"). If this device is driving a TTL level 1/0 signal to say "done"/"not done" then you should be able to rely on it driving a solid 0 or 1.

 

I think it might be time to show use a schematic and some detail of what this I2C device is and how you have it wired.