Haberler:

Forum kuralları güncellendi LÜTFEN  okuyunuz:  https://bit.ly/2IjR3ME

Ana Menü

uart kesmesi

Başlatan Karamel, 08 Eylül 2014, 15:48:05

Karamel

merhaba. mikroc ile uart kesmesi yapmaya calisiyorum. asagidaki kodum ile kesme olusuyor. yalniz microcontroller surekli kesme rutinine giriyor. bunu anlamak icin interrupt rutininin icersinde buzzer imi otturdum. buzzer surekli bip bip bip bip otuyor. nerde hata yapiyorum? kullandigim microcontroller = pic18f2525


void interrupt()
{
      PIE1.RCIE = 1;                          // Uart Kesmeleri
      PIR1.RCIF=0;                            // Uart Flagı

      INTCON.GIE = 0;
      INTCON.PEIE = 0;
      
      
      Buzzer = 1; Delay_ms(500);
      Buzzer = 0; Delay_ms(500);
      
      

      PIE1.RCIE = 1;                          // Uart Kesmeleri
      PIR1.RCIF=0;                            // Uart Flagı

      INTCON.GIE = 1;
      INTCON.PEIE = 1;
}


interruptlarida soyle aciyorum

      // interruptlar açık!
      INTCON.F6 = 1;
      PIE1=0b00100000;
      INTCON.GIEL = 0;
      PIE1.RCIE   = 1;     // Rs485 kesmeleri aktif
      INTCON.PEIE = 1;
      INTCON.GIE  = 1;

kimlenbu

interrupt rutini içinde delay kullanmak, hele ki toplam 1sn'lik delay kullanmak oldukça büyük sıkıntılara yol açar.

uart'tan her karakter geldiğinde kesme oluşur, senin bu veri akışını kontrol etmen gerekir. Gelen verileri bir buffer'a atarsın, beklediğin bir karakter vs gelince işlemlerini yaparsın.

Micro C kullanmadım hiç, interrupt flaglarıyla ilgili sıkıntı da olabilir.

LukeSkywalker

Kodun tamamını paylaşın.

Karamel

#3
Alıntı yapılan: LukeSkywalker - 08 Eylül 2014, 15:58:55
Kodun tamamını paylaşın.

#define Buzzer PortA.F4
#define Select PortB.F0


void interrupt()
{
      PIE1.RCIE = 1;                          // Uart Kesmeleri
      PIR1.RCIF=0;                            // Uart Flagı

      INTCON.GIE = 0;
      INTCON.PEIE = 0;


      Buzzer = 1; Delay_ms(500);
      Buzzer = 0; Delay_ms(500);



      PIE1.RCIE = 1;                          // Uart Kesmeleri
      PIR1.RCIF=0;                            // Uart Flagı

      INTCON.GIE = 1;
      INTCON.PEIE = 1;
}

void init()
{
      TrisA = 0;
      TrisB = 0b11111100;
      TrisC = 0b10111000;

      PortA = 0;
      PortB = 0;
      PortC = 0;

      CMCON = 0xCF;                       //  Herkes dijital olsun
      ADCON1=0x0F;                        //

      PortB.F0 = 0;        // 75176 alıcı modda

      // interruptlar acik!
      INTCON.F6 = 1;
      PIE1=0b00100000;
      INTCON.GIEL = 0;
      PIE1.RCIE   = 1;     // Rs485 kesmeleri aktif
      INTCON.PEIE = 1;
      INTCON.GIE  = 1;


      UART1_Init(57600);   // Uart Aciliyor
      Delay_ms(500);       // Uart stabilize olsun siye bekliyoruz.


}


void main() 
{
    init();
    while(1);
}


mesaj birleştirme:: 08 Eylül 2014, 16:57:56

simdi kodumun uzerinde biraz daha oynama yaptim.

#define Buzzer PortA.F4
#define Select PortB.F0


