Arkadaşlar rf iletişim kurmaya çalışıyorum(16f628a nın uartı üzerinden(rf modül DRF4432)).
Ama 16f628a da sık sık donma oluyor.Ve bu donmayı bulabilmek için kodun bazı yerlerinde ledi yakıp kapatmayı denedim ve donmanın uart kesmesinde "hserin"komutunda gerçekleştiğini gördüm.Önerilerinizi bekliyorum.
Alıcı:
Kod:
@ __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_OFF & _LVP_OFF & _CP_OFF
PortA=0
PortB=0
TrisA=%00000000
TrisB=%00000010
include "modedefs.bas"
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
OPTION_REG.7 = 1
CMCON=7
'----------------------------------------------------------------------------
Say VAR word
X VAR Byte
Y VAR Byte
XX VAR Byte
K VAR Bit
KAPI VAR Bit
SYMBOL LED=PORTB.7
clear
pause 500
'*******************************************************************************
BASLA:
say=say+1
if say=1000 then
if x=xx then
if K=1 then
xx=X
HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]
HSEROUT ["EEEEEEEEE",dec3 xX]
HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]
HSEROUT ["EEEEEEEEE",dec3 xX]
HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]
HSEROUT ["EEEEEEEEE",dec3 xX]
k=0
endif
else
xx=X
HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]
HSEROUT ["EEEEEEEEE",dec3 xX]
HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]
HSEROUT ["EEEEEEEEE",dec3 xX]
HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]
HSEROUT ["EEEEEEEEE",dec3 xX]
endif
say=0
endif
PORTA=xx
GOTO BASLA
DISABLE
INT:
GIE=0 'kesme gerçekleştiği andan itibaren tekrar kesmenin oluşmaması için kesmeler iptal edilir
led=1
K=1
HSERIN 50,,[WAIT ("EEE"),dec3 x]'rx bacağından alınan veri gelen değişkenine alınır..
led=0
RCREG=xx
RCIF=0
GIE=1 'kesmeler aktif
Resume
enable
Verici:
@ __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_OFF & _LVP_OFF & _CP_OFF
PortA=0
PortB=0
TrisA=%11000011
TrisB=%00000010
include "modedefs.bas"
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
OPTION_REG.7 = 1
CMCON=7
'----------------------------------------------------------------------------
Say VAR word
X VAR Byte
XX VAR Byte
H VAR Byte
SYMBOL LED=PORTA.2
SYMBOL HATA=PORTB.0
pause 5000
clear
xx=000
x=000
'*******************************************************************************
BASLA:
if h=25 then
hata=1
h=0
endif
say=say+1
if say=10000 then
if x=xx then
h=0
hata=0
else
HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]
HSEROUT ["EEEEEEEEE",dec3 xX]
HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]
HSEROUT ["EEEEEEEEE",dec3 xX]
HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]
HSEROUT ["EEEEEEEEE",dec3 xX]
endif
say=0
h=h+1
endif
if porta.1=1 then
xx.1=1
else
xx.1=0
endif
if porta.0=1 then
xx.0=1
else
xx.0=0
endif
if porta.7=1 then
xx.7=1
else
xx.7=0
endif
if porta.6=1 then
xx.6=1
else
xx.6=0
endif
GOTO BASLA
DISABLE
INT:
GIE=0 'kesme gerçekleştiği andan itibaren tekrar kesmenin oluşmaması için kesmeler iptal edilir
led=1
HSERIN 50,,[WAIT ("EEE"),dec3 x]'rx bacağından alınan veri gelen değişkenine alınır..
led=0
RCREG=xx
RCIF=0
GIE=1 'kesmeler aktif
Resume
enable
Bu hata ilk açılıştada yaşanıyor iletişim sırasında da.Led değişkeni ni heserinden önce lojik 1 sonra lojik 0 yaptım.Ama arada led lojik 1 olarak donup kalıyor.Ve ne kadar beklersem bekleyeyim resetlemeden düzelmiyor.Bu arada wdt de neden çalışmıyor anlamadım. ???
Kesme içinde kesme bayrağının sıfırlanması için RCREG registerinin içinin boşaltılması gerekir.
Sen bunuyapmaya çalışmışsın ama bence yanlış zira,
RCREG=xx
şeklindeki tanımlama RCREG registerini boşaltmaz doldurur.
xx=RCREG
şeklinde yazarsan daha doğru olacaktır.
Böylece kesme bayrağı sıfırlanır ve program sürekli olarak kesme içinde kalmaz.
Ete
Kesme den çıkmadan önce kesme bayrağının sıfırlanması gerektiğini hepimiz biliyoruz.
Seniin konunda kesme bayrağı RCIF bitidir. Bu bit direk ulaşılabilir bit değildir. yani senin yaptığın gibi programda;
RCIF=0 yazmakla bu bit sıfırlanmaz. Bu komut derlemede hata da verdirmez. Çünki teorik olarak yanlış değildir. Donanımsal olarak imkansızdır. Data sheet öyle yazıyor. RCIF bitinin sıfırlanması ancak ve ancak XX=RCREG komut'u ile mümkün oluyor. Bu işlem geri planda hem RCREG registerini boşaltıyor (yer açıyor) hemde bayrağı sıfırlıyor.
Sende bu olay gerçekleşmediği için programın bence kesme den hiç ayrılamıyor donma sebebi budur. Ayrılsa bile bayrak set edili durduğu için anında yeniden geri kesme etiketine dönüyor.
Sen denemeni yap bence . Muhtemelen sorun düzelecektir.
Diğer bir konu da EEEEEEEEE şeklinde bir işaretçi kullanmak bence çok iyi bir fikir değil. İşaretçiler en fazla 3 karekter olursa çok iyi sonuç veriyor. Fazlası işlemciyi meşgul ediyor ve kodun aksamasına sebep oluyor. Üstelik bu işaretçi 3 farklı karekter yada en azından biri farklı olması dahada iyi sonuç veriyor.
Ete
Kodları alıcı verici diye ayırmışsın ama her ikiside ham alıyor hem veriyor.
Şayet ortada bir protokol yok ise kilitlenme sebebi muhtemelen veri yollanırken aynı zamanda veri almaya zorlanmasıdır programın.
Verme kodlarını teke düşür birden fazla vermeninde bir avantajı yok aslında hatta dezavantajı olabilir.
Ben olsam önce tek taraflı çalıştırmayı denerdim önce. Kilitlenme olup olmadığına bakardım. Olmuyorsa kesin alma ve verme sinyallerinin bir birine karışmış olmasıdır sebep.
Ete
OERR: Overrun Error bit
1 = Overrun error (Can be cleared by clearing bit CREN)
0 = No overrun error
Alıntı yapılan: BİLİRSHOP - 20 Mayıs 2015, 00:13:08
Müfit hocam thank you :)
Birde türkçe olsaymış hiç fena olmazmış.
Hocam malesef bu taşma hatası ile ilgili pek bi bilgim yok.Doğrusu kesmede kullanılan çoğu terim hakında bilgim yok.
o zaman ac adama balik verir gibi olurdu, halbuki simdi balik tutmayi ogrendi o ac adam.
Alıntı yapılan: BİLİRSHOP - 20 Mayıs 2015, 00:17:53
Eyvallah hocam.Peki bakıyorum şimdi inşallah bir şeyler çıkar :)
MCU'lar deterministik sistemlerdir. Bana farkli sana farkli davranmaz. Onun icin Insallah gibi icinde 'ALLAH'in adi gecen sozleri kullanirken daha dikkatli olmak gerekir.
Allahü teâlânın ismini, gereksiz yere kullanmak hürmetsizlik olur.
UART gibi asynchronous serial communication kullaniyorsan muhakkak
- Framing Error bit (burada FERR) ve Overrun Error bit (burada OERR) durumlarini da ISR yada okuma dongusunde kontrol etmek gerekir.
16f628A Datasheetinden bu bitler ne zaman durum degistirir ve yazilimla bunlari nasil okursunuz/degistirirsiniz bilmeniz lazim.
Allah calisma azmi'nizi daim kilsin ve bilmediklerinizi ogrenirken zihin acikligi versin.
Alıntı yapılan: BİLİRSHOP - 20 Mayıs 2015, 00:34:37
Mufit hocam ilk bahsettiğiniz konuda sizin gibi düşünmüyorum.Yani Allah'ın adını kullanmak ve duymak bana huzur veriyor.Ki bence bunu keşke daha sık yapabilsek.(diye düşünüyorum).
Lafi anlamadan cevap yaziyorsunuz. Ben size Insallah demeyin demiyorum. Bu durumda Insallah demek yerine ornegin "Eûzu billahi mineş-şeytânirracîm, Bismillahirrahmanirrahîm." deyin ve calismaniza baslayin daha yerinde olur. Sonucta Allah yeri ve gogu, Canli cansiz butun alemleri yaratmaya muktedirdir. Sizin programinizda sizin bilginizin kitligindan dolayi calismamaktadir. Dolayisi ile Allah isterse olur demek yerine Allahim bana calisma azmi ve zihin acikligi nasip etki bu problemimi cozeyim demek daha yerinde olur demek istedim.
Ama haklisiniz ogrenmek istemeyenede ogretilmesi dogru değildir. Bu da benim size yazacagim son mesaj olacak.
hep yanlış anlaşılma başka bişey değil. birbirimize yardım ederken bile kavga ediyoruz. aynı konu yüz yüze konuşulsa kesin kavga çıkmaz ama forumda birbirimizi görmediğimizden bazı şeyler yanlış anlaşılabiliyor.
Bu mantıkla sorun olması kaçınılmaz. İşaretçi 3 kerekter olmalı bu kural yollanırkende aynı alırkende aynı şekilde uygulanmalı.
Sen "EEEEEEE" yollayıp. "E" bekliyorsun.
Şimdi şöyle bir bilgi pakeyi yollandığını düşünelim EEEEEEEE,123
Alıcı önce ilk E yi görecek ve peşinden gelen 3 byte alacak aldığı bilgi E ve EEE olur.
Bilgiyi EEE,123 şellinde yollarsan ve alıcıda EEE bekleyerek çalışırsa alınan bilgi EEE,123 şeklinde olacaktır.
Toparlarsak işaretçi karekter adedi bu işte çok önemlidir. Ne yollamış isen onubekleyecek ve alacaksın.
Yollanan ve alınan byte adedi daima eşit olmalıdır.
Ete
Bence takılmıyor. Sürekli EEEE yollayıp tek E alarak işini yapmaya çalıştığın için sürekli program kesmeye giriyor.
Bu kadar USART yada UART lı gerçek devre yaptım hiç takılanı görmedim. Sorun senin Sistemi kullanış şeklinde mutlaka.
Denemeni yap ve ondan sonra bakalım ne olup bittiğine.
Timeout süresini 10ms den fazla verme. Aslında önceden de döyledim. wait ("BIL"),DEC3 X şeklinde kullanma neden desimal 3 digit olarak zorluyorsunki 2 digit yollanırsa ne olacak. O kısmı direk wait ("BIL"), X şeklinde kullan. Sonra program içinde sen yine onu desimal olarak değerlendir. Bu gibi şeyler haberleşme süresini artırıyor. Zira X=123 iken alacağın değer 123 olacaktır. DEC3 X şeklinde de yine 123 alacaksın ama kod uzayacak. Sonuçta yollarken X olarak yolla alırkende X olarak almayı dene bence.
Ete
Bu sistemin senaryosu nedir. Ne yapmaya çalışıyorsun? bunu açıklarsan belki daha fazla yardımcı olabilirim.
Kesme kısmında aşağıdaki kodu denermisin.?
DISABLE
INT:
GIE=0 'kesme gerçekleştiği andan itibaren tekrar kesmenin oluşmaması için kesmeler iptal edilir
led=1:K=0
HSERIN 10,ATLA,[WAIT ("BLR"),X]'rx bacağından alınan veri gelen değişkenine alınır..
K=1
ATLA:
LED=0
RC=RCREG
GIE=1 'kesmeler aktif
Resume
enable
Burada bilgi doğru gelirse K=1 olacaktır. Hatalı bilgi gelirse LED=0 yapılıp kesmeden çıkılacaktır. Her konumda led sönmesi gerekiyor.
Hatalı bilgi derken kesme oluşturacak kadar USART dan bir bilgi girişi olmalıdır. Aksi halde kesme meydana gelmeyecektir.
Örneğin ilk gelen bilgi BLR,3 şeklinde gelsin hatalı olanbilgide ERR,10 şeklinde gelirse led söner K=0 olarak çıkar.
Birde bu sistemi PC ile kullanıyor isen yollanan bilginin peşine 10,13 eklemen uygun olacaktır. Bunlar PC dilinde 1 adet Line Feed ve 1 adet RETURN komutu dur. (HSEROUT ["BLR",xX,10,13])
Ete
Interrupt rutini içinde alma gönderme gibi fonksiyonlar kullanmamayı dene.
Bu tür işleri ana programa bırak.
Time out vs değerleri olan fonksiyonlarla int rutinlerini bekletmek yanlış bir iş. Üstelik int rutini içinden her fonksiyon çağrılabilir mi diye dilin dokümanlarına bakman lazım.