Set-Reset

Başlatan yambaxx, 21 Ekim 2011, 15:54:42

yambaxx

Merhaba,
Elimde bir buton ile bir ledi yakıp söndürmeye yarayan bir blok var,

*******************************************************
Device = 16F876a
TRISb=0          'çıkıs olarak ayarlandı
TRISa=%00000001  '0.bit 1 digerleri 0

symbol  led=portb.0  'symbol degiskenine tus adı veridi
symbol  tus=porta.0  'symbol degiskenine led adı veridi

basla:
    if tus=1 then    'tus 1 ise yanı anahtar kapalı ise
        high led     'ledi yak
    else             'değilse
        low led      'ledi söndür
    endif            'if sorgulama sonu
        goto basla   'tekrar basla
    end              'son
**************************************************


1-Benim bunu 8 buton ve 8 lede çıkarmam gerekiyor,(her butona karşılık bir led)
2-bu butonlardan birine 1sn den  uzun basıldığında o led sürekli yanmalı aynı butona basıldığında ise sönmeli (kalıcı set olayı)
Halbu iken yukarıdaki kodda nasıl bir düzenleme yapmalıyım ki,
istediğime ulaşabileyim....
(Tüm forumu neredeyse aradım ama bir çözüm bulamadım lütfen yardım edin)

Saygılarımla

Kabil ATICI

Öncelile bu programlama dilini tam bilmiyorum ancak programla ilgili yardımcı olabilirim Boşlukları kendin tamamlaman gerekecek.
Büyük oranda çözüm verilen programda var...

LED çıkışı için birşey yapmana gerek yok. Zaten B portu çıkış olarak atanmış.

TRISa=%00000001  '0.bit 1 digerleri 0
satırı giriş uçlarını tanımlıyor. Bir tane buton olduğu için  bir tane giriş tanımlanmış dersem, aslında kaç tane giriş istersen  o bitin değerini 1 yap. (butonların b u porta bağlı.

symbol  led=portb.0  'symbol degiskenine tus adı veridi
bu satır led ve bağlı olduğu port ve biti tanımlanmış. eğer başka ledler istiyorsan kolaylık olması için ledlere numara ver (led1,led2,led3...) ve istediğin ledi port ve bitini tanımlayarak ekle.
symbol  led0=portb.0
symbol  led1=portb.1
.
.
gibi...

symbol  tus=porta.0  'symbol degiskenine led adı veridi
bu satırda bağlanan tuşun portu ve port numarası tanımlanmış. aynı LEDlerde olduğu gibi tanımla
symbol  tus0=porta.0
symbol  tus1=porta.1
.
.
gibi.
burada sana tam olarak yardımcı olamayacağım bölüm geliyor. tuş basıldıktan sonra  led durumunu hafızasında tutacak değişkenlere ihtiyacın var.bu değişkenleri aslında buton veya led gibi tanımlanaları gerekiyor.
burada  deg1,deg2... gibi tanımlaadığımıızı varsayalım.

if tusx=1 then    'tus 1 ise yanı anahtar kapalı ise
(bekleme)
if tusx=1 then    'tus 1 ise yanı anahtar kapalı ise
     if degx=1 then
        degx=0
        high ledx     'ledi yak
    else             'değilse
        degx=1
        low ledx      'ledi söndür
    endif            'if sorgulama sonu
endif            'if sorgulama sonu
endif            'if sorgulama sonu


buradaki x ile tanımlanan tuş,led ve değişken numarasıdır.
Yani sekizli grup olacaksa 8 tane bu gruptan alt alta olacak.

sana yardımcı olamayacağı konuda
(bekleme)
ile ilgili koddur.
Buradada bekleme ile ilgili alt betik oluşturacaksın  ve bu satırlardan bu alt betiği çağıracaksın ya da   bekleme ile ilgili  betiği doğrudan bu satıra yazacaksın.

programın altına da
      goto basla   'tekrar basla
sürekli döngü için


    end              'son
bunu açıklamaya gerk var mı?
kolay gelsin...
aslında programı biraz incelersen sen de yapabilirdin!
ambar7

Kabil ATICI

    if tusx=0 then   
         pause 1000
   if tusx=0 then
              toggle ledx
         endif
       endif

her tuş için LEDi yakıp söndürür ve 1saniye bekleme ile.
aslında site içinde varmış. ben de öğrenmiş oldum
ambar7

yambaxx

yardımınız için teşekkür ederim ama konu biraz daha karışık hale geldi şimdi benim açımdan :(
konuyla ilgili çalışan örnek kodlar olsa sanırım biraz daha içinde çıkılabilir olurdu :)

Saygılarımla...

yambaxx

Herkese merhabalar,
Bayağı bir uğraştıktan sonra her butona bir led denk getirip butona basınca ledi yaktırmayı başardım,
8 buton 8 led i kontrol eder oldu (aşağıdaki koddan görebilirsiniz)
Şimdi bana lazım olan;

Şu anda ben porta.1 deki butona basınca portb.1 deki ledi yakabiliyorum bu led sönükken ben porta.1 deki butona basılı tutarsam led sürekli yanık kalsın sonra porta.1 deki butona tekrar basınca led sönsün
yani 1 butona 3 görev,
görev1) kısa basışta çıkış verecek (kilitleme olmayacak)
görev2) uzun basınca çıkışı set edip kilitleyecek
görev3) eğer çıkış set ise (led yanıyor ise) çıkışı reset edecek (led sönecek)
aynı işi 8 buton içinde yapacağım....

