Butona kaç defa basıldığını saymak "PBP ile"

Başlatan solidus, 16 Mart 2008, 19:15:50

bahri

DEGER VAR BYTE
TRISA=%00000001
TRISB=0
PORTB=0
BUTON VAR PORTA.0
DEGER = 0
BASLA:
        IF BUTON =1 THEN
        PAUSE 150
           DEGER = DEGER + 1
           GOSUB EKRAN
           pause 500
           ENDIF
        IF DEGER =9 THEN DEGER = 1  
           
           PORTB=0
        GOTO BASLA
EKRAN:
        LOOKUP DEGER,[$0,$1,$2,$4,$8,$10,$20,$40,$80],PORTB
        RETURN
       
               END

solidus
eğer 1 kez tuşa bastığında 1. led yansın belli bir süre sonra sönsün aynı işlem ikinci.......sekizinci led için olsun diyorsan bu program işini görür
ledin ne kadar yanık durmasını istiyorsan bi zahmet pausela oynayarak hallet :)

sitenindelisi

yani bu yöntemi kullanmamın rahatlıkla bi alakası yok sadece alışkanlık.

solidus

@ DEVICE pic16F84A 
@ DEVICE pic16F84A, WDT_ON 
@ DEVICE pic16F84A, PWRT_ON 
@ DEVICE pic16F84A, PROTECT_OFF 
@ DEVICE pic16F84A, XT_OSC

TRISA=%00000     	'A portunun tamamı Çıkış olarak ayarlandı.
PORTA=0          	'A portunun tamamı LOW (0).
TRISB=%11100000     'B portunun 5,6,7. bitleri giriş olarak ayarlandı.
PORTB=0             'B portunun tamamı LOW (0).


STA1 VAR PORTA.0
STA2 VAR PORTA.1
STA3 VAR PORTA.2
STA4 VAR PORTA.3
BTTN VAR PORTB.5
SNGL VAR PORTB.7
RPPL VAR PORTB.6
LED1 VAR PORTB.1
LED2 VAR PORTB.2

x var byte
y VAR BYTE 
x=0  
y=0
KONTROL:
IF SNGL=1 THEN HIGH LED2
GOto SINGLE
IF SNGL=0 THEN LOW LED2
IF RPPL=1 THEN HIGH LED1
GOTO RIPPLE
IF RPPL=0 THEN LOW LED1
GOTO KONTROL
'================================
SINGLE:
If BTTN =1 Then 'Butona Basıldı. 
x=x+1 
EndIf 
If x>4 Then 
x=0 
EndIf 
'=========================================
If x=1 Then 
STA1 =1 
Else 
STA1 =0 
EndIf
pause 50
'========================================= 
If x=2 Then 
STA2 =1 
Else 
STA2 =0 
EndIf
pause 50
'=========================================
If x=3 Then 
STA3=1 
Else 
STA3=0 
EndIf
pause 50 
'=========================================
If x=4 Then 
STA4=1 
Else 
STA4=0 
EndIf
pause 50

'=========================================
GoTo KONTROL
'=========================================
RIPPLE:
If BTTN =1 Then 'Butona basınca 
PAUSE 20:STA1=1:PAUSE 20:STA1=0
PAUSE 20:STA2=1:PAUSE 20:STA2=0
PAUSE 20:STA3=1:PAUSE 20:STA3=0
PAUSE 20:STA4=1:PAUSE 20:STA4=0
ENDIF
GOTO KONTROL


Kod bu arkadaşlar. Amacım Single durumunda portb.5 teki butona her basışta basılı tuttuğum sürece  mesela ilk lamba yanacak bırakınca sönecek. tekrar bastığımda ikinci lamba yanacak bırakınca sönecek. Ve Riple durumunda butona bastığım sürece 1 den 4 e kadar lambalar sırayla yanıp son lambadan sonra duracak.
[/URL][/img]
Kimine göre kralım kimine göre yalanım… Herkes rahatına baksın, ben adamına göre adamım..

Veli B.

Bu linkte bir dsn var. Ugras biraz olmazsa degisiklikleri beraber yapariz.  
http://rapidshare.com/files/100079797/solidus.rar.html

