PicBasic Pro'da Usart Kesmesi Oluşturmak

Başlatan sburakguneri, 12 Mart 2011, 17:06:10

sburakguneri

Merhaba arkadaşlar. Merak ettiğim konu şu; bir USART kesmesi programı oluştururken PIE1 ve PIR1 registerlerini düzenlemek gerekiyor mu? Örneğin pice seri porttan herhangi bir veri gönderdiğimde pice (16f628a) bağlı bir ledin yanmasını istiyorum. Aşağıdaki kodlarla bunu gerçekleştirebilir miyim? Yoksa PicBasic Pro bu registerleri kendi mi kontrol etmektedir?


INTCON=%10000000   'GIE=1
PIE1=%00110000       'USART RECEIVE VE TRANSMIT KESMELERİ AKTİF
.......
....
..
.
     
DISABLE
KESME:
IF PIR1.5=1 THEN HIGH RLED ENDIF     'USART ALMA OLAYINDA FLAG 1 OLMUŞSA LEDİ YAK
PIR1.5=0
RESUME
ENABLE



ete


USART kesmesini açmak için;
Önce Genel kesmeleri açmak lazım yani INTCON.7=1
Daha sonra peripheral kesmeleri açmak lazım yani INTCON.6=1
Daha sonra  Usart Alma kesmesini açmak lazım yani PIE1.5 =1
En sonunda da ON INTERRUPT GOTO INT komutunu kullanmak lazım.
Tabiiki bunlardan önce usart haberleşme parametrelerini ayarlamak için gerekli define komutlarınıda programın başına yerleştirmen lazım.

İşin bu kadarı kesmenin açılması ileilgili. Birde kesme kısmında yacakların var elbette.
USART dan bir veri (bu bir parazit sinyalide olabilir gerçek veri de olabilir) girdiği zaman program hemen INT etiketine atlayacaktır.
Şayet gelen veri paketinin başına bir işaretçi yerleştirmiş iseniz program önce paketin başında bu işaret varmı bakacaktır.
Var ise gelen veri alıncak ok ise bekleme default süresi  kadar bekleyip INT alt programından çıkılacaktır.
Şayet veri paketinin başında beklenen işaret var ise verinin geri kalanı alınıp değişkenlerine yerleştirilecektir.
Ayrıca USART kesme bayrağının sıfırlanabilmesi için RCREG registerinin bir değişkene eşitlenmesi gerekiyor. Daha sonra kesme bayrağı sıfırlanıp kesme den ayrılmak gerekir.

Şimdi gelelim senin isteğine; İki türlü yapılabilir. İlk açıklama en doğrusudur. Çünki en tutarlı olanı bu ilk yöntemdir.
Gelen veri paketi içerisine ilgili led in yakılması için bir işaret değişkeni yerleştirilirse bu değişken alındığı zaman gidip ilgili led yakılabilir.
Aşağıdaki örnek programda alınan bilgi arasında göreceğin VeriLED değeri normalde sıfır da bekletilir. Veri geldiği zaman değeri 10 olur ve programiçinde VeriLed=10 ise led=1 yapılıp veriled yeniden sıfırlanır.

İkinci sistemde gelen paket istenen paket ise bir bit değişkeni set edilir ve ana program içinde bu değişken set edilmiş ise led yakılır.


DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_SPBRG 25  ' 9600 Baud @ 0,16%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically

SYMBOL GIE  =INTCON.7   'genel interruptları açıyor
SYMBOL PEIE =INTCON.6   'peripheralinterruptları açıyor
SYMBOL RCIE =PIE1.5     'USART Recive interrupt enable bit
SYMBOL RCIF =PIR1.5     'USART Receive interrupt flag bit

RCIE=1
PEIE=1
GIE=1 
ON INTERRUPT GOTO INT


Basla:
         if veriLED=10 then HIGH LED
...
..
...
..
GOTO Basla


DISABLE
INT:
    GIE=0
    hSerIn , [WAIT("TMR"),VeriA,VeriLED]  
