AVR INT & PCINT

#include <avr/io.h>
#include <stdint.h>            // has to be added to use uint8_t

#include <avr/interrupt.h>    // Needed to use interrupts    

volatile uint8_t portbhistory = 0xFF;     // default is high because the pull-up

int main(void)
{
	//---- INT0
    DDRD &= ~(1 << DDD2);     // Clear the PD2 pin
    // PD2 (PCINT0 pin) is now an input

    PORTD |= (1 << PORTD2);    // turn On the Pull-up
    // PD2 is now an input with pull-up enabled

    EICRA |= (1 << ISC00);    // set INT0 to trigger on ANY logic change
    EIMSK |= (1 << INT0);     // Turns on INT0

	//---- PCINT
    DDRB &= ~((1 << DDB0) | (1 << DDB1) | (1 << DDB2)); // Clear the PB0, PB1, PB2 pin
    PORTB |= ((1 << PORTB0) | (1 << PORTB1) | (1 << PORTB2)); // turn On the Pull-up
    // PB0,PB1,PB2 (PCINT0, PCINT1, PCINT2 pin) are now inputs with pull-up enabled
    
    PCICR |= (1 << PCIE0);     // set PCIE0 to enable PCMSK0 scan
    PCMSK0 |= (1 << PCINT0);   // set PCINT0 to trigger an interrupt on state change 

    sei();                     // turn on interrupts

    while(1)
    {
        /*main program loop here */
    }
}

ISR (INT0_vect)
{
    /* interrupt 0 code here */
}

ISR (PCINT0_vect)
{
    uint8_t changedbits;

    changedbits = PINB ^ portbhistory;
    portbhistory = PINB;
    
    if(changedbits & (1 << PINB0))
    {
        /* PCINT0 changed code here */
    }
    
    if(changedbits & (1 << PINB1))
    {
        /* PCINT1 changed code here */
    }

    if(changedbits & (1 << PINB2))
    {
        /* PCINT2 changed code here */
    }

}