FOR.. NEXT ile ilgili bi sorun..

Başlatan solidus, 12 Kasım 2008, 19:02:20

solidus

Arkadaşlar PORTB.0'a bağlı bir test butonumuz var. Buna ilk basışta programın ilk adımını işleyecek 2. basışta 2 adımını işleyecek bir kod yazmaya çalıştım. Sanırım bi yerlerde hata yapıyorum. Acaba nerede ?
'DEĞİŞKENLER
Z VAR WORD
PIN    VAR PORTA.0
LNL    VAR PORTA.1
CLRSOL VAR PORTA.2
HYD    VAR PORTA.3
LAST   VAR PORTA.4
SENS   VAR PORTA.5
TEST   VAR PORTB.0

PINLED VAR PORTB.7
LNLLED VAR PORTB.6
LOW PORTC.2 
PAUSE 300
LAMBA:
HIGH PORTB.7:PAUSE 100:HIGH PORTB.6:PAUSE 100
HIGH PORTB.5:PAUSE 100:HIGH PORTB.4:PAUSE 100
HIGH PORTB.3:PAUSE 100:HIGH PORTB.2:PAUSE 100
HIGH PORTB.1
PAUSE 500
LOW PORTB
BASLA:
Z=0
PAUSE 100
LCDOUT $FE,$86,"XXXXX "
PAUSE 200
LCDOUT $FE,$C2,"XXXXX TEST SET "
PAUSE 1000

STARTING:
PAUSE 300
LCDOUT $FE,$80,"BASLAMAK ICIN   "
PAUSE 300
LCDOUT $FE,$C0,"TEST'E BAS      "
PAUSE 300
PRESSTEST:
IF TEST = 0 THEN GOTO STARTING
FOR Z=1 TO 10
IF TEST = 1 THEN Z=Z+1
LOW TEST
NEXT Z
IF Z=1 THEN
GOSUB TESTING
ENDIF
IF Z=2 THEN
GOSUB XXXXXXXXX
ENDIF

TESTING:
LOW PORTB.0
PAUSE 300
LCDOUT $FE,$80,"XXXXX XXX       "
PAUSE 300
LCDOUT $FE,$C0,"OMAJ TEST        "
PAUSE 700
PIN0:
IF PIN=0 THEN
PAUSE 100
LCDOUT $FE,$C0,"EMNIYETI SOK     "
LOW PINLED
ENDIF
GOTO PIN1

PIN1:
IF PIN=1 THEN
PAUSE 100
LCDOUT $FE,$C0,"OMAJ OK!         "
HIGH PINLED
ENDIF
GOTO PIN0

TOTALIZER:
PAUSE 300
LCDOUT $FE,$80,"XXXXXXXXX        "
PAUSE 300
LCDOUT $FE,$C0,"OMAJ TEST        "
PAUSE 700
TOT0:
IF LNL=0 THEN
PAUSE 100
LCDOUT $FE,$C0,"DEGER BAGLA      "
LOW LNLLED
ENDIF
GOTO TOT1
TOT1:
IF LNL=1 THEN
PAUSE 100
LCDOUT $FE,$C0,"OMAJ OK!         "
HIGH LNLLED
ENDIF
GOTO TOT0
END
Kimine göre kralım kimine göre yalanım… Herkes rahatına baksın, ben adamına göre adamım..

papylon

Gerçi bu işi yeni öğrenmeye çalışıyorum fakat, sorun LAMBA: etiketinin en alt satırındaki LOW PORTB komutundan kaynaklanıyor olabilirmi ?
Bildiğim kadarıyla LOW ve HIGH komutları Pin bazında işlem görüyor.

LAMBA: 
HIGH PORTB.7:PAUSE 100:HIGH PORTB.6:PAUSE 100 
HIGH PORTB.5:PAUSE 100:HIGH PORTB.4:PAUSE 100 
HIGH PORTB.3:PAUSE 100:HIGH PORTB.2:PAUSE 100 
HIGH PORTB.1 
PAUSE 500 
LOW PORTB

ftsahin

Alıntı yapılan: "solidus"
FOR Z=1 TO 10
IF TEST = 1 THEN Z=Z+1
LOW TEST
NEXT Z


For-Next döngüsü için kullandığın Z değişkeninin değerini döngü içerisinde değiştirmeye çalışmışsın. Döngü için başka bir değişken kullanabilirsin.  Programda başka hatalar da var.  
GOTO PIN1 

PIN1:


bu şekilde bir dallanma için goto kullanmaya gerek yok program zaten bir sonraki satıra gider.

solidus

