Word Tipi Değişkeni EEPROM'a Yazma ve Okuma Sorunu

Başlatan Elektronikprojem, 29 Eylül 2016, 09:00:54

Elektronikprojem

Merhabalar kolay gelsin,
Eeproma veri kaydetme ve yazma konusunda ete hocanın derslerinden ve forumdan okuduklarımdan birşeyler yapmaya çalıştım ama kayıt işlemini pek beceremedim. cihazı kapatıp açınca sağlam ve bozuk değişkenleri sıfır gözüküyor. Kodlar aşağıda, sorunun nerede olduğuna dair yardımcı olabilecek birisi varmı?Amacım sağlam ve bozuk sayılarını ekrana yazmak ve stus isimli portb.1 deki butonla istendiğinde bu sayıları 0 yapmaktır.

@ __config _XT_OSC & _WDT_ON & _LVP_OFF & _CP_OFF              
DEFINE OSC 4
OPTION_REG=%0000000
TRISA=0                                                     
TRISB=%111111111                                               
TRISC=0                                                       
TRISD=0
trise=0
porta=0
portb=0
portc=0
portd=0
porte=0                                                 
;-------------------------------------------------------------------------------
DEFINE ADC_BITS 8       
DEFINE ADC_CLOCK 3     
DEFINE ADC_SAMPLEUS 50 
ADCON1=7
;-------------------------------------------------------------------------------
DEFINE LCD_DREG PORTD     
DEFINE LCD_DBIT 4       
DEFINE LCD_EREG PORTC     
DEFINE LCD_EBIT 7             
DEFINE LCD_RSREG PORTC   
DEFINE LCD_RSBIT 6       
DEFINE LCD_BITS 4       
DEFINE LCD_LINES 2           
PAUSE 500         
;-------------------sembol ve değişken tanımları--------------------------------
SYMBOL sat=portb.7
symbol sot=portb.6
symbol uvys=portb.5
symbol start=portb.4
symbol bpms=portb.3
symbol reset=portb.2
symbol bp=portd.2
symbol kp=portd.1
symbol kled=porta.0
symbol yled=porta.1
symbol stus=portb.1
saglam var word
bozuk var word
if saglam=65535 then saglam=0
if bozuk=65535 then bozuk=0
i var byte
;-------------------------------------------------------------------------------
basla:
if stus=0 then GOSUB sifirlama
write $0,saglam.lowbyte
write $1,saglam.highbyte
write $2,bozuk.lowbyte
write $3,bozuk.highbyte
pause 30
read $0,saglam.lowbyte
read $1,saglam.highbyte
read $2,bozuk.lowbyte
read $3,bozuk.highbyte
;-------------------------------------------------------------------------------
if start=0 and uvys=1 then
gosub urunkoy
endif
lcdout $fe,1, "Butona Basiniz"
lcdout $fe,$c0, "S:",#saglam, "     B:",#bozuk 
pause 200
if start=0 and uvys=0 then
pause 200
if start=0 and uvys=0 then
lcdout $fe,1, "Test Ediliyor"
pause 100
high bp
gosub sabitleme
endif
endif
goto basla
;-------------------------------------------------------------------------------
sabitleme:
pause 200
if bpms=0 and sat=0 and sot=0 and uvys=0 then
high kp
pause 250
gosub kontrol
endif
if bpms=0 and sat=1 and sot=0 then gosub sata
if bpms=0 and sat=0 and sot=1 then gosub sota
if bpms=0 and sat=1 and sot=1 then gosub ikita
if reset=0 then gosub rest
goto sabitleme
;-------------------------------------------------------------------------------
kontrol:
if sat=1 and sot=1 then
low kp
pause 150
if sat=0 and sot=0 then
gosub ikincikontrol
endif
endif
if sat=1 and sot=0 then
gosub sota
endif
if sat=0 and sot=1 then 
gosub sata
endif
if sat=0 and sot=0 then
gosub ikita
endif
if reset=1 then gosub rest
goto kontrol
;-------------------------------------------------------------------------------
ikincikontrol:
high kp
pause 150
if sat=1 and sot=1 then
gosub ok
endif
if sat=1 and sot=0 then
gosub sata
endif
if sat=0 and sot=1 then 
gosub sota
endif
if sat=0 and sot=0 then
gosub ikita
endif
if reset=1 then gosub rest
goto ikincikontrol
;-------------------------------------------------------------------------------
ok:
Lcdout $fe,1, "Anahtar Saglam"
high yled
pause 250
saglam=saglam+1
low kp
low bp
low yled
if bpms=1 then
goto basla
else
goto ok
endif
;-------------------------------------------------------------------------------
sata:
Lcdout $fe,1, "3. Term. Arizali"
lcdout $fe,$c0, "Reset'e Basin"
high kled
pause 250
if reset=0 then
bozuk=bozuk+1
gosub rest
else
goto sata
endif
;-------------------------------------------------------------------------------
sota:
Lcdout $fe,1, "1. Term. Arizali"
lcdout $fe,$c0, "Reset'e Basin"
high kled
pause 250
if reset=0 then
bozuk=bozuk+1
gosub rest
else
goto sota
endif
;-------------------------------------------------------------------------------
ikita:
Lcdout $fe,1, "2. Term. Arizali"
lcdout $fe,$c0, "Reset'e Basin"
high kled
pause 250
if reset=0 then
bozuk=bozuk+1
gosub rest
else
goto ikita
endif
;-------------------------------------------------------------------------------
rest:
lcdout $fe,1, "Reset...."
Lcdout $fe,$c0, "Bekleyiniz..."
pause 200
low kled
low kp
low bp
goto basla
;-------------------------------------------------------------------------------
urunkoy:
high kled
for i=1 to 10
lcdout $fe,1, "  Yuvaya Urun  "
lcdout $fe,$c0, "  Yerlestirin  "
pause 125
low kled
next
goto basla
;-------------------------------------------------------------------------------
sifirlama:
saglam=0
bozuk=0
if stus=1 then
goto basla
else
goto sifirlama
endif





