E

PIC16F1826 #int_rda kesmesine gitmiyor

Başlatan eem7490, 27 Ağustos 2013, 12:34:11

eem7490

Merhaba Arkadaşlar.

Şuan üzerinde çalıştığım bir projede RDA kesmesini kullanmam gerekiyor. Kullandığım mikroişlemci PIC16F1826 ve programımı CCS C de yazıyorum.

İlk etapta yapmak istediğim RX den herhangi bir veri geldiğinde kesme alt programına gidip sadece 1 led yakmasını istemiştim. Ama burada paylaştığımdan anlaşıldığı üzere çalışmıyor.


#include <16f1826.h>   
#fuses intrc_io,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay (clock=32000000)
#use rs232 (baud=9600, xmit=pin_b5, rcv=pin_b2,bits=8,parity=N)

#int_rda
void kesme()
{   
    disable_interrupts(int_rda);
    output_high(pin_a0);
}
void main()
{
   output_LOW(pin_a0);
   while(1)
   {
    enable_interrupts(int_rda);
    enable_interrupts(global);
   }
}


Cevaplarınızı almadan önce belirtmek istediklerim :
1) Aynı kodu sadece işlemci değiştirerek düzenledi sorunsuz çalışıyor.
2) RDA kesmesi donanımsal bir kesme olduğu için pic RX ucundan veri alıyorum yine olmuyor. hatta tüm pinleri bile denedim belki olur diye yine olmadı.
3) Kodu yazdıktan registerleri kontrol ettim olması gerektiği gibi ama çalışmıyor.
4) Bunlara rağmen pes etmedim CCS C de Assembly komutlarıyla registerları ayarladım yine çalışmadı. Acaba asm kodlarında hata mı yapıyorum diye timer0 ve ext kesmelerini denedim sorunsuz çalıştı.
5) PIC de bu kesme özelliği yoktur demeyin lütfen.
6) Pic'i değiştirme gibi bir seçeneğim yok. Çünkü devre hazır ve sadece yazılımının yüklenmesini bekliyor.

Şimdi 4 günlük uğraştan sonra hala çalışmayan rda kesmesi yüzünden kafayı yemek üzereyim. Sorun hakkında sadece fikri bile olan varsa paylaşıp yardımcı olabilirse çok memnun olurum.

ete

Bu tür her işi gören işlemcileri pek sevmiyorum. Her işi yapayım derken hiç bir iş yaptırmıyor.
Bu işlemcide bunlardan birisidir.
Bu işlemci bacakları birden fazla fonksiyona sahip. Öncelikle kullanılmayan fonksiyonların iptal edilmesi gerekiyor. Bunları sıralarsak ;
- analog fonksiyonu
- komparatör özelliği
- kapasitif dokunma kontrol özelliği (capacitive sens)
- modulatör özelliği
- bir iki tane daha var ama onlar etkilimi bilemiyorum. İncelemek lazım.
Daha sonra ,  TX ve RX bacaklarının hangileri olduğunu belirlemen gerekiyor.
APFCON0 registeri 7 nolu bit RX bacağının RB1 veya RB2 de olacağına karar veriyor. Apfcon.7=0 verirsen RX pini PortB.1 oluyor. Sonra APFCON1 registeri sıfır nolu bit ile de TX bacağını belirliyorsun. APFCON1.0=0 verirsen Tx bacağı PortB.2 de oluyor.

Bu aşamadan sonra diğer USART kesmeleri gibi;
PIR1 registeri RCIE biti set ediliyor. Intcon.6 ve Intcon.7 set edilerek usart kesmesi açılıyor.
Rxsta registeri cren biti ile spen bitleri set ediliyor, txsta registeri sync biti sıfırlanıyor.
Bu işlemden sonra temp=rcreg denilerek kesme bayrağını bir kere sıfırlamak gerekiyor.
Bu işlemcide dikkat edilecek bir diğer husus da 16 bitlik baud rate registerinin olmasıdır. Ayrıca otomatik baud rate detection özelliğide bulunuyor. Bunları hiç kullanmadım ama bana kalırsa baudcon=%01000000 şeklinde bir değer verilmesi ayrıca gerekir diye düşünüyorum.
Yine bu işlemciye özel overrun error ve framing error gibi fonksiyonlar mevcut bunlardan birisi gerçekleşir ise karekter alma duruyormuş. Bu nedenle bu bitlerin sıfırlanması gerekiyormuş. Bunun için RCSTA.5 biti (CREN) sıfırlanması gerekiyormuş. Bu aynı zamanda continuous receive enable biti olduğu için herhalde önce sıfırlanıp sonra yeniden set edilmesi gerekiyor olmalı.
Bütün bunları değerlendirerek yeniden deneme yap bakalım sonucu bildirirsen memnun olurum.