solidus

Sevgili katana,
Linkteki dosyayı inceledim fakat tam anlayamadım. Neredeyse 1 haftadır yukarıdaki kodlarla uğraşıyorum. Bir de sıkıntım portb1 deki lamba yanıyor port b 2 deki lambayı istediğim gibi yakamadım..
Kimine göre kralım kimine göre yalanım… Herkes rahatına baksın, ben adamına göre adamım..

Veli B.

Simulasyonda istedigin gibi calismiyor mu?
Sorun nedir anlayamadim, aciklar misin?

solidus

simülasyonda gosub kullanamıyorum. proteus 7.2.2 denmi kaynaklanıyor pbp 2.50 denmi anlayamadım..
BASLA:
IF SNGL=1 THEN LED2=1
GOSUB SINGLE
IF RPPL=1 THEN LED1=1
GOSUB RIPPLE

şeklindeki kodda şartlar oluştuğunda single yada ripple döngüsüne dallanması gerekmezmi ? Bu şekilde sadece single döngüsü çalışıyor. Riple döngüsüne dallanmıyor.
Kimine göre kralım kimine göre yalanım… Herkes rahatına baksın, ben adamına göre adamım..

Veli B.

If then else yordamını yanlış kullanıyorsunuz bu durum için. Ete' nin hazırlamış oldugu ders notlarını okumanızı öneririm.
Yukarı da vermiş oldugunuz şekilde kullanılırsa dallanma kısmı bağımsız çalışır, yani if bloğu içinde işlem görmez. Then den sonra ki kismi alt satıra indirip end if ile sonlandırın.

solidus

BASLA:

IF SNGL=1 THEN 
LED2=1
endif
GOSUB SINGLE
IF RPPL=1 THEN 
LED1=1
endif
GOSUB RIPPLE

şeklinde de denedim sonuç aynı yapabileceğimiz bişey varmı acaba ?
Kimine göre kralım kimine göre yalanım… Herkes rahatına baksın, ben adamına göre adamım..

Veli B.

Tam olarak yapmak istediğiniz senaryoyu yazar misiniz?
Sanirim olay sadece bir butona basarak 4 farkli çikisi kontrol etmek değil.

solidus

Tam olarak yapma çalıştığım iş bir butonla iki ayrı modda 4 tane çıkışı kontrol etmek. single durumunda her basışta tek lamba yanacak 1,2,3,4 gibi.. Ripl durumunda ise basılı tuttuğum sürece çıkışlar sırayla aktif olacak. Her iki modda da 4. lamba inaktif olduğunda işlem sona erecek..
Kimine göre kralım kimine göre yalanım… Herkes rahatına baksın, ben adamına göre adamım..

Veli B.

ripl durumunu anlamadım? sırayla aktif olacak derken ne kast ediyorsunuz.
single ve ripple çalışma durumuna ne karar verecek tek buton var ise?

solidus

Bir önceki sayfada şemayı verdim incelme şansınız oldumu bilemiyorum. Mod seçimi basit çift kontaklı bir sw ile yapılıyor. buton ise mod sw. durumuna göre farklı işlevler yükleniyor. ripl modunda butona basılı tutulduğu sürece çıkışlar sırayla aktif oluyor. Single modda ise her basışta bir çıkış aktif oluyor. Yani olması isteniyor..
Kimine göre kralım kimine göre yalanım… Herkes rahatına baksın, ben adamına göre adamım..

forsa1975

tus var bit
eskitus var bit
cikis var byte
trisa=%11111111
trisb=%00000000
eskitus=0
single var porta.0' mod seçimi
cikis=1
basla:
if porta.1=0 then portb=0
if single=1 then
   if  porta.1=eskitus then ' tusta değisiklik olmadıysa degeri 0 dır
    
   else' eğer tus 1 oldusa bu deger eski tus degiskenine yuklenerek birdahaki dongude 1 gelmeye devam ediyorsa tus degiskenini 0 yapsın
      eskitus=porta.1
     if porta.1=1 then cikis=cikis*2
     if cikis=16 then cikis=1
      portb=cikis

   endif
