Mohamed Emad
Mohamed Emad

Reputation: 21

AVR Microcontroller Interrupt

I have ATmega32 AVR and I want to have more Interrupt pins than (INT 0, INT 1, INT 2) so Can I convert any pins in ATmega32 to an interrupt or there is another method to have more interrupts in the micro controller? Or should I get another AVR microcontroller?

Upvotes: 2

Views: 376

Answers (3)

Spektre
Spektre

Reputation: 51845

You can "Wire-OR" your interrupt sources to single signal and then just read the pins value in ISR ...

Beware if your interrupt sources are not open drain then you need also add diodes to prevent short-circuit between the wire-ored interrupt sources.

so you have 3 INT pins so just group all your sources that will share the same ISR together (WIRE OR) and connect each group to one of the INT pins... and also connect each source individualy to some GPIO so you can read which pin triggered the ISR from within the ISR.

I do not use ATmega32 but on ATmega328P there are also PCINT pins (pin change) which can also trigger ISR like INT0/1 and they are on all pins (PC,PB,PD) of the MCU just they are not configurable (they react only on any level change and are grouped to 3 ISRs one for each port) so I expect ATMega32 have similar stuff on it (too lazy to check datasheet)

Upvotes: 0

dunajski
dunajski

Reputation: 389

INT0/INT1/INT2 and pins assigned to them in Atmega32 have special features, for example to wake up MCU from energy saving modes. If you need another interrupt with special feature but on diffrent pin then it is not possible, but... if you want to check input pin state and then execute some actions there is workaround that I used a few times.

So, how external interrupts works?

(Simplified, pseudo-description) There is a special hardware controller inside your MCU that detect rise-up/down, change of chosen pins and when certain condition is met, it reports to interrupt controller what happened, then if mask bit of this interrupt is set to enabled your MCU invokes interrupt vector (ISR).

So, how to workaround this?

Short explaination:

  1. Use one of interrupts given by timer unit and set "faster" than signal on input can change.
  2. Probe input states in timer ISR.
  3. Whenever condition is met, for example high-state on pin for about 5 ms, you can save that fact in variable value.
  4. Make callback to execute action or just make action inside your ISR, that depends about execution time of this action, ISRs should be short in execution time.

Pseudocode below (typed without compiling, just here in answer textbox):

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

volatile int sth_happened = 0;

void ExecuteCallback(void)
{
    // your action goes here
    // reset sth_happened by assgining to 0
}

ISR(TIMER0_COMP_vect) // this ISR should be executed faster than signal on chosen pin can change
{
    // check PIN of your pin here

    // if state/signal on your pin met requirements,
    // save it to variable or execute another code
    // sth_happened = 1 / ExecuteCallback();
}

int main(void)
{
    // Prepare your ISR timer here
    // I would recommend to use CTC mode with desired execution time
    sei(); // enable interrupts
    
    while(1)
    {
        if (sth_happened) ExecuteCallback();
    }
    return 0;
}

Upvotes: 1

David Grayson
David Grayson

Reputation: 87406

You might consider just making the main loop in your program run faster so you can read those pins in your program and react when they change.

If you really need actual interrupts, you might consider switching to a newer AVR like the ATmega328P, where every I/O line can be used as a pin-change interrupt (PCINT) pin.

Upvotes: 0

Related Questions