Ete

eem7490

Sağolun hocam. dediklerinizin çoğunu assemly kullanmadan yapmıştım. Ama tekrar asm kodlarıyla deneyip olanları bildiririm.

eem7490

Şükürler olsun sonunda sorun çözüldü.
Hocam Allah sizden razı olsun. Kafayı yemek üzereydim.

Aşağıda pic16f1826 da rda kesmesinin oluşması için şart olan ayarlamalar kodda belirtilmekte. Etkilemeyen ayarları koda eklemedim, çünkü tam olarak neyin etkilediğinin görülmesini istedim.


#include <16f1826.h>   

#fuses intrc_io,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay (clock=32000000)
#use rs232 (baud=9600, xmit=pin_b5, rcv=pin_b2)

#byte RCSTA = 0X19D//4,7=1 6=0
#byte TXSTA = 0X19E//4=0
#byte APFCON0 =0X11D//7=0
#byte ANSELB=0X18D// 1,2=0

#int_rda
void kesme()
{   
   char j;
   j = getc();
   disable_interrupts(int_rda);
   output_toggle(pin_a0);
   putc(j);
}

void main()
{
   output_LOW(pin_a0);
   #asm
      BSF APFCON0,7
      BCF ANSELB,2// Önemli değil
      BSF RCSTA,7
      BCF TXSTA,4
      BSF RCSTA,4
   #endasm
   enable_interrupts(global);
   while(1)
   {
      enable_interrupts(int_rda);
   }
}



APFCON0  registerının 7. biti rda kesmesinin hangi pin için olacağını belirliyor.
   RXDTSEL: Pin Selection bit
   0 = RX/DT function is on RB1
   1 = RX/DT function is on RB2
Default olarak '0' yani RB1 etkin. Eğer  #use rs232 ( rcv=pin_b2)  yazarak alıcı pininin RB2 olduğunu belirtseniz bile kesme çalışmıyor bilginize. Ama RB1 i kullanacağım derseniz yazmaya gerek yok.
ANSELB registerının bitleri de B portu içiin hangi pinlerin analog olarak kullanılacağını seçiyor. Hangi biti set ederseniz o pin analog olarak kullanılıyor. ama default olarak '0' o yüzden dijital olarak kullanılmakta ve şuanki durum için yazmaya gerek yok. Çünkü analog ölçüm yapmıyoruz.
RCSTA ve TXSTA registerlarının durumları için, datasheetin 290'ıncı sayfasında bilgileri veriyor.

Ekte proteus ve hex dosyasını atıyorum. terminalden ne gönderirseniz pic aynen terminale geri gönderiyor.

ETE hocama gerçekten çok teşekkür ediyorum o olmasaydı şuan kafayı yerdim herhalde.

Hem proteusta hem de devre üzerinde denenmiştir.Gayet güzel çalışıyor.

rhnrgn

#4
Bir sorum olacak. Ekteki dosyanızı inceledim. Neden RB1 ve RB2 pinini beraber consola bağladınız?

Koda baktığımda RX olarak RB2 seçtiğinizi görüyorum. Bu kafamı karıştırdı.

Şu sıra bu 16f1826'nın uartı ile uğraşıyorum ve bir türlü çalıştıramadım da. Sadece saniyede bir veri bassın istiyorum hatta. Ayarlarda mı hata yapıyorum anlamadım.

CCS C complier kullanıyorum ve kodum şu.

/////////////////////////////////////////////////////////////////////////////////////////////
#include <16f1826.h>   

#fuses intrc_io,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay (clock=32000000)
#use rs232 (baud=9600, xmit=pin_b5, rcv=pin_b2)

#byte RCSTA = 0X19D//4,7=1 6=0
#byte TXSTA = 0X19E//4=0
#byte APFCON0 =0X11D//7=0
#byte ANSELB=0X18D// 1,2=0