@ftsahin,
Haklısınız, goto komutunu fazladan kullanmışım. Burada yapmak istediğim butona her basışta bir sonraki test döngüsüne dallanmak.. Bu şekilde yapınca ilk test işlemini gerçekliyor ve orada kalıyor..
IF TEST = 1 THEN 
PAUSE 50
Z=z+1
ENDIF
IF Z=1 THEN
GOSUB PINTEST
ENDIF
IF Z=2 THEN
GOSUB TOTALIZER
ENDIF
IF Z=3 THEN
GOSUB SOLTEST
ENDIF
IF Z=4 THEN
GOSUB HYDTEST
ENDIF
IF Z=5 THEN
GOSUB LASTTEST
ENDIF
IF Z=6 THEN
GOSUB MAGNTEST
ENDIF

şeklinde değişiklik yaparsam dilediğim gibi çalıştırabilirmiyim ?

@papylon,
Dostum teşekkür ederim sende haklısın.. Bi güncelleme yaparken orada unutulmuş..
Kimine göre kralım kimine göre yalanım… Herkes rahatına baksın, ben adamına göre adamım..

ete

Solidus,
Son verdiğin şekilde program çalışacaktır. Ancak her tuşa basılışta Z nin değeri bir artacak ama nereye kadar?. Bunuda kontrol altına alman gerek.
Makismum değer 6 olacak ise;
IF Z=7 then Z=1
demek işi çözümleyecektir. Yani Tuşa bastıkça Z bir artacak ve sonunda tekrar başa diönecektir. Yada başka bir şey yaptırmak istersen ona göre bir kod eklemen gerek.
Ayrıca Tuşa basarbasmaz Z=Z+1 olacak ve ilgili yere dallanıp yeniden başa gelecektir. Oraya koyduğun 50 ms tuşu bırakmak için yeterli bir süre değil. Ya bu değeri 100 veya 150 ms ye ye çıkart yada yeniden Z=Z+1 yapılması için tuşun bir kere bırakılmış olmasını şart koş.
Diğer hataları arkadaşlar belirtmişler ayrıca belirtmeyeceğim.


IF TEST = 1 THEN
PAUSE 150
Z=z+1
ENDIF

veya
IF TEST=1 THEN
Z=Z+1
WHILE TUS=1:WEND 'tuş bırakılıncaya kadar burada bekler
..
..

Programın başında bir kusur daha var. Ben olsam şöyle yazardım
STARTING:
LCDOUT $FE,$80,"BASLAMAK ICIN   "
LCDOUT $FE,$C0,"TEST'E BAS      "
PAUSE 500
PRESSTEST:
IF TEST = 1 THEN
  Z=Z+1
  if Z=7 then Z=0
endif

IF Z=1 THEN
GOSUB TESTING
ENDIF
IF Z=2 THEN
GOSUB XXXXXXXXX
ENDIF
Goto Starting

Bu şekilde yazdığın zaman Z=0 ise hiç bir yere dallanma olmayacak ve Test tuşuna basılıncaya kadar program bekleyecektir.
Basılmış ise Z=Z+1 yapılacak ve ona görede ilgili alt programa dallanma olacak ancak dallandığın alt programdan REURN ile dönülmesi gerektiğini unutma. Gosub ile gidilen yerden mutlaka yalnız bir RETURN komutu ile dönülür.
Alt programlarında RETURN göremedim. Üstelik program orada sonsuz döngüyede giriyor. Zira bir defa Testing kısmına geldimi bir daha oradan çıkamyor bu program. Sürekli pin0 ile Pin1 arasında dolaşıp duracak. Çıkış için bir şart oluşturman gerek.
Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

solidus

@ ete,
Hocam Yardımlarınız için teşekkür ederim dediğiniz üzere tüm değişiklikleri yaptım. Final Kod:
'DEĞİŞKENLER
Z VAR BYTE
PIN    VAR PORTA.0
TOT    VAR PORTA.1
SOL    VAR PORTA.2
HYD    VAR PORTA.3
LAST   VAR PORTA.4
MAGN   VAR PORTA.5
TEST   VAR PORTB.0

PINLED    VAR PORTB.7
TOTLED    VAR PORTB.6
SOLLED    VAR PORTB.5
HYDLED    VAR PORTB.4
LASTLED   VAR PORTB.3
MAGNLED   VAR PORTB.2
LOW PORTC.2 
PAUSE 300
Z=0

START:
PAUSE 300
LCDOUT $FE,$80,"BASLAMAK ICIN   "
PAUSE 300
LCDOUT $FE,$C0,"TEST'E BAS      "
PAUSE 300
PRESSTEST:
IF TEST = 0 THEN GOTO START

GONDER:
IF TEST = 1 THEN 
PAUSE 150
Z=Z+1
IF Z=4 THEN 
Z=0
ENDIF
ENDIF

IF Z=1 THEN
GOSUB PINTEST
ENDIF

IF Z=2 THEN
GOSUB TOTALIZER
ENDIF

IF Z=3 THEN
GOSUB SOLTEST
ENDIF

GOTO GONDER

PINTEST:

