Interrupt types

Hi all,

Wasn't too sure whether or not to put this in the programming section or here, but here seems most appropriate.

Now, I've used both rising and falling edge interrupts before - but I'm currently working at the moment on a board design of my own. I'm just trying to figure out the differences between the interrupt types actually available as per the datasheet. Am I correct in saying pins marked as INT0, INT1, INTn..... are true external interrupts that can be triggered by rising, falling or change, whilst PCINT pins are interrupts that can only trigger on a change, not a rising or falling edge?

I believe that is correct.

But then again it's kind of semantics maybe, as a pin change interrupt is a result of at least one bit having had a transition, no? It's just up to further software tests to figure out which bit changed and in which direction.
Lefty

check out this - Google Code Archive - Long-term storage for Google Code Project Hosting. - its a lib to handle the pcint's AFAIK it does detect rise and fall too ..

The main difference is that the pin-change interrupts are in groups of 8 bits (that is a change in the port, eg. PINB) would trigger the interrupt. Then you have to work out which one caused it (by comparing your storing of the previous state with the current one). You can mask them out, if you only want one or two pins to cause the interrupt.

Plus, if you want rising, but not falling, to trigger then the external interrupt would be better.

Thanks for all the info - i'll have a read up now.

I didn't know about pin change being a change on the port as a whole, sounds like a drag!

Certainly sounds like external interrupts are still the way to go. I've run out of all ADC and I/O lines on a 1284P, and don't see it as feasible to add a port expander and an analog MUX or external ADC, when I could simply up to a bigger chip with more true external interrupts that keeps code simpler.

The problem is, I like the option of 16Kb SRAM on the 1284, there is no other MegaAVR by the looks of things with 16Kb - still flicking through the site at the moment - but I guess it's me being picky. Looks like I might aswell go to a 2560.

If say I did decide to go with an AVR that isn't an Arduino supported chip, how easy is it to add the chip to the list in the IDE? I'm not interested in using a bootloader, i'll be programming over ICSP anyway.

EDIT: Even if I go with the 2560, 16 ADC lines isn't really enough, so I'm still going to need either a MUX or external ADC. The only advantage would be, easier processing of pin change interrupts, as they would be normal external interrupts instead. So, I'm likely to stick with the 1284 (lots of RAM) and set an external port expander up to interrupt on change, and work out which has gone high/low as said. I'm only young, might as well take up the challenge!

However, running an external ADC and port expander, plus another 4 devices on SPI - and trying to poll them all relatively fast.... maybe asking a lot.

whilst PCINT pins are interrupts that can only trigger on a change, not a rising or falling edge?

That's not a big deal: you just need to test for the levels of the pins in the isr to determine if it is rising or falling edge.

I didn't know about pin change being a change on the port as a whole

On an avr, the pins can be individually configured to trigger a pcint. On some mcus where individual pins cannot be configured (STM8), you simply have to mask the port in the isr.

On an avr, the pins can be individually configured to trigger a pcint

So actually, a PCINT is only different from an INT in that you must work out if it's rising or falling yourself. It is indeed pin specific still?

Here's some skeletal code from my interrupts page:

ISR (PCINT0_vect)
 {
 // handle pin change interrupt for D8 to D13 here
 }  // end of PCINT0_vect

ISR (PCINT1_vect)
 {
 // handle pin change interrupt for A0 to A5 here
 }  // end of PCINT1_vect

ISR (PCINT2_vect)
 {
 // handle pin change interrupt for D0 to D7 here
 }  // end of PCINT2_vect


void setup ()
  { 
  // pin change interrupt (example for D9)
  PCMSK0 |= _BV (PCINT1);  // want pin 9
  PCIFR  |= _BV (PCIF0);   // clear any outstanding interrupts
  PCICR  |= _BV (PCIE0);   // enable pin change interrupts for D8 to D13
  }

In this particular case we only get an interrupt on pin 9. However you note there are three ISRs for all of the pins (the ranges are in the comments). You still need to work out if it is rising or falling, and if you wanted D9 and D10 you would need to work out which one had caused it. I'm not certain what would happen if, while processing (say) an interrupt for D9 a change in D10 occurred while you were in the ISR. Judging by the datasheet (page 73) if a further change occurred while processing one, it would be queued for the future. I can imagine a race condition here. Say you had D9 and D10 both triggering PC interrupts. D9 changes and you enter the ISR. D10 then changes while you are in the ISR. The ISR notices that both have changed and reacts accordingly. However the D10 interrupt is still remembered for next time, and you may enter the ISR again a moment later and find no changes. This isn't necessarily a disaster. You would just need to allow for it.