Sorum şu ben bu basılı tutunca daimi çıkışı set etme işini nasıl yaparım ve daimi set iken resetleme işini
Yardım edebilirseniz sevinir, şimdiden teşekkür ederim...

Device = 16F876a
ALL_DIGITAL = TRUE
PORTB_PULLUPS = ON 

TRISB=%00000000  'cikis olarak ayarlandi
TRISA=%00000011  'giris olarak ayarlandi
TRISC=%00111111  'giris olarak ayarlandi
portb=0

symbol  led0=portb.0  'symbol degiskenine tus adi veridi
symbol  led1=portb.1  'symbol degiskenine tus adi veridi
symbol  led2=portb.2  'symbol degiskenine tus adi veridi
symbol  led3=portb.3  'symbol degiskenine tus adi veridi
symbol  led4=portb.4  'symbol degiskenine tus adi veridi
symbol  led5=portb.5  'symbol degiskenine tus adi veridi
symbol  led6=portb.6  'symbol degiskenine tus adi veridi
symbol  led7=portb.7  'symbol degiskenine tus adi veridi

symbol  tus0=porta.0  'symbol degiskenine led adi veridi
symbol  tus1=porta.1  'symbol degiskenine led adi veridi
symbol  tus2=portc.0  'symbol degiskenine led adi veridi
symbol  tus3=portc.1  'symbol degiskenine led adi veridi
symbol  tus4=portc.2  'symbol degiskenine led adi veridi
symbol  tus5=portc.3  'symbol degiskenine led adi veridi
symbol  tus6=portc.4  'symbol degiskenine led adi veridi
symbol  tus7=portc.5  'symbol degiskenine led adi veridi

basla:
    if tus0=1 then    'tus 1 ise yani anahtar kapali ise
        high led0     'ledi yak
    else             'degilse
        low led0      'ledi söndür
    endif            'if sorgulama sonu
                      'tekrar basla


    if tus1=1 then    'tus 1 ise yani anahtar kapali ise
        high led1     'ledi yak
    else             'degilse
        low led1      'ledi söndür
    endif            'if sorgulama sonu
                       'tekrar basla
        

    if tus2=1 then    'tus 1 ise yani anahtar kapali ise
        high led2     'ledi yak
    else             'degilse
        low led2      'ledi söndür
    endif            'if sorgulama sonu
                      'tekrar basla        
        

    if tus3=1 then    'tus 1 ise yani anahtar kapali ise
        high led3     'ledi yak
    else             'degilse
        low led3      'ledi söndür
    endif            'if sorgulama sonu
                       'tekrar basla        
        

    if tus4=1 then    'tus 1 ise yani anahtar kapali ise
        high led4     'ledi yak
    else             'degilse
        low led4      'ledi söndür
    endif            'if sorgulama sonu
                       'tekrar basla        
        

    if tus5=1 then    'tus 1 ise yani anahtar kapali ise
        high led5     'ledi yak
    else             'degilse
        low led5      'ledi söndür
    endif            'if sorgulama sonu
                        'tekrar basla        
        

    if tus6=1 then    'tus 1 ise yani anahtar kapali ise
        high led6     'ledi yak
    else             'degilse
        low led6      'ledi söndür
    endif            'if sorgulama sonu
                      'tekrar basla        
        

    if tus7=1 then    'tus 1 ise yani anahtar kapali ise
        high led7     'ledi yak
    else             'degilse
        low led7      'ledi söndür
    endif            'if sorgulama sonu
        goto basla   'tekrar basla        
       
    end              'son