ta3usl

Merhaba,

Programı sonuna kadar incelemedim fakat değişken tanımlayıp , herhangi bir değer atamadan sıfırlıyorsun. Bu yüzden her seferinde sıfırlanıyor. Değişkenleri tanımladığın satırların altında epromdan okutup kontrollerini yaptırırsan sorun düzelecektir diye tahmin ediyorum.

saglam var word
bozuk var word

'''Bu araya epromdan okutup değişkenlere atama yap

if saglam=65535 then saglam=0
if bozuk=65535 then bozuk=0



Elektronikprojem

Şu şekilde diyorsunuz değil mi
saglam var word
bozuk var word
read 0,saglam.highbyte
read 1,saglam.lowbyte
read 2,bozuk.lowbyte
read 3,bozuk.highbyte
if saglam=65535 then saglam=0
if bozuk=65535 then bozuk=0

Elektronikprojem

Şu anda kayıt işlemi tamam ama mesela saglam yazan kısın kapatırken 2 ise cihazı kapatıp açtığımda 512 oluyor tekrar kapatıp açtığımda tekrar 2 oluyor

ete

Programda bir çok hata var.
Başla satırından önceki hatayı düzelttin. Değişkenler ilk açılışta sıfır değeri ile açılır. Bu garanti değildir ama genelde sıfırlanır açılır. Açılır açılmaz o değişkeni kayıt edersen elbette sonradan okunan değer sıfır olurdu. Neyseki düzelttin.

Başla satırından sonrakilere bakarsak sırası ile;
if stus=0 then GOSUB sifirlama komutu ile şayet STUS isimli tuşa basılırsa SIFIRLAMA ya GOSUB ile gidilmesini söylüyorsun. Bu şu demektir. Program o etikete gider ama oradan dönerken ilk gördüğü RETURN komutu ile geldiği satıra veya bir sonraki satıra döner. Senin SIFIRLA isimli alt programında hiç RETURN yok. Bu stack taşmasına sebep olur ve bir müddet sonra programın kilitlenir. SIFIRLA isimli etiketten GOTO BASLA ile dönecek isen oraya GOTO SIFIRLAMA şeklinde gitmen gerekiyor.
Burada unutulmaması gereken şey GOSUB ile gidilen alt programdan RETURN ile dönülür. Gosub ile gidilip Goto ile dönersen stack taşması meydana gelir ve bu durum kilitlenmeye kadar gider.

Alt kısımda ise birden fazla eproma yazma komutu var. Bunlar bir şarta bağlanmamış. Bu durumda program o satırlarda dönerken sürekli eproma kayıt yapar. Bu durumda eprom kayıt ömrü (1 milyon adet) anında dolar. Fazla gibi geliyor belki sana ama bir günde olmazsa ikinci gün eprom kayıt ömrün biter işlemcide kullanılmaz hale gelir. Eproma bir bilgi kayıt edilecek ise o bilgi değiştiği zaman kayıt edilmeli gereksiz kayıtlardan kaçınılmalıdır.
Program algoritmasını buna göre değiştirmen gerek.
Eprom Okuma işleminin ömüre etkisi yoktur istediğin kadar okuma yapabilirsin. Ama okuma işleminide sürekli yapmanın anlamı yok. Bir değişkene verdiğin değer onu değiştirene kadar veya devrenin voltajını kesene kadar değişmez. Süreki okuma yapmanında bir anlamı yok diye düşünüyorum. Algoritmayı bu noktada da değiştirerek gerektiği zaman okuma yapmayı denemelisin.

Programda bol keseden GOSUB kullanmışsın ama bir tane bile RETURN göremedim. Bu durumda bu GOSUB satırlarını ya GOTO yap yada oradan dönüşleri RETURN ile yapmayı dene.

Ete

Elektronikprojem

Yani programı gosub ile etikete yolladıktan sonra mutlaka return yapmalıyım. O etiketin içinde döngü yapmasını istiyorsam o etikete GOTO ile mi gitmeliyim hocam.

ete

Gosub ile gittiğin alt programdan mutlaka return ile dönmelisin. Return komutu programı gosub satırından bir sonraki satıra geri gönderir.
Goto şarta bağlı olmaksızın bir yönlendirme komutudur. Goto etiket denildiğinde etikete gider ve orada kalır. Oradan başka bir yere yine goto ile göndermen gerekir. Gosub öyle değil. Gosub -Return ayrılmaz ikilidir. Gosub etiket denildiğinde program etikete gider ama oradan mutlaka bir return ile geri döndürülmelidir, istersen etiketten sonra bir başka etikete goto ile gidebilirsin ama bu sefer gittiğin ikinci etiketten mutlaka return ile dönmelisin. Bunun ana sebebi stack denilen ara hafıza kullanımıdır. İşlemcide direk ulaşılamayan ama işlemci tarafından yoğun olarak kullanılan bir ara hafıza vardır. Gosub etiket komutunu program gördüğü zaman ayrıldığı program adresini hemen stack a atar işlemci. Bir başka gosub komutu görürse onuda atar bu durumda son giren daima ilk çıkan olacaktır. Yani ilk return komutu ikinci gosuba döndürür. Orada görülen diğer return da programı ilk gosub ile gelinen yere döndürür. Stack seviyesi işlemciye göre değişmekle birlikte 5-6 tane gibi düşünülmelidir. Bu nedenle return olmadan en fazla üst üste 5-6 adet gosub kullanılmalıdır.
Ama programda yüzlerce gosub kullanabilirsin. Yeterki üst üste 5-6 taneyi geçme. Gidip döndükten sonra gosubların sınırı yoktur. Gosub ile gidip goto ile dönersen  gidiş adresin stack de kalır. Bir sonraki gosub yeniden stacke yazılır ve sonunda yazılacak adres için hafıza kalmaz buda kilitlenme sebebidir, bu nedenle daima gosub ile gittiğin yerden return ile dönmelisin.

Ete

Elektronikprojem

Aydınlattığınız için teşekkürler hocam. Şu an herşey halloldu gosubları goto yaptım ve kayıt işini de hallettim.

Powered by EzPortal