void interrupt()
{
      PIR1.RCIF = 0;                            // Uart Flagı


      Buzzer = 1; Delay_ms(100);
      Buzzer = 0; Delay_ms(100);
}

void init()
{
      TrisA = 0;
      TrisB = 0b11111100;
      TrisC = 0b10111000;

      PortA = 0;
      PortB = 0;
      PortC = 0;

      CMCON = 0xCF;                       //  Herkes dijital olsun
      ADCON1=0x0F;                        //

      PortB.F0 = 0;        // 75176 alıcı modda

      // interruptlar acik!
      PIE1.RCIE   = 1;     // Rs485 kesmeleri aktif
      INTCON.GIE  = 1;
      
      RCON.IPEN = 1;       // high priority aktif
      IPR1.RCIP = 1;

      UART1_Init(57600);   // Uart Aciliyor
      Delay_ms(500);       // Uart stabilize olsun siye bekliyoruz.

}


void main() 
{
    init();
    while(1);
}



interruptin olusmasi icin gerekli sartlari sagliyorum. zaten microcontroller interrupta giriyor. interrupt icersinde RCIF i 0 yapiyorum. bu sartlarda interrupt olusmamasi gerekir? ama olusuyor...


RaMu

Denem aşamasında buzzer ı boşver sağlıklı çıkarım olmaz.
programına bir 2x16 lcd ekle
kesme içinde bir değişkeni arttır,
bunuda ana döngüde lcdde göster.

Ayrıca bu kesme tarzı
eğerki başka kesme kaynağı yoksa kullanılabilir
yoksa herhangibirbaşka kesme olduğundada kesme rutinine girilir,
bu nedenle
ya özel kesme ataması varsa direk o kullanılacak
yada kesme rutini içerisinde kesmenin kaynağı hangi modül diye bakılacak
misal
void interrupt()
{
   if(  PIR1.RCIF  )  
   {
   //eğer kesme kaynağı uart ise yapılacak işlemler
   }
}


Kesme içinde delay kullanma.

Birde uart için kesme oluşturacak durum belki 2 msde bir gerçekleşiyor?
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Karamel

hocam buzzeri toggle ettim yine olmadi. hocam pc den A karakterini gonderiyorum birkere. microcontroller interrupt rutininden cikamiyor yada surekli interrupta giriyor. cok ilginc bir durum.

void interrupt()
{
      if(  PIR1.RCIF  )
      {
       //eğer kesme kaynağı uart ise yapılacak işlemler
      }

      Buzzer = ~Buzzer;
      
      PIR1.RCIF = 0;                            // Uart Flagı
}

LukeSkywalker

Sorun şu: RCIF bayrağı RCREG'den veri okunana kadar 1 olarak kalır. Bu bayrağı kendiniz sıfırlayamazsınız. Uart kesmesi içerisinde uart_read komutunu kullanın, sorununuz çözülecek. Datasheet'i iyi okuyun.

Karamel

Alıntı yapılan: LukeSkywalker - 08 Eylül 2014, 17:50:51
Sorun şu: RCIF bayrağı RCREG'den veri okunana kadar 1 olarak kalır. Bu bayrağı kendiniz sıfırlayamazsınız. Uart kesmesi içerisinde uart_read komutunu kullanın, sorununuz çözülecek. Datasheet'i iyi okuyun.

hocam hallettim. cok tesekkur ederim. hocam pic dunyasinda yeniyim. RCIF in acikladigi satirdan acikca anlayamadim durumu. gerci pekte acik degil gibi.

bit 5 RCIF: EUSART Receive Interrupt Flag bit
1 = The EUSART receive buffer, RCREG, is full (cleared when RCREG is read)
0 = The EUSART receive buffer is empty

LukeSkywalker

Gayet açık datasheet.
Kalınlaştırdığınız yerde " 1=Eusart veri alma tamponu, RCREG, dolu ( RCREG okunduğunda sıfırlanır) " yazıyor.