0
votes

In avr Xmega device, there are only two IO port interrupt vectors INT0 and INT1.

I have three switches that should generate three interrupts. I have written an interrupt code for the first switch using INT0. Now, I can write the second interrupt using INT1 which will exhaust my vectors. Below is my code for INT0 ISR:

ISR (PORTD_INT0_vect){
PORTD.INTFLAGS = 0x01; // clear INT0IF flag.

PORTD_OUT = PORTD_OUT | (1<<4); // led on.

}

Can I redefine this ISR to enable interrupt for second switch?

The registers that I set in main function are as follows:

PORTD.INT0MASK = 0x04; // PD2 is the source of interrupt for INT0.
PORTD.INTCTRL = 0x03; // Disable INT1, enable INT0 and place it a high-priority level.
PORTD.PIN2CTRL = 0x03; // configure PD2 pin to interrupt on the low level of signal.
PMIC.CTRL = 0x07;    // enable high,medium, and low level interrupts.
sei();         // enable interrupt globally.
4
Why don't you use a single interrupt vector and test the source when interrupted?Weather Vane
If that is the case, the ISR should remember which switch I pressed. Is that possible?Pradeep Ch
@PradeepCh: Yes, ISR can remember which switch pressed, by storing state of PORTx_IN register in a variable.datenwolf

4 Answers

2
votes

The idea of the external interrupts is that you get to know that something happened, but not what happened. In your ISR you have to read out the state of the inputs the switches are connected to and determine based on the readout, what to do. To detect, if the state did alter, keep a copy of the ports input status and do an XOR with the newly read out value (do this for a whole port, not just for single pins).

0
votes

I'm not expert of XMEGA, but I can suggest, for example using PD1 as interrupt pin:

PORTD.INT0MASK = 0x04; // PD2 is the source of interrupt for INT0.
PORTD.INT1MASK = 0x02; // PD1 is the source of interrupt for INT1.
PORTD.INTCTRL = 0x0F; // Enable INT1, enable INT0 and place them a high-priority level.
PORTD.PIN2CTRL = 0x03; // configure PD2 pin to interrupt on the low level of signal.PORTD.PIN1CTRL = 0x03; // configure PD1 pin to interrupt on the low level of signal.
0
votes

Every port has 2 interrupts. You can use more ports if you need more interrupts than 2. You can connect the third switch to a second port and use the INT0 there.

0
votes

How about polling input(s) from your code, in a loop or from timer interrupt routine(s)? This way you can handle as many input signals as you have inputs capable of sensing the signal change.

The limiting factor, though is the frequency of polling and the delay the polling software introduces.

Of course I assume you want to observe high/low levels of the signal. For more elaborate signal sensing (rising, fallsing, frequency change) the use of ADC is unavoidable.

I hope this helped.