Picproje Elektronik Sitesi

DERLEYİCİLER => Microchip MPLAB C serisi => Konuyu başlatan: smail - 27 Ocak 2014, 21:33:23

Başlık: interrupt işlemiyor
Gönderen: smail - 27 Ocak 2014, 21:33:23
merhaba arkadaşlar,

her türlü yöntemi denedim ama olmadı. interrupt işlemiyor. rb4 pinine bağlı butona basılınca interrupt ın devreye girip motorlarımın durmasını , butondan çekince ise tekrar motorlarımın dönebilmesini istiyorum. her yöntemi denedim diyebilirim. lütfen yardımcı olun..

#include <p18f452.h>
#include <pwm.h>
#include <stdlib.h>
#include <usart.h>
#include <timers.h>
#include <delays.h>
#include <stdio.h>
#include <adc.h>
#include <portb.h>

#pragma config OSC = XT, PWRT = ON, WDT = OFF, LVP = OFF, DEBUG = OFF
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF, CPB = OFF, CPD = OFF
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF, WRTB = OFF,WRTC = OFF, WRTD = OFF
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF, EBTRB = OFF

void motor (int);
void int_handler(void);
int x;
#pragma code high_vector=0x08
void high_interrupts (void) {
    _asm GOTO int_handler _endasm
}

#pragma code low_vector=0x18
void low_interrupts (void) {
    _asm GOTO int_handler _endasm
}

#pragma code
#pragma interrupt int_handler
void int_handler(void) {
   
   if(PORTBbits.RB4 == 0)     // PORTB Change Interrupt
   {
   
    PORTDbits.RD0 = 1;
    PORTDbits.RD1 = 1;
    PORTDbits.RD2 = 1;
    PORTDbits.RD3 = 1;
    INTCONbits.RBIF = 0;
     
   }
   if(PORTBbits.RB4 != 0)
   {
    motor(x);     
   }

   }

#pragma code

void main(void){
    TRISB = 0xff;
    PORTB = 0;
    TRISC=0x80;
    PORTC=0;
    TRISD=0;
    PORTD=0;   
    ADCON1 = 0x0F; // All channels Digital
       
     //Enables all interrupts & the RB port change interrupt
    INTCONbits.GIE  = 1;        // Interrupts generell erlauben
    INTCONbits.RBIF = 0;        // Interrupt on Change Flag aus
    INTCONbits.RBIE = 1;        // Interrupt on Change an den PINs
       

 
    OpenRB0INT(PORTB_CHANGE_INT_ON & FALLING_EDGE_INT);
   
    OpenUSART(USART_TX_INT_OFF &  // usart konfigürasyon ayarlarý
  USART_RX_INT_ON &
  USART_ASYNCH_MODE &
  USART_EIGHT_BIT &
  USART_CONT_RX &
  USART_BRGH_HIGH,207);
    OpenTimer2 ( TIMER_INT_OFF & T2_PS_1_4 & T2_POST_1_1 ); 
    OpenPWM1(249); // Period
    OpenPWM2(249);   
    SetDCPWM1(0);
SetDCPWM2(0);
   
    INTCONbits.GIE = 1;
    RCONbits.IPEN = 0;          // priority       // enable interrupt
    INTCONbits.RBIE = 1;

    if((BusyUSART()));
   
while(1)
    {       
            x=ReadUSART(); 
            while (!DataRdyUSART());
            motor(x);
    }
}

