Enable Interrupt

On Arduino Mega :

to enable group interrupts on PORTB PCINT[7:0] and then to enable interrupt PCINT0 (pin 53) use the following two commands :

PCICR |= (1<<PCIE0); 
PCMSK0 |= (1<<PCINT0);

How to enable group interrupts on PORTJ PCINT[9:15] and then to enable interrupt PCINT9 (pin 15) ???

From the ATMega2560 datasheet, accessible from the arduino.cc product page for the Arduino Meg ADK:

15.2.5
PCICR – Pin Change Interrupt Control Register
• Bit 1 – PCIE1: Pin Change Interrupt Enable 1
When the PCIE1 bit is set (one) and the I-bit in the Status Register (SREG) is set (one), pin
change interrupt 1 is enabled. Any change on any enabled PCINT15:8 pin will cause an inter-
rupt. The corresponding interrupt of Pin Change Interrupt Request is executed from the PCI1
Interrupt Vector. PCINT15:8 pins are enabled individually by the PCMSK1 Register.

That suggests that the way to enable PCINT[15:8] is to set PCIE1 in register PCICR. Section 15.2.8 in the same document suggests that the way to enable PCINT9 is to set PCINT9 in register PCMSK1.

Note that I've never used an ATMega2560, so my suggestions are untested.

tmd3:
From the ATMega2560 datasheet, accessible from the arduino.cc product page for the Arduino Meg ADK:

15.2.5
PCICR – Pin Change Interrupt Control Register
• Bit 1 – PCIE1: Pin Change Interrupt Enable 1
When the PCIE1 bit is set (one) and the I-bit in the Status Register (SREG) is set (one), pin
change interrupt 1 is enabled. Any change on any enabled PCINT15:8 pin will cause an inter-
rupt. The corresponding interrupt of Pin Change Interrupt Request is executed from the PCI1
Interrupt Vector. PCINT15:8 pins are enabled individually by the PCMSK1 Register.

That suggests that the way to enable PCINT[15:8] is to set PCIE1 in register PCICR. Section 15.2.8 in the same document suggests that the way to enable PCINT9 is to set PCINT9 in register PCMSK1.

Note that I've never used an ATMega2560, so my suggestions are untested.

if you meant this way , it doesn't work .

PCICR |= (1<<PCIE1);
PCMSK1 |= (1<<PCINT9);

Actually , I just want to use port J for both encoder so I configured pins as follow :

I want to enable the interrupts on a Port J (PJ0 & PJ1) with the Pin Change Interrupt Control Register (PCICR) by setting the correct PCIE (pin change interrupt enable) bit in the register. Then enable Pin Change Mask Resister(PCMSK). I do this in setup but the encoder doesn't count , any help ?

PJ0 ( RXD3/PCINT9 ) -- > Digital pin 15 (RX3)
PJ1 ( TXD3/PCINT10 ) -- > Digital pin 14 (TX3)

#define encoder2PinA 15 
#define encoder2PinB 14 


volatile long encoder2Value;


long lastEncoder2Value = 0;

void setup() { 

  Serial.begin (115200);
  Serial.println("Half of Quadrature Counts");
  pinMode(encoder2PinA, INPUT_PULLUP); 
  pinMode(encoder2PinB, INPUT_PULLUP);


PCICR |= (1<<PCIE1);
PCMSK1 |= (1<<PCINT9);



}

void loop() {


  if(encoder2Value != lastEncoder2Value){
    Serial.print("Count:  ");
    Serial.println(encoder2Value);

    lastEncoder2Value=encoder2Value;
  }
  


}


ISR (PCINT9_vect)
{ 
if( bitRead(PINJ,0)== bitRead(PINJ,1)) 
{
encoder2Value++;
} 
else 
{
encoder2Value--;
} 
}

Maria88:
if you meant this way , it doesn't work .

PCICR |= (1<<PCIE1);

PCMSK1 |= (1<<PCINT9);

Have you read the Atmega2560 datasheet carefully? (How many times - I find that things become clearer after the 10th time).

Also (and this is just a personal weakness) I prefer to ste the bits in a register like this

REG |= 0b00010010; // to set the bits that have 1 in them and
REG &= 0b11101101; // to clear the bits that have 0 in them

so that I have a visual representation of the bits that I can relate to the datasheet.

...R

PCICR |= (1<<PCIE1);
PCMSK1 |= (1<<PCINT9);
ISR (PCINT9_vect)

I'm not sure about the Mega, but I think that if you are enabling interrupts on PCIE1, then the ISR should be PCINT1_vect

Quite right. You have to get the ISR name right or it will silently fail.

/* Pin Change Interrupt Request 0 */
#define PCINT0_vect			_VECTOR(9)
#define SIG_PIN_CHANGE0			_VECTOR(9)

/* Pin Change Interrupt Request 1 */
#define PCINT1_vect			_VECTOR(10)
#define SIG_PIN_CHANGE1			_VECTOR(10)

#if defined(__ATmegaxx0__)
/* Pin Change Interrupt Request 2 */
#define PCINT2_vect			_VECTOR(11)
#define SIG_PIN_CHANGE2			_VECTOR(11)

You can tell it is interrupt 1 (and not 9) because you are fiddling with the PCMSK1 register. Each register handles 8 bits, so PCINT0_vect handles the first 8, PCINT1_vect the second 8, and so on.

Maria88:
if you meant this way , it doesn't work .

PCICR |= (1<<PCIE1);

PCMSK1 |= (1<<PCINT9);

I think it does work. I think that this doesn't work:

ISR (PCINT9_vect)

From the ATMega2560 datasheet, Section 15:

The Pin change interrupt PCI2 will trigger if any enabled PCINT23:16 pin toggles, Pin change interrupt PCI1 if any enabled PCINT15:8 toggles and Pin change interrupts PCI0 will trigger if any enabled PCINT7:0 pin toggles.

(Emphasis mine.) There's no PCINT9 interrupt. The interrupt is PCINT1, and it triggers when any pin on PORTJ. whose pin change interrupt has been enabled, changes. The interrupt fires when any enabled pin changes. If more than one are enabled, your code has to figure out which one changed. I don't see that there's a flag register associated with individual pins, so I presume that the code has to remember the last state of the pins, and compare it to the current state, to learn which pin changed. I hope there's a better way, and that our friends on this forum will describe it.

As Nick says, IDE 1.0.5 silently discards an ISR whose name doesn't exactly match its list of interrupts. If you turn on verbose output during compilation, you'll see a warning that something "appears to be a misspelled signal handler." As I understand it, the correct names are the names found in table 14.1 of the datasheet, with underscore characters substituted for spaces, and with the characters "_vect" attached at the end.

Why not use the macros provided in pins_arduino.h:

void enablePCINT (byte pin)
{
  * digitalPinToPCICR(pin) |= digitalPinToPCICRbit(pin) ;
  * digitalPinToPCMSK(pin) |= digitalPinToPCMSKbit(pin) ;
}

void disablePCINT (byte pin)
{
  * digitalPinToPCMSK(pin) &= ~digitalPinToPCMSKbit(pin) ;
  if (* digitalPinToPCMSK(pin) == 0)
    * digitalPinToPCICR(pin) &= ~digitalPinToPCICRbit(pin) ;
}