Maxim

çok basit
butona basınca ayrı bir sayıcı başlat
işte AA sayıcısı olsun

butona basılı tuttuğun sürece 1 artsın
if AA=100 then porta.1=1 dersen porta.1 high olur ve öyle kalır

yambaxx

Sayın Maxim öncelikle cevabınız için sağolun,
Pic programlamakta yeni olduğum için bu dediğinizi kod'a dökülmüş bir örnek ile gösterebilirseniz,
daha kolay halledebilirim...  ???

Maxim

#7
düşündüğümden daha uzun kod gerekti
mutlaka daha basit yolları vardır ama dün akşam geç saatte benden bu kadarı çıktı.
bu kod sadece 1. led için

kodlar proton+, Picbasic olarak çevirin
delayms yeride pause
dim abc as bit yerine abc as var bit gibi işte kolay .


   Symbol Tus0=PORTA.0
   Symbol Led0=PORB.0
   Dim Tusset1 As Bit
   Dim Tusset2 As Bit
   Dim Tussay As Byte

loop:

   '1- tusa basınca led yanacak, çekince led sönecek
   '2- tusa basınca led yanacak, elini çekmeden beklersen led hep yanık kalacak(çektikten sonrada yanık kalacak)
   '3- eğer led sürekli yanık ise tuşa basınca sönecek
   '* tuş girişleri pull-down diye gözüküyor, yani tuşa basınca giriş high oluyor? ona göre yaptım.
   
   BASLA0:
   If Tus0=1 And Tusset1=0 Then
   DelayMS 50
   Inc Tussay
   High Led0
   If Tussay>25 Then ' Bu değer uzun basık kalma süresini belirler
   A0:
   Tusset1=1
   Tusset2=1
   If Tus0=0 Then GoTo BASLA0
   DelayMS 10
   GoTo A0
   EndIf
   
   Else
   If Tusset1=0 Then 
   Low Led0
   Tussay=0
   EndIf
   EndIf
   
   If Tus0=1 And Tusset2=1 Then
   DelayMS 50
   Low Led0
   Tusset1=0
   Tusset2=0
   Tussay=0
   EndIf

GoTo loop


edit:
'2- tusa basınca led yanacak, elini çekmeden beklersen led hep yanık kalacak
bu yazıyı ekledim : (çektikten sonrada yanık kalacak)

Mujdat117

#8
merhaba pbp konusunda çok bilgili olduğumu söyleyemem ama
şöle bir algoritma kullanılabilir. buton basma süresini hesaplamak için
birtene BTNcNT değişken tanımlarsınız belirli bir süre pause ettikten sonra
mesela 10sn  BTNcNT değerini 1 artırısınız. butona basılı tutulduğu sürece bu işlem devam eder. bırakıldıgında  BTNcNT değeri 10 ise (süre farazidir değiştirlebilir) SET_BUTTON adındaki başka bir değiken yardımyla hangi ledin set / reset(toggle komutu kullanılarak durumu her seferinde değiştirilerek) edileceğini belirleyerek ledlerin bağlı olduğu porta bu SET_BUTTON değeri gönderilir bu set durumdaki ledlerin yanmasını sağlar. ve basıp bırakılan butonlar yanmakta olan ledlerin durumunu etkilemez ve aynı şekilde belirli bir süre basılıp bırakıldığında aynı led söner.
basla:
BTNcNT=0'butonnu basılma süresini hesaplayacak değişkeni sıfırla
BTN0	IF tus0=1 then    'tus 1 basıldımı 
	PAUSE	10	'basıldı ise bir süre bekle
	INC	BTNcNT     'basılı kalma süresini hesapla
	high led0  'ledi yak   'basılı oldugu sürece ledi ya
IF	tus0=1 THEN GOTO	BTN0	'tus basılı ise başa dön ve tekrar kontrol et taki bırakılanakadar.
	IF	BTNcNT>10 THEN	TOGGLE	SET_BUTTON.0 'tus bırakıldı ise süreyi kontrol et ve ledin durumunu gerekiyorsa değiştir.
	LED_PORT=SET_BUTON'set durumda olan ledleri porta yazdır.
        
    else             'süre dolmamışsa
        low led0      'ledi söndür
    endif            'if sorgulama sonu
   
şeklinde olablir.
Ayinesi iştir kişinin lâfa bakılmaz.Şahsın görünür rütbe-i aklı eserinde

ete