'    kesme=kesme+1
    TEMP=RCREG 
    RCIF=0
    GIE=1
    Resume
    enable


Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

sburakguneri

Çok faydalı oldu. Bilgiler için teşekkür ederim.

sburakguneri

Bir  sorum daha var. Diyelim ki farklı 2 kaynaktan veri bekliyoruz. Kaynaklardan herhangi  birisi veri yolladığında usart kesmesi oluşuyor. Bu durumda verinin hangi kaynaktan geldiği problemini nasıl çözebiliriz?

Örneğin program aşağıdaki gibi olucak. HSERIN ile alınan veriye nasıl bir karar mekanizması kuracağım konusunda sorun yaşıyorum.

     
DISABLE
KESME:
    GIE=0
    hSerIn , [WAIT ("ABC"), DATA1]   'Bu 1. kaynaktan gelen veri
    hSerin , [WAIT("DEF"), DATA2]  ' 2. kaynaktan gelen veri
   
    TEMP=RCREG
   
    RCIF=0
    GIE=1
    Resume
enable


ete

Bunun için iki bileşenli veri alırsın. Birisi kaynağı (gönderenin ID numarası) diğeri ise kullanılacak veriyi gösterir.
Örnek vermek gerekirse USART dan gelen veri KIM,ALINAN şeklinde iki değişken halinde olur ise;
KIM=1 ise 1. kaynak
KIM=2 ise 2 kaynak
şeklinde verinin kimden geldiği anlaşılabilir.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

Emin Aydın EROĞLU

#5
Hocam peki şöyle bir sorum olacak aynı olayı yazılımsal seri haberleşme içinde yapabilirmiyiz yani serin2 komutu için ?

EFESU

Konu  çok eski ama  kafama  takılan bişey var ..  usart kesmesi oldu tamam
kesmeye gidildi tekrar hserin  neden kullanılıyor...
  If PIR1.5 = 1 Then   
     B1 = RCREG         
   endif ... bu kod  daha doğru değil mi _?
veri rcreg e gelmiş olmuyor mu kesme  olduğun da _?

ete

Oluyor haklısın ama birde şöyle düşün o yazdığın kod sistemini kullanarak,
Hserin 5,CIK,[Wait("EFE"),veri1,veri2,veri3]
Komutunun yaptığı işi yaptırabilecek bir kod yazda görelim bakalım hangisi daha kolaymış.

Unutma usart kesmesi veri paketinin başını yakalamak amacı ile kullanılır. Basicde program yazıyorsun ve o konuda basic komutu var ise kullanır işini kolaylaştırırsın. Yoksa asm mantığı ile registerler üzerinden kod yazarsın seninki gibi.
Önemli olan veri paketinin başını yakalamaktır gerisi hserin ile kolaylıkla alınır. Aynı işi yapacak kodu yazınca anlayacaksın ki epeyce kod kullanman bir sürü if kullanman gerekecek. Gerek varmı?

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

EFESU

Hocam seri dizi verisi geldiğini varsayar isek şu an max485 ile  yatığım devrede
20 adet veriyi taşıyorum yada şöyle söylim taşımaya  çalışıyorum..

Kesme oldu gittik
hserin ile diziyi alabilirmiyiz yada her kesme  oluşunda dizi elemnını bir artırıp mı almak
daha doğru  olur ...
If PIR1.5 = 1 Then  
 
     B1[i] = RCREG 
i=i+1        
   endif

ete

Hserin [str Bi\n]
Komutu n adet byte alıp bi dizisine yerleştirir.
Komut işaretçi ilede başlayabilir. Hserin 5,atla,[wait("ser"),str  BI\8] şeklinde de kullanılabilir.
Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

EFESU

#10
Hserin [str Bi\n]


bu komut yada str  kullanımı
shiftout komutu yada hserout içinde geçerli mi _?

data2 5 elemanlı dizi  hocam
SHIFTOUT DTA,CLK,1,[str data2\5]
bu şekilde kullandım hata verdi