16f628A Uarta Donma

Başlatan BİLİRSHOP, 19 Mayıs 2015, 01:58:26

BİLİRSHOP

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. ???

ete

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
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

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

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

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
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

mufitsozen

OERR: Overrun Error bit
1 = Overrun error (Can be cleared by clearing bit CREN)
0 = No overrun error
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

mufitsozen

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.
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

mufitsozen

#6
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.
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

mufitsozen

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.
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

elektronik

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.


ete

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
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

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
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

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


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

z

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.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com