#9
Bu olayı basitten zora doğru düşünmekte yarar var.
Asıl konuya geçmeden bir soru sormam gerek. Kalıcı set edilmiş bir pini aynı butona ne kadar basınca LOW yapacağız? Burası açık değil.
Çünki o pini set de bırakmak için 1 sn müddetle basılı bıraktık. Hemen ardından yine 1 sn süre ile basarsam yine sönecekmi yoksa yanmış ledi söndürmek için butona basılma süresi  faktörü göz ardı mı edilecek. Burayı açarsan sonuca daha kolay ulaşırız.

Şimdi asıl konuya dönelim. A portuna bağlanmış Butonları (LOW'a çekilmişler) kullanarak B portuna bağlı ledleri yakacağız.
Bunun için basit iki komut işimizi görebilir.
Normalde buton portu olan A portu low da yani PORTA=0 da bekler.
TUS=PORTA dediğiniz zaman bütün butonları okuyup TUS değişkenine koymuş olursunuz. Hatta bunu Symbol TUS=PORTA dediğiniz zaman direk symbol olarak tanımlamış olursunuz. Geriye onu kontrol etmek kalır.
PORTB=TUS derseniz hangi butona basılmış ise ona karşılık gelen led de yanar. Bu bir otomatik atama işidir.
PORTA daki girişi aynen PortB ye aktarmış oluruz.
yani programı şöyle yazsak;
BASLA:
PORTB=TUS
hiç bir kontrol rutini yazmadan direk basılan tusa karşılık gelen ledi yakmış oluruz. Elimizi tus dan çekincede led sönecektir elbette.
Bu durumda ilave kod yazarak kalıcı set etme işini halledebiliriz.
İzahat yazmaktansa kodu vermek daha açıklayıcı olacaktır herhalde.
Tek açıklamam gereken şey önceden 1 sn süre geçtiği için set edilmiş bir pinin low yapılması için yeniden 1sn süre ile basılması gerektiğidir.
Ete

@ DEVICE pic16F628A                      'işlemci 16F628                                
@ DEVICE pic16F628A, WDT_Off              'Watch Dog timer açık
@ DEVICE pic16F628A, PWRT_ON             'Power on timer açık
@ DEVICE pic16F628A, PROTECT_OFF         'Kod Protek kapalı
@ DEVICE pic16F628A, MCLR_off            'MCLR pini kullanılMIYOR.
@ DEVICE pic16F628A, INTRC_OSC_NOCLKOUT  'Dahili osilatör kullanılacak 

DEFINE OSC 4
TRISA=255
TRISB=0
CMCON=7
SAYAC VAR WORD 56
ESKI VAR BYTE  58
YENI VAR BYTE  59
TUS  VAR BYTE  60
ESKI=TUS
BASLA:
      TUS=PORTA                '8 adet TUS un değerini okuyup TUS isimli değişkene yerleştiriyoruz.
      IF TUS>0 THEN           'tuslardan birisine basılmış ise Tus değeri sıfırdan büyük olacaktır
        PORTB=ESKI | TUS   'basılan tusa kaşlık gelen led'i yakmak için eski yakılmış ledleride göz önüne alıyoruz. (ESKI or  TUS)
        YENI=tus                  'YENI=TUS şeklinde tus değerini YENI değişkenine yerleştirdik 
        SAYAC=0                  'süre sayacını sıfırlıyoruz
        WHILE TUS>0           'tusa basılı tuttukça ,
          tus=PORTA             ' TUS ları oku 
          PAUSE 1                 '1 ms bekle
          SAYAC=SAYAC+1    'sayac değerini 1 artır
          IF SAYAC=1000 THEN CIK 'sayac=1000 olunca 1 sn geçmiş olacak ve CIK etiketine gidilecek.
        WEND                         
      ENDIF                  
      PORTB=ESKI        '1 sn geçmeden tuşu bırakırsak eski tus değerini yeniden PortB ye veriyoruz.
      GOTO BASLA       'tekrar basla etiketine gönderiyoruz.
      
CIK:   '1 sn geçince buraya geliyor program
      ESKI=ESKI ^ YENI    'eski portB değerine Yeni basılan tusu da ekliyoruz veya XOR ile  TOGGLE yaparak yanmışı söndürüyoruz.
      PORTB=ESKI '  Değişen durumu yeniden portB ye yazıyoruz.
      YENI=0
      WHILE PORTA>0:wend   'tusa basılı tuttuğumuz müddetçe bekle.
      GOTO BASLA


Şayet önceden set edilmiş bir pini kısa süreli karşılık butonuna basarak LOW yapmak isterseniz yalnızca 2 satır kod eklenmesi gerekiyor.
Eklenecek kod ve yerini aşağıdaki satırlardan anlayabilirsiniz.
          IF SAYAC=1000 THEN CIK '
        WEND
        IF (ESKI & YENI)=YENI THEN 
           PORTB=(ESKI ^ YENI)
           ESKI=PORTB
        ENDIF  
      ENDIF
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

yambaxx

#10
Sayın Maxim,Mujdat117 ve ete cevaplarınız için teşekkür ederim.Verdiğiniz kodları hemen denemeye geçiyorum...

Bu arada Sayın ete'nin cevap aradığı,
Alıntı YapAsıl konuya geçmeden bir soru sormam gerek. Kalıcı set edilmiş bir pini aynı butona ne kadar basınca LOW yapacağız? Burası açık değil.
soruyu aşağıda açıklayayım...
Aşağıda bahsettiğim 1 buton, 3 görevi için,
Alıntı Yap
görev1) kısa basışta çıkış verecek (kilitleme olmayacak)
görev2) uzun basınca çıkışı set edip kilitleyecek
görev3) eğer çıkış set ise (led yanıyor ise) çıkışı reset edecek (led sönecek)
görev1 'de butona basılıp çekilecek ve led butona basıldığında yanmış buton bırakıldığında sönmüş olacak,
görev2'de butona (örneğin 1 sn kadar basılı tutup butonu bıraktığımızda led sürekli yanık kalacak)
görev3'te ise set konumundaki ledi süren butona basıp bırakırsak (-ki süre önemli değil bas-çek şeklinde olması daha iyi olur) set olan led sönecek...