void motor (int x)
{
           
            if(x=='S')
            {
             SetDCPWM1(0);
             SetDCPWM2(0);
             PORTDbits.RD0 = 0;
             PORTDbits.RD1 = 0;
             PORTDbits.RD2 = 0;
             PORTDbits.RD3 = 0;
             PORTDbits.RD6 = 1;
             PORTDbits.RD7 = 0;     
            }
         
            if(x=='F')
            {
             SetDCPWM1(498);
             SetDCPWM2(498);
             PORTDbits.RD0 = 0;
             PORTDbits.RD1 = 1;
             PORTDbits.RD2 = 0;
             PORTDbits.RD3 = 1;                       
             PORTDbits.RD6 = 1;
             PORTDbits.RD7 = 0;                           
             }
                     
         
            if(x=='V')
            {
             SetDCPWM1(498);     
             SetDCPWM2(498);
             PORTDbits.RD0 = 1;
             PORTDbits.RD1 = 0;
             PORTDbits.RD2 = 1;
             PORTDbits.RD3 = 0;
             PORTDbits.RD6 = 1;
             PORTDbits.RD7 = 0;                               
             }

            if(x=='R')
            {

             SetDCPWM1(124);          
             SetDCPWM2(498);
             PORTDbits.RD0 = 0;
             PORTDbits.RD1 = 1;
             PORTDbits.RD2 = 0;
             PORTDbits.RD3 = 1;                       
             PORTDbits.RD6 = 1;
             PORTDbits.RD7 = 0;                 
             }
                     
         
            if(x=='L' )
            {
             SetDCPWM1(498);          
             SetDCPWM2(124);
             PORTDbits.RD0 = 0;
             PORTDbits.RD1 = 1;
             PORTDbits.RD2 = 0;
             PORTDbits.RD3 = 1;
             PORTDbits.RD6 = 1;
             PORTDbits.RD7 = 0;                 
            }
           
           
}


