Pic12F1572'de IOC ve EXTI kullanımı

Başlatan Mucit23, 06 Aralık 2023, 15:25:17

Mucit23

Selamlar

Birkaç gündür Pic12LF1572 kullanarak bir uygulama yapmaya çalışıyorum. Uuzun zamandır da pic kullanarak bir uygulama yapmıyorum baya geride kalmışım.

Yapmak istediğim sistemde 2 adet Giriş var. Bir tanesi RA2(EXT INT) diğeri ise RA3(MCLR). Bu pinlerdeki değişimlerde kesme oluşturmam lazım. RA2 yükselen kenar oluştuğunda kesme oluşması lazım. Aynı zamanda RA3 düşen kenar oluştuğunda kesme oluşması lazım.

RA2 yani EXT_INT donanımını çalıştırdım bunda sorun yok. Fakat IOC'yi çalıştıramadım. Sanki RA2 deki değişim de kesme oluşturuyor. Bunun dışında RA3 deki değişim kesme oluşturmuyor.

Ayarlarım bu şekilde

    /*Oscillator Settings*/
    OSCCON=0b01011000;  //1Mhz
    while (!OSCSTATbits.HFIOFL); //HFI OSC Locked %2 Accurate
    while (!OSCSTATbits.HFIOFR); //HFI OSC Ready
    
    /*GPIO Settings*/
    ANSELA=0x00;       //Disable Analog Inuts
    TRISA=0b00001100;  //RA2 and RA3 Input
    PORTA=0x00;        //Clear the PortA
    OPTION_REGbits.nWPUEN=0; //Enable WPU Resistors   
    WPUAbits.WPUA2=0;  //Disable RA2 Pull-up Resistors
    WPUAbits.WPUA3=1;  //Enable RA3 Pull-up Resistors
    
    /*Interrupt Settings*/
    OPTION_REGbits.INTEDG=1; //Interrupt on rising edge of INT pin
    INTCONbits.INTE=1;       //Enable RA2 EXTI interrupt
    INTCONbits.PEIE=1;       //Enable all active peripheral interrupts
    INTCONbits.IOCIE=1;      //Enable IOC intterrupt
    INTCONbits.INTF=0;       //Clear EXTI Interrupt Flag
    INTCONbits.IOCIF=0;      //Clear IOC Interrupt Flag
    IOCAP=0x00;              //Disable the all Rissing Edge detectors
    IOCAN=0x08;              //Enable the RA3 Falling Edge detector  
    IOCAF=0x00;              //Clear all the Edge detector Flags
    INTCONbits.GIE=1;        //Enable Global Interrupt 

Kesme Fonksiyonum ise aşağıdaki gibi.

void __interrupt() ext_int(void)
{
    if(INTCONbits.INTF)//RA2 External interrupt occured 
    {
        LATA4 = ~LATA4; //RA4 Toggle
        INTCONbits.INTF=0; 
    }
    
    if(INTCONbits.IOCIF) //IOC interrupt Flag
    {
        LATA5 = ~LATA5; //RA5 Toggle
        IOCAF=0x00; //Clear the IOC flag
        INTCONbits.IOCIF=0;
    }
}

Bu durumda RA2 deki değişim IOCF flağını tetikliyor ve kesme oluşturuyor ama böyle olmaması lazım. Datasheet Sayfa 119 Da böyle açıklanmış ama çıkamadım işin içinden



Nerde hata yapıyorum çözemedim. Yardım edebilecek birileri var mı?

Mucit23

Evet şuan hallettim. Çok ufak bir hata yapmışım. IOCN registerini başka bir pin için ayarlamışım. Sadece Bayrak silme işini tam anlayamadım. Ben Kenar dedektörlerinden sadece RA3 için kullandığım için IOCF registerinin tamamını siliyorum. IOC donanımının güzel tarafı her pin için ayrı ayrı düşen kenar veya yükselen kenar dedektörleri var. Bunları ayrı ayrı aktif edip pasif edebiliyorsunuz.

Aslında bu MCU'yu baya sevdim. Çok küçük çok yetenekli LF serisi özellikle çok çok az enerji tüketiyor. Bende bu özelliğinden dolayı bu MCU'yu kullanıyorum. İki Adet AA pil ile 3-4 ay çalışabiliyor. IOC ile birde uykudan uyandırırsam tamamdır. :D

JOKERAS

İnterrupta nedense hep bayrak hatası yapılır.

IOCAFbits.IOCAF3 gibi Direkt olarak Registere eriş.
Çünkü tüm flaglar tek bir Register üzerinde.