ATMEL PROGRAMLAMA 18 - Pin Change Interrupts (PCINT23....0)


    Pin change interrupts (pin durum değişim kesmesi ) ilgili pinlerdeki (PCINT23....0) lojik seviyenin değişmesi sonucu oluşan kesmedir. Üç gruba ayırabiliriz.
  
         1- PCI0    :  PCINT[7:0] pinlerindeki değişimi algılar
         2- PCI1    :  PCINT[14:8] pinlerindeki değişimi algılar
         3- PCI2    :  PCINT[23:16] pinlerindeki değişimi algılar


   
     PCICR  Pin Change Interrupt Control Register



 

   PCIE0 -  Pin Change Interrupt Enable 0 : 1 olduğu zaman PCINT[7:0] pinlerindeki değişimi
                                                                             algılar ve pin change İnterrupt 0 aktif  olur.

   PCIE1 - Pin Change Interrupt Enable 1  : 1 olduğu zaman PCINT[14:8] pinlerindeki değişimi
                                                                            algılar ve pin change İnterrupt 1 aktif  olur.

   PCIE2 - Pin Change Interrupt Enable 2  : 1 olduğu zaman PCINT[23:16] pinlerindeki değişimi
                                                                           algılar ve pin change İnterrupt 2 aktif  olur.

  
  PCIFR  Pin Change Interrupt Flag Register 

 




     PCIF0 - Pin Change Interrupt Flag 0 :  PCINT[7:0] pinlerinde bir değişim algılandığında
                                                                        PCIF0 1 olur. ISR yürütüldüğü zaman 0 (sıfır)'lanır.      
                                                                        Yazılımla sıfırlanması için 1 yapılması gerekir

    PCIF1 - Pin Change Interrupt Flag 1 :  PCINT[14:8] pinlerinde bir değişim algılandığında
                                                                        PCIF1 1 olur. ISR yürütüldüğü zaman 0 (sıfır)'lanır.      
                                                                        Yazılımla sıfırlanması için 1 yapılması gerekir

    PCIF2 - Pin Change Interrupt Flag 2 :  PCINT[23:16] pinlerinde bir değişim algılandığında
                                                                        PCIF2 1 olur. ISR yürütüldüğü zaman 0 (sıfır)'lanır.      
                                                                        Yazılımla sıfırlanması için 1 yapılması gerekir




   PCMSK0 - Pin Change Mask Register 0



 
  
  PCINT[7:0]  Pin Change Enable Mask 7...0 :   konum değiştiğinde kesme oluşması istenen 
                                                                                  opinler 1, istenmeyen pinler 0 yapılır.
  



  PCMSK1 - Pin Change Mask Register 1


 


 PCINT[14:8] Pin Change Enable Mask 14...8 :   konum değiştiğinde kesme oluşması
                                                                                  istenen opinler 1, istenmeyen pinler 0 yapılır.



  PCMSK2 - Pin Change Mask Register 2


 


  PCINT[23:16] Pin Change Enable Mask 23...16 :   konum değiştiğinde kesme oluşması
                                                                                       istenen opinler 1, istenmeyen pinler 0 yapılır.



  Örneğin :PCINT18 pinindeki (PD2)durum dğişikliğine göre kesme oluşturalım . Kesme oluşunca  
                  PB0 pinindeki Ledi yakalım.

Devre şemamız aşağıdaki gibi olacak. PD2 pininin dahili pull-up'ı aktif yapılarak pin normalde Lojik 1 seviyesinde tutulur. Butona basınca pinin lojik seviyesi değişir. Bu değişim kesme olarak algılanacak ve PB0 pinindeki led durum değiştirecek (yanıyorsa sönecek, sönüyorsa yanacak)
 




programda öncelikle hangi kesme kullanılacaksa o aktif edilmeli. Burada PCINT18 pini kullanılacağı için  PCI2 kesmesi kullanılacak. 

 PCI2 kesmesini aktif etmek için  PCICR registerı içindeki PCIE2 (2.bit) 1 yapılır.

 PCI2 içinde PCIN18'i aktif etmek için ise PCMSK2 registerındaki PCINT18 biti 1 yapılmalıdır.

Bu şekilde kesme ayarlanır. bu kesmenin kullanılabilmesi için SREG registerındaki Global Interrupt enable (I) bitinin 1 yapılması gerekir. bu da sei(); ile yapılır.

Anlattıklarımızı programımız geçirirsek 
 

#include <avr/io.h>
#define F_CPU 8000000ul
#include <util/delay.h>
#include <avr/interrupt.h>

#define led PORTB0
#define buton PORTD2

ISR(PCINT2_vect)
{  
    PORTB^=(1<<led);   
}

int main(void)
{
    PORTB=0x00;
    DDRB |=(1<<led);                         // led pini çıkış
    DDRD &=~(1<<buton);               // buton pini giriş
    PORTD |=(1<<buton);                 // buton pini pull up aktif
     
    PCICR|=(1<<PCIE2);                 //
PCI2 kesmesini aktif     
    PCMSK2 |=(1<<PCINT18);       // PCINT18 pini seçiliyor

     sei();                                              // Global İnterrupt enable=1
   
    for(;;); 
   
}
























Yorumlar