(http://s22.postimg.cc/84u303c1p/scheme.jpg) (http://postimg.cc/image/84u303c1p/)
Başlık: Ynt: interrupt işlemiyor
Gönderen: Tagli - 27 Ocak 2014, 22:37:47
Kodu detaylı incelemedim ama ilk bakışta göze çarpan birkaç hata, daha doğrusu usulsüz yazım var.

Öncelikle, çıkış amacıyla PORT'lara erişirken PORT değil LAT register'larını kullanmalısın. Özellikle PORT register'ları üzerinden bitlere yapılan arka arkaya erişim tehlikeli. Komutların kendilerinden önceki komutları geçersiz kılma ihtimali var. Senin kodunda arka arkaya gelen PORTDbits.RD0 = 1; PORTDbits.RD1 = 1; gibi satırlardan bahsediyorum. Bu işlemleri LATDbits üzerinden yap. Tabi bu dediğim sadece yazmalar için. Bacakları okumak gerektiğinde yine PORTD kullanılacak.

Kesme kodu içinde her kesme türü için ayrı bir if bloğu açıp, if (bayrak == 1 && izin == 1) şeklinde kontrol etmek usuldendir. Buna uymazsan, tespit etmesi güç hatalarla karşılaşabilirsin.

OpenRB0INT(PORTB_CHANGE_INT_ON & FALLING_EDGE_INT); Aklımda çok net kalmamış olabilir ama bu satır bana yanlış gözüktü. Buradaki iki ayrı ayar, sanki iki farklı kesme türü için gibi. PORTB kesmesi hem düşen hem yükselen kenarda çalışır, yani sadece düşen kenarda çalışsın diyemezsin. İkinci ayar seçeneği sanki diğer kesme için gibi duruyor (PIC16'larda RB0 kesmesi olarak bilinen kesme, PIC18'lerde EXT0 veya INT0 gibi bir ismi vardı ve galiba 2 veya 3 adet vardı bunlardan, pek hatırlamıyorum şimdi). PORTB değişim kesmesi ile çalışırken dikkatli olmak lazım, hata yapmak kolay.

Adım adım hata ayıklama işlemi yapman gerekiyor. Öncelikle program akışının kesme kodunun içine girip girmediğine bak. Kesme olunca bir LED yakıp söndür. Ben hep öyle yaparım.

Son olarak, C18 güncelliğini yitirdi. Sana tavsiyem XC8'e geçmen. Kullanımının daha kolay olduğunu söyleyebilirim, özellikle de C18'e alışmış biri için.

Başlık: Ynt: interrupt işlemiyor
Gönderen: smail - 27 Ocak 2014, 22:55:32
hocam bir kısım değişiklikler yaptım dediğiniz bu şekilde mi oluyor ?

"Kesme kodu içinde her kesme türü için ayrı bir if bloğu açıp, if (bayrak == 1 && izin == 1) şeklinde kontrol etmek usuldendir. Buna uymazsan, tespit etmesi güç hatalarla karşılaşabilirsin." kısmını anlayamadım bir örnek verebilirmisiniz?

#pragma code
#pragma interrupt int_handler
void int_handler(void) {
   
   if(PORTBbits.RB4 == 0)     // PORTB Change Interrupt
   {
    LATDbits.LATD0 ^= 1;
    LATDbits.LATD1 ^= 1;
    LATDbits.LATD2 ^= 1;
    LATDbits.LATD3 ^= 1;
    INTCONbits.RBIF = 0;
     
   }
   if(PORTBbits.RB4 != 0)
   {
    motor(x);     
   }

   }

#pragma code

void main(void){
    TRISB = 0xff;
    PORTB = 0;
    TRISC=0x80;
    PORTC=0;
    TRISD=0;
    PORTD=0;   
    ADCON1 = 0x0F; // All channels Digital
       
     //Enables all interrupts & the RB port change interrupt
    INTCONbits.GIE  = 1;        // Interrupts generell erlauben
    INTCONbits.RBIF = 0;        // Interrupt on Change Flag aus
    INTCONbits.RBIE = 1;        // Interrupt on Change an den PINs
       

 
    OpenRB0INT(PORTB_CHANGE_INT_ON);


mesaj birleştirme:: 27 Ocak 2014, 23:33:33

hocam en son şekliyle bu şekilde yaptım fakat yine çalışmıyor . bir bakabilirmisiniz..

#include <p18f452.h>
#include <pwm.h>
#include <stdlib.h>
#include <usart.h>
#include <timers.h>
#include <delays.h>
#include <stdio.h>
#include <adc.h>
#include <portb.h>

#pragma config OSC = XT, PWRT = ON, WDT = OFF, LVP = OFF, DEBUG = OFF
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF, CPB = OFF, CPD = OFF
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF, WRTB = OFF,WRTC = OFF, WRTD = OFF
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF, EBTRB = OFF

void motor (int);
void int_handler(void);
int x;
#pragma code high_vector=0x08
void high_interrupts (void) {
    _asm GOTO int_handler _endasm
}

#pragma code low_vector=0x18
void low_interrupts (void) {
    _asm GOTO int_handler _endasm
}

#pragma code
#pragma interrupt int_handler
void int_handler(void) {
   
   if(INTCONbits.RBIF==1 && PORTBbits.RB4 == 0)     // PORTB Change Interrupt
   {
    LATDbits.LATD0 ^= 1;
    LATDbits.LATD1 ^= 1;
    LATDbits.LATD2 ^= 1;
    LATDbits.LATD3 ^= 1;
    INTCONbits.RBIF = 0; //Clear the PORTB RBIF flag
    PORTDbits.RD5=1; 
   }

   if( PORTBbits.RB4 != 0)     // PORTB Change Interrupt
   {
    motor(x);
   }
}

void EnableInterrupts (void)
{
        INTCONbits.RBIE = 1; //Ensure PORTB interrupts enabled
        INTCONbits.RBIF = 0; //Clear the PORTB interrupt flag
        INTCONbits.PEIE = 1; //Enable peripheral interrupts (don't think i really need this one
        INTCONbits.GIE = 1; //Enable all interrupts
}


void main(void){
    TRISB = 0xff;
    PORTB = 0;
    TRISC=0x80;
    PORTC=0;
    TRISD=0;
    PORTD=0x80;   
    ADCON1 = 0x0F; // All channels Digital
   
    OpenPORTB(PORTB_CHANGE_INT_ON);
   
    EnableInterrupts(); //Setup the interrupts   
   
    OpenUSART(USART_TX_INT_OFF &  // usart konfigürasyon ayarlarý
  USART_RX_INT_ON &
  USART_ASYNCH_MODE &
  USART_EIGHT_BIT &
  USART_CONT_RX &
  USART_BRGH_HIGH,207);
    OpenTimer2 ( TIMER_INT_OFF & T2_PS_1_4 & T2_POST_1_1 ); 
    OpenPWM1(249); // Period
    OpenPWM2(249);   
    SetDCPWM1(0);
SetDCPWM2(0);


    if((BusyUSART()));
   
while(1)
    {       
            x=ReadUSART(); 
            while (!DataRdyUSART());
            motor(x);
    }
}

void motor (int x)
{
           
            if(x=='S')
            {
             SetDCPWM1(0);
             SetDCPWM2(0);
             LATDbits.LATD0 ^= 0;
             LATDbits.LATD1 ^= 0;
             LATDbits.LATD2 ^= 0;
             LATDbits.LATD3 ^= 0;
             LATDbits.LATD6 ^= 1;
             LATDbits.LATD7 ^= 0;   
            }
         
            if(x=='F')
            {
             SetDCPWM1(498);
             SetDCPWM2(498);
             LATDbits.LATD0 ^= 0;
             LATDbits.LATD1 ^= 1;
             LATDbits.LATD2 ^= 0;
             LATDbits.LATD3 ^= 1;
             LATDbits.LATD6 ^= 1;
             LATDbits.LATD7 ^= 0;                       
             }
                     
         
            if(x=='V')
            {
             SetDCPWM1(498);     
             SetDCPWM2(498);
             LATDbits.LATD0 ^= 1;
             LATDbits.LATD1 ^= 0;
             LATDbits.LATD2 ^= 1;
             LATDbits.LATD3 ^= 0;
             LATDbits.LATD6 ^= 1;
             LATDbits.LATD7 ^= 0;                             
             }

            if(x=='R')
            {

             SetDCPWM1(124);          
             SetDCPWM2(498);
             LATDbits.LATD0 ^= 0;
             LATDbits.LATD1 ^= 1;
             LATDbits.LATD2 ^= 0;
             LATDbits.LATD3 ^= 1;
             LATDbits.LATD6 ^= 1;
             LATDbits.LATD7 ^= 0;                 
             }
                     
         
            if(x=='L' )
            {
             SetDCPWM1(498);          
             SetDCPWM2(124);
             LATDbits.LATD0 ^= 0;
             LATDbits.LATD1 ^= 1;
             LATDbits.LATD2 ^= 0;
             LATDbits.LATD3 ^= 1;
             LATDbits.LATD6 ^= 1;
             LATDbits.LATD7 ^= 0;               
            }
           
           
}

Başlık: Ynt: interrupt işlemiyor
Gönderen: Tagli - 28 Ocak 2014, 09:37:30
Kesme kodu girişi şu şekilde olmalıydı:
if(INTCONbits.RBIF==1 && INTCONbits.RBIE==1) Yani izin biti dediğim, sonu IE ile biten kesme açma kapama (izin) biti. Bloğun içine girdikten sonra yine istiyorsan PORT durumlarına göre istediğin kontrolü yaparsın, o ayrı.

LAT bitlerini ayarlarken neden ^= kullandın? Amacın doğrudan atama yapmak değil miydi?

Benim senin programın üzerinde uzaktan hata ayıklama yapmam pek mümkün değil. Ben sadece yol gösterebilirim, hata çok bariz olmadığı sürece tespit edemem. Dediğim gibi, ilk kontrol etmen gereken şey, istediğin şartlar oluştuğunda kodun kesme bölümüne dallanıp dallanmadığını görmen. Bunu en basit şekilde bir LED yakarak gözlemleyebilirsin.
Başlık: Ynt: interrupt işlemiyor
Gönderen: yldzelektronik - 28 Ocak 2014, 09:46:51
@smail

Pogramını kesmeye girip girmediğini (Kesme izinlerini doğru yapılandırıp yapılandırmadığını) kontrol etmeyi dener misin?Böylece sorunun nerede olduğu daha net anlaşılır.

Kesmeye girdiğinde led yaksın veya printf debug yap.
Başlık: Ynt: interrupt işlemiyor
Gönderen: Gökhan BEKEN - 28 Ocak 2014, 11:05:41
Bir tavsiyem var;
Bu tarz sorunlarda, kimse kodları alıp da proje oluşturup, simülasyon oluşturup, derleyip denemez.
Siz projeyi ve simülasyonun proje halini yükleyip, link verseydiniz, çok daha fazla kişi ilgilenecekti. Sorun çözüldüğünde de yararlananların sayısı çok olacaktı.
Başlık: Ynt: interrupt işlemiyor
Gönderen: smail - 28 Ocak 2014, 11:48:21
değerli hocalarım, aşağıdaki siteye kodlar, hex ve proteus dosyalarını yükledim. ben kendi yazdığım bir yazılımla programı kontrol ediyordum. onu göndersem birde ek olarak sanal port programı yüklemeniz gerekiyordu. bende proteusa virtual terminal ekledim. virtual terminal açıkken f tuşuna basınca ileri s tuşuna basınca durması gerekiyor. en çokda takıldığım konu rb4 pinindeki buton kapalı durumdayken motorların hiç çalışmaması gerekiyor. ben kodları mplab da derledim. ilgilendiğiniz için çok  teşekkür ederim.

http://www.dosya.tc/server23/jIhILm/interrupt.rar.html (http://www.dosya.tc/server23/jIhILm/interrupt.rar.html)
Başlık: Ynt: interrupt işlemiyor
Gönderen: selimkoc - 28 Ocak 2014, 16:29:51
http://elektrokod.wordpress.com/2013/10/12/portb-change-interrupt-portb-degisim-kesmesi/ (http://elektrokod.wordpress.com/2013/10/12/portb-change-interrupt-portb-degisim-kesmesi/)

Register bazında şematik olarak anlatım ve uygulama var. Faydalı olması ümidiyle..
Başlık: Ynt: interrupt işlemiyor
Gönderen: smail - 28 Ocak 2014, 17:06:45
selim hocamın verdiği örneğe çok benzer biçimde yaptım. şu an sonuca sanki çok yaklaştım. butona basıldığında interrupt devreye giriyor fakat buton hala basılı durumdayken basarsam yine döngüden çıkıp motorlar dönmeye devam ediyor. ben ise buton basılı durumdayken ne olursa olsun motorlar çalışmasın istiyorum.. selim hocanın kodlarına göre düzenlediğim son kodlar şu şekilde oldu:

#pragma interrupt int_handler

void int_handler(void) {
  if(INTCONbits.RBIF) // RBIF bayrağı oluşmuşsa
  {
       INTCONbits.RBIF=0; // RBIF bayrağını sil
       
       if(!PORTBbits.RB4)
       PORTD=0x20;
       else
       motor(x);       
  }
}

void main(void){

    TRISB = 0x10;
    INTCONbits.GIE=1; // bütün kesmelere izin ver
    INTCONbits.RBIE=1; // PORTB değişim kesmesine izin ver
    INTCONbits.RBIF=0; // RBIF bayrağını temizle
    PORTB = 0;
    TRISC = 0x80;
    PORTC = 0;
    TRISD = 0;
    PORTD = 0x80;
Başlık: Ynt: interrupt işlemiyor
Gönderen: yldzelektronik - 28 Ocak 2014, 17:09:05
Buton hala basılı iken basmak nasıl oluyor?

While ile yapabilirsin.

while(portdbits.rd0); gibi.

Yada bayrak ekleye de bilirsin.
Başlık: Ynt: interrupt işlemiyor
Gönderen: smail - 28 Ocak 2014, 17:14:13
yani şuan sadece butona basıldığı anda interrupt fonksiyonuna giriyor sonra elim hala butona basılı olmasına rağmen, yani hala if(!PORTBbits.RB4) olmasına rağmen, motorları hareket ettirebiliyorum. dediğiniz gibi while(!PORTBbits.RB4) şeklinde yazdım , bu seferde rb4 deki interrupt butonundan elimi çeksem dahi fonksiyon ordan geri çıkamadı. yani bu seferde program tamamen kilitlenip interrupt fonksiyonun içinde kaldı.
Başlık: Ynt: interrupt işlemiyor
Gönderen: Tagli - 28 Ocak 2014, 17:16:38
Benim de aklıma gelen çözüm bayrak oldu. Yoksa sürekli olarak kesmede kalmak gerekir ki bu saçma. Kesme ne de olsa hem düşen hem de yükselen kenarda gelecek, bu durumda hem düğmeye basılmasını hem de çekilmesini algılayacaktır. Kesmenin yapması gereken şey bayrağın terslemekten (toggle) ibaret. Ancak, ana döngünün, bayrağı tatmin edici bir sıklıkta kontrol etmesi gerekir.

Elbette düğmenin fiziksel olarak temiz bir sinyal vermeyeceği de göz önünde bulundurulmalı ve gereken önlemler alınmalı (debounce diye aratılabilir).

Düğmenin basılı olması fiziksel olarak bir güvenlik önlemi ise, bu işe PIC'i karıştırmayıp harici bir AND kapısı kullanmak daha doğru olabilir.
Başlık: Ynt: interrupt işlemiyor
Gönderen: yldzelektronik - 28 Ocak 2014, 17:19:51
Ben yazarken @Tagli yanıtlamış.O halde main içinde flag kontrolü ile de yapabilirsin.Eğer main dolu değilse interruptu kapatıp flag kontrolü yapabilirsin.
Başlık: Ynt: interrupt işlemiyor
Gönderen: smail - 28 Ocak 2014, 17:29:49
RBIF flagını kontrol ederekmi yapayım ? tam olarak ne yazmalıyım örnek kod yazabilirmisiniz? while 'ı hiç bir şekilde yutturamadım.
Başlık: Ynt: interrupt işlemiyor
Gönderen: yldzelektronik - 28 Ocak 2014, 18:29:39
Alıntı yapılan: smail - 28 Ocak 2014, 17:29:49
RBIF flagını kontrol ederekmi yapayım ?

Benim önerim bu yönde idi
Başlık: Ynt: interrupt işlemiyor
Gönderen: smail - 28 Ocak 2014, 19:05:31
hocam şimdi nasıl bir düzenleme yapıcağız kodlarda lütfen bi söyleseniz. main içine yada interrupt fonksiyonunda tam olarak nasıl bir değişiklik yapmalıyız?

if(INTCONbits.RBIF) // RBIF bayrağı oluşmuşsa
  {   
       INTCONbits.RBIF=0; // RBIF bayrağını sil 
       if(!PORTBbits.RB4)
       PORTD=0x20;
       
  }

}

void main(void){

    TRISB = 0x10;
    INTCONbits.GIE=1; // bütün kesmelere izin ver
    INTCONbits.RBIE=1; // PORTB değişim kesmesine izin ver
    INTCONbits.RBIF=0; // RBIF bayrağını temizle
    PORTB = 0;
    TRISC = 0x80;
    PORTC = 0;
    TRISD = 0;
    PORTD = 0x80;


     
    OpenUSART(USART_TX_INT_OFF &   
  USART_RX_INT_OFF &
  USART_ASYNCH_MODE &
  USART_EIGHT_BIT &
  USART_CONT_RX &
  USART_BRGH_HIGH,207);

    OpenTimer2 ( TIMER_INT_OFF & T2_PS_1_4 & T2_POST_1_1 ); 

    OpenPWM1(249); // Period
    OpenPWM2(249); 

    SetDCPWM1(0);
SetDCPWM2(0);


     
    if((BusyUSART()));
Başlık: Ynt: interrupt işlemiyor
Gönderen: selimkoc - 28 Ocak 2014, 21:19:09
Kesme bayrağını;

INTCONbits.RBIF=0; // RBIF bayrağını sil 

işin bittiğinde temizle. Butona bastığında us ler süresinde işlemi yapıp arktan dolayı tekrar kesme algılayabilir. İşlerini yap ondan sonra bu bayrağı temizle. İlla kesme içinde temizlenecek diye bir durum yok.

kesme içinde;

if(!PORTB.B4)  <motor döndür>

if(PORTB.B4) <motor durdur>

diyebilirsin. Çünkü her kenar değişiminde kesme algılar.
Başlık: Ynt: interrupt işlemiyor
Gönderen: smail - 28 Ocak 2014, 22:49:58
selim hocam dediğiniz gibi RBIF flagının yeri ile ilgili problem var. "INTCONbits.RBIF=0; " kodunu herhangi bir yere koyarsam program direk kilitlenip döngüye dahi girmiyor. ama aşağıdaki gibi "if(PORTBbits.RB4)  den sonra INTCONbits.RBIF=0;" yazarsam program buton basılıncaya kadar çalışıyor. basılınca interrupt devreye giriyor. fakat burdada butondan çekildikten sonra interruptan çıkamayıp program kilitleniyor.

void int_handler(void) {

  if(INTCONbits.RBIF) // RBIF bayragi olusmussa
  {   
       
       if(!PORTBbits.RB4)
       PORTD=0x20;
       if(PORTBbits.RB4)
       {
       INTCONbits.RBIF=0; // RBIF bayragini sil
       motor(x);     
       }     
  }

}

void main(void){
    TRISB = 0x10;
    INTCONbits.GIE=1; // bütün kesmelere izin ver
    INTCONbits.RBIE=1; // PORTB degisim kesmesine izin ver

    PORTB = 0;
    TRISC = 0x80;
    PORTC = 0;
    TRISD = 0;
    PORTD = 0x80;
Başlık: Ynt: interrupt işlemiyor
Gönderen: Tagli - 28 Ocak 2014, 22:54:48
Bayrak sıfırlamanın yeri yanlış. Bir blok dışarıda olmalı. Mevcut durumda, RB4 sıfır ise, kesme bayrağı sıfırlanmıyor.
Başlık: Ynt: interrupt işlemiyor
Gönderen: smail - 28 Ocak 2014, 23:05:34
Hocam bir blok dışarı derken ne kastettiğinizi anlayamadım. ama ben şöyle 3 farklı durum denedim :

1. durum : bu durumda kesmeye girildiğini led den  anlıyorum fakat buton basılı durumda olsa bile hala motorlar devam edebiliyor.
void int_handler(void) {

  if(INTCONbits.RBIF) // RBIF bayragi olusmussa
  {   
       
       if(!PORTBbits.RB4){
       PORTD=0x20;
       }

       if(PORTBbits.RB4)
       {

       motor(x);     
       }     
  }
       INTCONbits.RBIF=0;
}


2. durum: bu durumda çok acaip saçma şeyler yapıyor ..

void int_handler(void) {

  if(INTCONbits.RBIF) // RBIF bayragi olusmussa
  {   
       
       if(!PORTBbits.RB4){
       PORTD=0x20;
       INTCONbits.RBIF=0;
       }

       if(PORTBbits.RB4)
       {

       motor(x);     
       }     
  }

}


3. durum: 1. durumla aynı sonuç çıkıyor..

void int_handler(void) {

  if(INTCONbits.RBIF) // RBIF bayragi olusmussa
  {   
       
       if(!PORTBbits.RB4){
       PORTD=0x20;

       }

       if(PORTBbits.RB4)
       {

       motor(x);     
       }     
       INTCONbits.RBIF=0;
  }

}
Başlık: Ynt: interrupt işlemiyor
Gönderen: selimkoc - 28 Ocak 2014, 23:40:54
if bloğu içine 200ms kadar bekleme koysan (buton arkı için),

birde butona paralel 100nf kond. eklesen duruma baksan.
Başlık: Ynt: interrupt işlemiyor
Gönderen: Tagli - 28 Ocak 2014, 23:56:28
Benim dediğim 3. durum idi.

Bu arada, PORTD=0x20; yerine LATD=0x20; yazmayı alışkanlık haline getir. Bu dediğim sadece çıkışlar için. Girişler yine PORT üzerinden okunacak.
Başlık: Ynt: interrupt işlemiyor
Gönderen: smail - 29 Ocak 2014, 00:43:05
arkadaşlar sonunda sorun çözülmüştür. verdiğiniz çok değerli fikirler için çok teşekkür ederim. inşallah benim gibi böyle bir sorun yaşayan kişiye faydalı olur.. interrupt dan çıktıktan sonra while(1) döngüsü içinde ikinci bir defa daha kontrol yaptırarak sorunu çözdüm. yani şu şekilde:

while(1)
    {   
   
            x=ReadUSART(); 
            while (!DataRdyUSART());
            if(!PORTBbits.RB4)
            LATD=0x40;
            if(PORTBbits.RB4)
            motor(x);     
    }


tüm kodlar ise şu şekilde oldu:

#include <p18f452.h>
#include <pwm.h>
#include <stdlib.h>
#include <usart.h>
#include <timers.h>
#include <delays.h>
#include <stdio.h>
#include <adc.h>
#include <portb.h>

#pragma config OSC = XT, PWRT = ON, WDT = OFF, LVP = OFF, DEBUG = OFF
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF, CPB = OFF, CPD = OFF
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF, WRTB = OFF,WRTC = OFF, WRTD = OFF
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF, EBTRB = OFF

void motor (int);
int x;

void int_handler(void);
#pragma code high_vector=0x08
void high_interrupts (void) {
    _asm GOTO int_handler _endasm
}

#pragma code low_vector=0x18
void low_interrupts (void) {
    _asm GOTO int_handler _endasm
}

#pragma code
#pragma interrupt int_handler

void int_handler(void) {

  if(INTCONbits.RBIF) // RBIF bayragi olusmussa
  {   
       
       if(!PORTBbits.RB4)
       LATD=0x40;

       if(PORTBbits.RB4)
       {
       motor(x);     
       }     
  }
       INTCONbits.RBIF=0;
}

void main(void){
    TRISB = 0x10;
    INTCONbits.GIE=1; // bütün kesmelere izin ver
    INTCONbits.RBIE=1; // PORTB degisim kesmesine izin ver

    PORTB = 0;
    TRISC = 0x80;
    PORTC = 0;
    TRISD = 0;
    PORTD = 0x40;


     
    OpenUSART(USART_TX_INT_OFF &   
  USART_RX_INT_OFF &
  USART_ASYNCH_MODE &
  USART_EIGHT_BIT &
  USART_CONT_RX &
  USART_BRGH_HIGH,207);

    OpenTimer2 ( TIMER_INT_OFF & T2_PS_1_4 & T2_POST_1_1 );

    OpenPWM1(249); // Period
    OpenPWM2(249); 

    SetDCPWM1(0);
SetDCPWM2(0);
     
    if((BusyUSART()));
   
while(1)
    {   
   
            x=ReadUSART(); 
            while (!DataRdyUSART());
            if(!PORTBbits.RB4)
            LATD=0x40;
            if(PORTBbits.RB4)
            motor(x);     
    }
}

void motor (int x)
{
            if(x=='S')
            {
             SetDCPWM1(0);
             SetDCPWM2(0);
             PORTD= 0x80;   
            }
         
            if(x=='F')
            {
             SetDCPWM1(498);
             SetDCPWM2(498);
             PORTD=0x8A;                       
             }
                     
         
            if(x=='V')
            {
             SetDCPWM1(498);     
             SetDCPWM2(498);
             PORTD=0x85;                             
             }

            if(x=='R')
            {

             SetDCPWM1(124);          
             SetDCPWM2(498);
             PORTD=0x8A;               
             }
                     
         
            if(x=='L' )
            {
             SetDCPWM1(498);          
             SetDCPWM2(124);
             PORTD=0x8A;               
            }
                       
}