Hi everyone,

This post is about using pin change interrupts and I will give a basic example to learn this topic very well. Before starting, we need to recover some terms such as interrupt, ISR and more.
Interrupt is an asynchronous signal to the processor and it indicates an event which needs immediate attention. When an interrupt is received, the processor completes the on-going instruction and redirect the interrupt request. This redirection procedure is called as ISR (Interrupt Service Routine).

Interrupt can be categorized as software based interrupts and hardware based interrupts. In software based interrupts, a special instruction or an exceptional situation might cause this type of interrupts. On the other hand, a signal is sent to the processor from an external unit in hardware based interrupts.

What if we do not use interrupt for detecting pin changes? Are there any alternatives to detect pin changes? Of course, there always exist a way which is called polling technique. Let’s look close the polling technique and its advantages and disadvantages due to using interrupt.
In the polling technique, the processor checks the event continuously. Because of this continuous checking, the processor does not do anything until event occurs. The main disadvantages of polling technique due to the interrupts are; timing accuracy, power consumption, wasting processor time.

In the previous lecture, I mentioned about ATmega328P pins. When you use pin change interrupt, you need to know PCINT value for enabling pin change interrupt for that specific pin.


Figure 1: Pinout Diagram for 28-pin PDIP[1]

For Arduino UNO users, it seems confusing because there is no information which pin is port-B on Arduino UNO.


Figure 2: Arduino UNO Pinout Diagram [2]

PCICR (Pin Change Interrupt Control Register) controls the pin change interrupt.


Figure 3: PCICR Register [3]


PCMSKn (Pin Change Mask Register) selects which pin change interrupt property is enabled. There are 3 type o PCMSKn and these are PCMSK2, PCMSK1, PCMSK0.

PCMSK2 Register:


PCMSK1 Register:


PCMSK0 Register:


There are 3 steps to use pin change interrupts.
  • Turn on pin change interrupt
  • Decide which pins to interrupt is enabled
  • Write an ISR for those interrupts.


Figure 8: Circuit Schematic of Lecture 2


#include <avr/io.h>
#include <avr/interrupt.h>
int main(void)
    DDRB |= 0xFF; // Set all PORT-B pins as output.
    PCICR |= 0b00000100; // Enable pin change interrupt on PORT-D
    PCMSK2 |= 0b00000001; // PIND0 pin change interrupt is enabled
    return 0;
ISR(PCINT2_vect) {
    PORTB ^= 0xFF;


Figure 9: Oscilloscope Result

The yellow line represents the PD0 pin and blue one represents the one of the LEDs. When the PD0 pin change the ISR will run and toggle the all port-B pins that are connected to the LEDs.



[1] ATmega328P Datasheet
[2] Website
[3] ATmega328P Datasheet
[4] ATmega328P Datasheet