void main()
{
   while(1)
   {
      putc('c');
      delay_ms(1000);
   }
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////

İşin garibi sizin proteus simulasyonunuza yüklediğimde bu kodu yine çalışmıyor.

daha da ilginci üstte verdiğiniz kodu CCS C de derleyip çıkan hex'i simulasyonunuza yüklediğimde yine çalışmıyor.

Daha daha da ilginci kodunuzda kullanmadığınız RB1 pininin bağlanısını simulasyonda koparttığımda kod yine çalışmıyor :D

Beni aydınlatırsanız sevinirim. Zira gözüm seğirmeye başladı :D




rree

 ccs karşılığı
 #asm      
   BSF RCSTA,7      
   BCF TXSTA,4      
   BSF RCSTA,4   
   #endasm   
//------------------------------------------
ccs karşılığı

  #bit CREN=GETENV("SFR:RCSTA").4
  #bit SPEN=GETENV("SFR:RCSTA").7
  #bit SYNC=GETENV("TXSTA:SYNC").4

 void main()
{
 SPEN=1;
 CREN=1;
 SYNC=0;
}

ete

16F1826 ve 16F1827 işlemcilerde EUSART modülü bulunuyor. Bu modül diğer normal USART modüllerinden farklı olarak Interrupt TRANSMITTER enable edildiği anda TXIF yani gönderme kesme bayrağını set etmektedir. Benzer şekilde Receiver Enable edildiğinde ise RCIF yani alma kesme bayrağını set etmektedir. Bu set edilen bayraklar nedeni ile işlemci normal çalışma koşulunda kesmeye gitmemektedir. Bu sorunu aşmanın yolu her iki bayrağın işe başlamadan önce sıfırlanmasıdır.
Her iki bayrak da program içinde direk sıfıra eşitlenerek sıfırlanmazlar. TXIF için TXREG=TEMP , RCIF için ise TEMP=RCREG komutlarının kullanılması gerekiyor. Asıl programa başlamadan önce bu işlemi yaparsanız daha sonra program doğru şekilde çalışacaktır. Şunu unutmayın USART yada EUSART modülü kullandığınız zaman TX ve RX pinleri başka amaçlar için kullanılamazlar. USart alma kesmesi kullanıp TX kesmesi kullanmasanız bile TX pinini boş bırakmak zorundasınız. Pek çok kişi bu hatayı yapmaktadır.

Ete

Akaan


Ben 16f877 de

#use rs232 (baud=9600, xmit=pin_C6, rcv=pin_C7, parity=N, stop=1)
Bu şekilde kullanıp #int_rda   // RX ucuna veri gelince meydane gelen kesme
Olarak gayet sorunsuz kullanıyorum.

Alıntı yapılan: rhnrgn - 25 Haziran 2014, 16:55:04Bir sorum olacak. Ekteki dosyanızı inceledim. Neden RB1 ve RB2 pinini beraber consola bağladınız?

Koda baktığımda RX olarak RB2 seçtiğinizi görüyorum. Bu kafamı karıştırdı.

Şu sıra bu 16f1826'nın uartı ile uğraşıyorum ve bir türlü çalıştıramadım da. Sadece saniyede bir veri bassın istiyorum hatta. Ayarlarda mı hata yapıyorum anlamadım.

CCS C complier kullanıyorum ve kodum şu.

/////////////////////////////////////////////////////////////////////////////////////////////
#include <16f1826.h>   

#fuses intrc_io,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay (clock=32000000)
#use rs232 (baud=9600, xmit=pin_b5, rcv=pin_b2)

#byte RCSTA = 0X19D//4,7=1 6=0
#byte TXSTA = 0X19E//4=0
#byte APFCON0 =0X11D//7=0
#byte ANSELB=0X18D// 1,2=0


void main()
{
   while(1)
   {
      putc('c');
      delay_ms(1000);
   }
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////

İşin garibi sizin proteus simulasyonunuza yüklediğimde bu kodu yine çalışmıyor.

daha da ilginci üstte verdiğiniz kodu CCS C de derleyip çıkan hex'i simulasyonunuza yüklediğimde yine çalışmıyor.

Daha daha da ilginci kodunuzda kullanmadığınız RB1 pininin bağlanısını simulasyonda koparttığımda kod yine çalışmıyor :D

Beni aydınlatırsanız sevinirim. Zira gözüm seğirmeye başladı :D





Powered by EzPortal