else
    if porta.1=1 then 
    cikis=cikis*2
   if cikis=16 then cikis=1
        portb=cikis
        pause 100' basılı kaldığında sürekli değişecek değişme süresi =100ms
   else
        portb=0
   endif
endif


goto basla
end


yukarıdaki kodun amacı butonu 1 kez okur ve elinizi butondan çekmeden tekrar buton bilgisi okumaz . Gecikme koymaya gerek kalmaz. Çok kullanışlıdır.

ete

Programla ilgili detay sonradan gelince bu tartışma ve örnek programlarda uzadıkça uzuyor hali ile. En baştan bu konu tam olarak açıklansa idi iş buraya kadar uzamaz idi. Tuşa basılı tutulduğu sürece ledin yanık kalması ve tuşu bırakınca sönmesi önemli bir detay ve son ana kadar sen bu detayı vermedin. Alkışlıyorum.

Verdiğin devre çiziminde de hatalar var. Öncelikle hemen belirteyim.
Tuşları ve anahtarları bir porta ve ledleride diğer porta almak varken neden yarısı bir yerde diğer yarısı başka yerde yerleştirilmiş. Bunuda bir açıklarsan sevinirim.

Ayrıca Tuş ve anahtarları bağladığın PortB nin güzel bir özelliği var. Bu özellik pinlerin dahili pullup dirençlerinin olmasıdır. Bu özellik nedeni ile genelde bu porta bağlı olan tuş ve anahtar gibi elemanların kapanması durumunda port pinine LOW uygulanır ve böylece dahili pull up lar nedeni ile HIGH da bekleyen port pini LOW a döner ve sende programla kolayca tuşa basıldığını anlarsın.  Bu özelliğe karşılık sen tuşa basılınca port pinine HIGH uygulamışsın. Ancaaaaak. Port Pinlerini LOW da tutman lazımki tuşa basılınca HIGH olması durumunda tuşa basıldığını anlayabilesin. Halbuki senin resimde PULL-DOWN (LOWa çekme) konusunda bir eleman göremedim. Bu şekilde programın düzgün çalışmayacaktır. Şayet aynı devre şemasını kullanıyorsan yaşadığın abuk subuklukların başlıca sebebi bu olsa gerek.

Tavsiyem, Tuş ve anahtarları PORTA ya taşı ve Ledleri de PORTB ye taşı.
Tuş Sİstemini ister Pull-up la ister Pull-Down la çalıştır. Fark etmeyecektir. Ancak tuş ve anahtar pinlerini mutlaka bir yöne çekmeli ve tuş kapanınca tersi olacak şekilde önlem almalısın.
Anahtar ve tuşlar portA da olduğunu ve ledlerinde PortB.0 dan itibaren yerleştirilmiş olduğunu varsayarak bir kod yazdım. (628 ile) Denemesinide yaptım . Tam istediğin gibi çalışıyor. Karar senin. İllaki yayınladığın devre şemasına uygun bir kod istersen onuda yaparım. Ancak bunu istemeden önce iyice bir düşün derim.

Doğru kod aşağıdadır.

PORTA=0:TRISA=1
PORTB=0:TRISB=0
OPTION_REG.7=0
cmcon=7
@ DEVICE pic16F628
@ DEVICE pic16F628, WDT_ON
@ DEVICE pic16F628, PWRT_ON
@ DEVICE pic16F628, PROTECT_OFF
@ DEVICE pic16F628, MCLR_OFF
@ DEVICE pic16F628, INTRC_OSC_NOCLKOUT

SAYI var byte

basla:
 IF PORTA.0=0 THEN
        IF SAYI=0 THEN
           SAYI=1
        ELSE
           SAYI=SAYI*2
           IF SAYI=64 THEN SAYI=1
        ENDIF
        while PortA.0=0
        portb=SAYI
        wend
      ENDIF
      PORTB=0
      PAUSE 50
      GOTO BASLA 
      end


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

solidus

Kimine göre kralım kimine göre yalanım… Herkes rahatına baksın, ben adamına göre adamım..