interrupt işlemiyor

Başlatan smail, 27 Ocak 2014, 21:33:23

smail

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()));

selimkoc

#16
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.

smail

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;

Tagli

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.
Gökçe Tağlıoğlu

smail

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;
  }

}

selimkoc

if bloğu içine 200ms kadar bekleme koysan (buton arkı için),

birde butona paralel 100nf kond. eklesen duruma baksan.

Tagli

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.
Gökçe Tağlıoğlu

smail

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;                
            }
                        
}