Overview
In previous post I introduce about external interrupt of the ATMega644P that has only three interrupt source with software select-able. Additionally to the external interrupt the this chip has four more interrupt source that is the Pin Change Interrupt (PCINTXX). It triggers whenever there is any logic change at each pins.
The Pin change interrupt PCI3 will trigger if any enabled PCINT31:24 pin toggle, 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. PCMSK3, PCMSK2, PCMSK1 and PCMSK0 Registers control which pins contribute to the pin change interrupts. Pin change interrupts on PCINT31:0 are detected asynchronously. This implies that these interrupts can be used for waking the part also from sleep modes other than Idle mode.
![]() |
| ATMega644P 40-Pin DIP Pin Diagram |
However any logic change from high to low or even from low to high can generate interrupt. To select any logic level the programmer must mask one logic level.
The Pin Change Interrupt source are distinct from external interrupt so they are grouped in different registers. These are some essential registers relate to PCINTXX:
- PCICR – Pin Change Interrupt Control Register
- PCIFR – Pin Change Interrupt Flag Register
- PCMSK3 – Pin Change Mask Register 3
- PCMSK2 – Pin Change Mask Register 2
- PCMSK1 – Pin Change Mask Register 1
- PCMSK0 – Pin Change Mask Register 0
To use any interrupt source the programmer must enable it, write the ISR and test its interrupt flag.
![]() |
| Relevant Registers |
Pin Change Interrupt Programming in C
Using AVR-LibC in Microchip Studio the programming of this interrupt source could be done from scratch just like we state it above.
![]() |
| Schematic |
In this example the interrupt source is at PortD (PCINT31:24). That's the Pin Change Interrupt 3. Each time the logic low level is detected the ISR will toggle the LED connects to PortB. PC0 blinks a LED for every 500ms.
- /*
- * 5-PCINT_2_LED.c
- *
- * Created: 1/27/2026 10:10:26 AM
- * Author : Admin
- */
- #include <avr/io.h>
- #include <avr/interrupt.h>
- #include <util/delay.h>
- #define F_CPU 16000000UL
- volatile uint8_t mask=0;
- int main(void)
- {
- /* Replace with your application code */
- DDRB=0xFF;
- DDRC=0xFF;
- DDRD=0x00;
- PIND=0xFF;
- PCICR=0x08;
- PCMSK3=0xFF;
- sei();
- while (1)
- {
- PORTC^=0x01;
- _delay_ms(500);
- }
- }
- /*Pin Change Interrupt ISR*/
- ISR(PCINT3_vect){
- switch(PIND){
- case 0xFE: PORTB^=0x01;
- break;
- case 0xFD: PORTB^=0x02;
- break;
- case 0xFB: PORTB^=0x04;
- break;
- case 0xF7: PORTB^=0x08;
- break;
- case 0xEF: PORTB^=0x10;
- break;
- case 0xDF: PORTB^=0x20;
- break;
- case 0xBF: PORTB^=0x40;
- break;
- case 0x7F: PORTB^=0x80;
- break;
- }
- }
In Proteus VSM this program run correctly. In physical Hardware I has some switches bouncing problems.
I tested this program on my AVR Prototype Board that offered by PCBWay.com.
I have been using PCBWay for many years now. PCBWay fabricate PCBs at low cost, fast processing time for only 24 hours, and fast delivery time using any carrier options. This double side 10cmx10cm can be fabricate at only 5USD for 5 to 10pcs by PCBWay. It's a standard PCB with silk screen and solder mask.
![]() |
| 10 PCBs for only 5USD |
For different size of PCB we can instantly quote on PCBWay website using a zip PCB Gerber file without account.
![]() |
| PCBWay Instant Quote |
I tested this demo example on my AVR Prototype Board.







No comments:
Post a Comment