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
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
Çok faydalı oldu. Bilgiler için teşekkür ederim.
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
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
Hocam peki şöyle bir sorum olacak aynı olayı yazılımsal seri haberleşme içinde yapabilirmiyiz yani serin2 komutu için ?
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 _?
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
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
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
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