Saygılarımla...

ete

#11
Aslında uzun basılıp set edilen pinin Tuş'a Kısa basarakmı yoksa yine uzun basarakmı reset edileceğini sormuştum.
Verdiğim ilk örnek Tuşa uzun basarak reset edilecek şekilde. Tuşa kısa basarak reset edilecek ise ikinci kod parçasını birinciye ilave etmek gerekiyor.  İkinci kod parçasında ufak bir kusur varmış. Onu düzelttim. Yenisine bakın.

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

yambaxx

Öncelikle cevabınız için teşekkür ederim...
Sayın ete'nin verdiği kodları deneme fırsatım oldu,
proton ve pbp editör ile,
proton da,
CMCON=7
SAYAC VAR WORD 56
ESKI VAR BYTE  58
YENI VAR BYTE  59
TUS  VAR BYTE  60

var yerine dim kullanın dedi onu da düzelttim ve
CMCON=7
SAYAC Dim WORD 56
ESKI Dim BYTE  58
YENI Dim BYTE  59
TUS  Dim BYTE  60

şekline getirdim
Bana verdiği hatalar sırasıyla,
error line 21: Variable 'CMCON' not found!
error line 22: Variable 'SAYAC' not found!
error line 23: Variable 'ESKI' not found!
error line 24: Variable 'YENI' not found!
error line 25: Variable 'TUS' not found!
error line 26: Variable 'ESKI' not found!
oldu....


pbp de ise,
Error[122]   C:\...\DESKTOP\TK628.ASM 18 : Illegal opcode (PIC16F628A)
Error[122]   C:\...\DESKTOP\TK628.ASM 19 : Illegal opcode (PIC16F628A)
Error[122]   C:\...\DESKTOP\TK628.ASM 20 : Illegal opcode (PIC16F628A)
Error[122]   C:\...\DESKTOP\TK628.ASM 21 : Illegal opcode (PIC16F628A)
Error[122]   C:\...\DESKTOP\TK628.ASM 22 : Illegal opcode (PIC16F628A)
Error[122]   C:\...\DESKTOP\TK628.ASM 23 : Illegal opcode (PIC16F628A)
oldu...

Bunları nasıl düzeltebilirim acaba?

Saygılarımla...

ete

Aşağıdaki linkten proje dosylarını (Bas - HEX ve DSN) yükleyip ordan çalıştırabilirsin.
Kod un protona çevrilmesinde yardımcı olamayacağım maalesef.

Ete

http://dl.dropbox.com/u/25364674/TUS_LED.rar
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

yambaxx

Vaktinizi ve bilginizi paylaştığınız için çok teşekkür ederim Sayın Ete,
proteus simulasyonuna göre aradığım tamda buydu...

:)