PAUSE 200
LCDOUT $FE,$80,"SAFETY PIN       "
PAUSE 200
LCDOUT $FE,$C0,"OMAJ TEST        "
PAUSE 500

PIN0:
IF PIN=0 THEN
PINLED=0 
'PAUSE 100
'LCDOUT $FE,$C0,"EMNIYETI SOK     "
ENDIF

IF PIN=1 THEN 
PINLED=1 
PAUSE 100
LCDOUT $FE,$C0,"      OK!        "
ENDIF
RETURN
'===============================================
TOTALIZER:
PAUSE 200
LCDOUT $FE,$80,"TOTALIZER        "
PAUSE 200
LCDOUT $FE,$C0,"OMAJ TEST        "
PAUSE 500

TOT0:
IF TOT=0 THEN
TOTLED=0
PAUSE 100
'LCDOUT $FE,$C0,"DEGER BAGLA      "
 
ENDIF

IF TOT=1 THEN
TOTLED=1 
PAUSE 100
LCDOUT $FE,$C0,"      OK!        "
ENDIF
RETURN
'===============================================
SOLTEST:
PAUSE 200
LCDOUT $FE,$80,"SELENOID         "
PAUSE 200
LCDOUT $FE,$C0,"OMAJ TEST        "
PAUSE 500

SOL0:
IF SOL=0 THEN 
SOLLED=0
PAUSE 100
'LCDOUT $FE,$C0,"DEGER BAGLA   "
 
ENDIF

IF SOL=1 THEN
SOLLED=1 
PAUSE 100
LCDOUT $FE,$C0,"      OK!             "
ENDIF
GOTO GONDER

END

şeklinde oldu. Ancak ufak bir ayrıntıda takıldım. Sanırım eksik bir şey var.İncelemek için zamanınız olursa  Link
Kimine göre kralım kimine göre yalanım… Herkes rahatına baksın, ben adamına göre adamım..

ete

Dosya ya baktım ama eksik olanı göremediğim gibi takıldığın şeyide anlayamadım. Açıklarsan sevinirim.

Sonradan fark ettim Z nin değerine bağlı olarak programı ilgili alt programlara Gosub ile göndermişsin. Ancak yalnızca PINTEST alt programı sonunda RETURN var ve diğerlerinde GOTO  GONDER yazmışsın. Bu önemli bir hata. Bir müddet sonra program sıkışır (kililtlenir) kalır.
Diğer alt programlardaki GOTO GONDER satırı yerine RETURN yaz.

Bir de bana ;
PAUSE 200
LCDOUT $FE,$80,"SAFETY PIN       "
PAUSE 200
LCDOUT $FE,$C0,"OMAJ TEST        "
PAUSE 500
şeklindeki satırlardaki mantığı bir açıklarmısın.
LCDOUT satırından önce verdiğin Pause komutu programı yavaşlatmaktan başka bir işe yaramaz. Bu satırları şöyle yazsan daha uygun olacak.

LCDOUT $FE,$80,"SAFETY PIN       "
LCDOUT $FE,$C0,"OMAJ TEST        "
PAUSE 200 'veya 300

LCDOUT komutundan önce Pause komutu kullanmamaya çalış. Pause komutu daima LCDOUT dan sonra kullanılır ve ekrana yazılan bilgininne kadar süre ekranda kalacağını belirler. Önceden yazdığın pause komutu bir önceki yazdırma işleminin ekranda kalma süresini artırır ve bu durumda kontrolu kaybedersin.
Örnek olarak;
TOTALIZER: alt programını şöyle yazıp bir dene bakalım.
TOTALIZER: 'ROUNDS LIMITER/TOTALIZER CONTINUITY & OPERATIONAL CHECK
LCDOUT $FE,$80,"TOTALIZER        "
LCDOUT $FE,$C0,"OMAJ TEST        "
PAUSE 500

TOT0:
IF TOT=0 THEN

LCDOUT $FE,$C0,"DEGER BAGLA      "
PAUSE 500
TOTLED=0 
ENDIF

IF TOT=1 THEN
TOTLED=1
LCDOUT $FE,$C0,"      OK!         "
PAUSE 200
ENDIF
RETURN


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

solidus

Alıntı yapılan: "ete"

Sonradan fark ettim Z nin değerine bağlı olarak programı ilgili alt programlara Gosub ile göndermişsin. Ancak yalnızca PINTEST alt programı sonunda RETURN var ve diğerlerinde GOTO  GONDER yazmışsın. Bu önemli bir hata. Bir müddet sonra program sıkışır (kililtlenir) kalır.
Ete

Tam da dediğiniz gibi ete hocam. Program sıkıştı..ve yaklaşık 800 adet uyarı verdi proteus.. sorun RETURN leri ekleyince çözüldü.. Teşekkür ederi başarılar dilerim..
Kimine göre kralım kimine göre yalanım… Herkes rahatına baksın, ben adamına göre adamım..