avatar_kotan04

buton komutu

Başlatan kotan04, 20 Aralık 2012, 22:21:28

efehurkan

Merhaba ben yeni öğrenmeye çalışıyorum fakat bir tülü çözemediğim bir konu var,  buton1 e basıldığında led1 3sn yanık kalacak, buton2 e basıldığında led2 3sn yanık kalacak, .... şeklinde yapmaya çalıştım fakat buton1 e basıldığında led1 3sn yanık kalıyor, 3sn süre sonuna kadar diğer butonlara basılsada led ler yanmıyor, kodlarım aşağıdaki gibi yardımlarınızı rica ederim.



TRISA=%11111111
TRISB=%00000000
PORTA=0
PORTB=0
   
BASLA: 
                     
IF PORTA.0=0  THEN       
HIGH PORTB.0                                                 
WHILE PORTA.0=0
PAUSE 3000                                                 
WEND
LOW PORTB.0
ENDIF

BASLA1: 

IF PORTA.1=0 THEN           
HIGH PORTB.1                                                   
WHILE PORTA.1=0
PAUSE 3000                                                 
WEND
LOW PORTB.1
ENDIF

BASLA2:   

IF PORTA.2=0 THEN             
HIGH PORTB.2                                                   
WHILE PORTA.2=0
PAUSE 3000                                                 
WEND
LOW PORTB.2
ENDIF 
   
BASLA3:                   
       
IF PORTA.3=0 THEN             
HIGH PORTB.3                                                   
WHILE PORTA.3=0
PAUSE 3000                                                 
WEND
LOW PORTB.3
ENDIF
     
BASLA4:

IF PORTA.4=0 THEN             
HIGH PORTB.4                                                   
WHILE PORTA.4=0
PAUSE 3000                                                 
WEND
LOW PORTB.4
ENDIF 

BASLA5:

IF PORTA.5=0 THEN             
HIGH PORTB.5
WHILE PORTA.5=0
PAUSE 3000                                                 
WEND
LOW PORTB.5
ENDIF

BASLA6:

IF PORTA.6=0 THEN             
HIGH PORTB.6                                                 
WHILE PORTA.6=0
PAUSE 3000                                                 
WEND
LOW PORTB.6
ENDIF
 
BASLA7:     
   
IF PORTA.7=0 THEN             
HIGH PORTB.7
WHILE PORTA.7=0                                                 
PAUSE 3000
WEND                                                 
LOW PORTB.7
ENDIF       
             
PAUSE 30                                       
GOTO BASLA
GOTO BASLA1
GOTO BASLA2
GOTO BASLA3
GOTO BASLA4
GOTO BASLA5
GOTO BASLA6
GOTO BASLA7

                             
END

MS_59

#31
pause 3000 dediğin zaman program bu süre bitene kadar hiçbir işlem yapamaz sürenin bitmesini bekler sonra alttaki satırı icra eder bu şekilde diğer butonların çalışmaması normal hangi işlemciyi kullanıyorsun ona göre yardımcı olalım     
mehmet

ete

#32
Program bu hali ile kusurlu olsada istediğini tam olarak yapıyor. Ne demişsin bir bakalım "3sn süre sonuna kadar diğer butonlara basılsada led ler yanmıyor," halbuki yanıyor. Tek yapman gerken sabırla sürenin bitmesi başka bir şey gerekmez.
Ama led'in biri yanarken diğer butonlar çalışır halde olsunlar diyorsan o başka. İstediğin bu mudur emin olamadım.

Basic programları satır tarar. Bir satırdaki işler bittikten sonra bir alt satıra geçer.
Ama alt satırda programı tekrar başa yönlendirecek bir komut var ise daha alt satırlara program geçemez.
Yazdıklarına bakarsak;
PAUSE 30
GOTO BASLA
GOTO BASLA1
GOTO BASLA2
GOTO BASLA3
Görüldüğü üzere pause 30 komutundan sonra bir alttaki komut icra edilir. O komut da GOTO BASLA komutu olduğuna göre program her seferinde pause 30 komutuna ve bir sonraki Goto Basla satırına gelir ve basa döner. Dolayısıyla Goto Basla1 satırına hiç bir zaman ulaşamaz. Oraya ulaşması için yol yok anlayacağın. Tabiiki altındaki satırlarda aynı konumda ulaşılamaz durumdalar. Boşuna yazmışsın onları. Zaten gerek de yok aslında zira Goto basla komutu onlarınhepsinin yerine geçmektedir. Program bir defa en başa yönlendirildikten sonra hangi tusa basılmış ise o kumut uygulanır. Diğer IF satırları es geçilir.
Bu nedenle programın bu hali ile çalışıyor dedim.

Tabiiki en güzeli tuşların bağımsız sürelerle bağlı oldukları ledleri yakmaları ve söndürmeleridir.
Bir butona basınce bir ledi yakıyorum ama hemen ardından bir başka ledi aktif etmek için neden 3 sn müddetle ilk yaktığım ledin sönmesini bekleyeyimki? Bu işin doğrusu bütün buton ve ledlerin bağımsız çalışmasıdır.
Peki bu nasıl yapılabilir?. Şöyle bir düşününce ilk akla gelen bir timer kesmesi kullanarak zaman saydırmak ve süre bitiminde ledi söndürmek. Bu iş için TMR0 sayacını her 1ms de bir  kesme oluşturarak kullanabiliriz.
O halde  3 sn için sayacın 3000'e kadar sayması yada 3000 den başlayıp sıfır oluncaya kadar geri sayması gerekir. Zira 3sn = 3000 ms dir.  Peki tuşlara aynı zamanlarda basmayacağımıza göre tek sayaçla bu iş olmayacak demektir.
Örnek vermek gerekir ise 1 nolu tuşa bastım ve led yandı. 1 nolu led için saymaya başladı diyelim . Ama 1 sn sonra ikinci butona basmış ise birinci söndükten 1 sn sonra ikincinin sönmesi gerekecektir. Bu nedenle kaç tane led var ise o kadar sayacımız olması gerekir. TMR0 her 1 ms de bir kesme oluşturduğuna göre bütün ledler için ayrıca sayaç çalıştırmaktansa aktif olanları seçip yalnızca onların sayaçlarını çalıştırmak akıllıca olacaktır.
Şimdi bu düşündüklerimizi program haline getirelim isterseniz.
Öncelikle TMR0 kesme oluşturmak için INTCON=%10100000 şeklinde komut vermek gerekiyor. En soldaki "1" Global kesmeleri açıyor. Sonraki "1" ise TMR0 kesmesini açmaktadır.
Ne demiştik her 1 ms de bir kesme oluşturacağız. Bu iş için TMR0 sayacını 7 den başlatacağız ve bölme oranımız ise 1/4 olacaktır. Hesap yapalım 256-7=249us  her seferinde sayılacak demektir. sayac her 4 işlemci pulsinde bir puls sayacağı için bunu 4 ile çarpmamız gerkecektir. 249*4=996 us eder 1000us = 1ms dir aslında 4us eksik kalıyor ama komut gecikmeleri zaten bu eksikliği fazlası ile kapatacaktır. O halde önce Option registerinden bölme oranımızı 1/4 olarak ayarlayalım.
Option_Reg=%00000001
Kesme oluşunca KESME etiketine programı yönlendirmek için,
ON INTERRUPT GOTO KESME   komutunu verelim.
TMR0=7 vererek sayacın 7 den başlamasını sağlayalım. Böylece işlem tamamdır.
Şimdi kesme içinde ne yapacağız bunları inceleyelim. Ancak buna geçmeden butona basılınca ne yapacağız ona bakalım.

IF PORTA.0=0 THEN   'Bir Butona basılınca;
PORTB.0=1           'ilgili led'i yak burada HIGH PORTB.0 komutu da aynı işi yapar ancak 2 byte fazladan harcar. Çünki o komut önce ilgili biti çıkış yapar sonra çıkışı HIGH yapar. 
SURE[0]=3000  'Sıfır nolu bite ait süreyi tanımlıyoruz.                                           
ENDIF
hepsi bu kadar. Artık orada ayrıca while wend komutuna gerek yok çünki zaten 3 sn sonra led sönecek.

Şimdi kesme kısmına geçelim.
DISABLE
KESME:
      For I=0 to 7  'öncelikle 0-7 arasında bitleri test etmek üzere döngü kuruyoruz.
        IF PORTB.0[I]=1 THEN  'şayet bitlerden birisi set edilmiş ise
          SURE[I]=SURE[I]-1     'ona ait süre değişkeninden bir çıkartıyoruz.
          IF SURE[I]=0 THEN    'süre değişkeni sıfırlanmış ise 3 sn lik süre sona ermiş demektir.
             PORTB.0[I]=0          'o halde led'i söndürelim.
          ENDIF
        ENDIF
        NEXT
        TMR0=7  'timer0 a yeniden ön yükleme değerini verelim
        INTCON.2=0  'kesme bayrağını sıfırlayıp
        RESUME         'kesmeden çıkalım.
        ENABLE
        END     

Hepsi bu kadar. Görüldüğü üzere SURE[8] şeklinde bir dizi değişkeni kullandım. Bunun için
SURE VAR BYTE[8] şeklinde bir tanımlama yapmak gerekecektir.

Programda sigorta ayarları ile bazı eksiklikler var idi onlarıda tamamlarsak programın son hali ilişiktedir.

Ete

efehurkan

Valla ETE bey müthişsiniz, ayırdığınız zaman ve çalışmalarınız için çok teşekkür ederim, günlerce araştırmama rağmen timer kesmesi ile ilgili hiç bir örnek veya açıklama bulamamıştım, yapmış olduğunuz açıklamalar ve örnekler ile de öğrenmiş olduk, eminim benim gibi bir çok meraklı pic le led yakmadan veya röle çektirmeden sonra bu konuda zorluklar çekiyorlardı, yapmış olduğunuz bilgilendirmelerden ve örneklerden  yüzlerce insana ışık olmaktasınız, teşekkürlerimi sunar, çalışmalarınızda başarılar dilerim.

efehurkan

Merhabalar ETE bey, yukarıdaki gibi devrenin pcb ye kurulumunu yaptım, fakat MCLR girişine bağlı butona basıldığında resetleme gerçekleşiyor, butona tekrar basıldığında röle aktif oluyor, röle pasif olmadan butona tekrar basıldığında ise röle pasif oluyor, acaba MCLR pini input olarak kullanıldığında toggle olarak mı çalışmaktadır acaba?

ete

MCLR pini normalde reset fonksiyonunu yerine getirir. Ancak sigorta ayarlarından MCLR_OFF komutunu verdiğiniz zaman o pin artık bir giriş pini olarak çalışır ve toggle olayı ile alakası yoktur.
Bu nedenle Pic'e yüklediğiniz program daki sigorta ayarları çok önem kazanıyor.
Ben örnek de bu ayarı sigorta ayarlarına eklemiş idim. Aynı programı kullandınız ise sorun olmaması gerekirdi. Ama elbette kullandığınız programlayıcı ayarları programdan alıp işlemciye yazıyormu burası önemli elbette. Hangi programlayıcıyı kullanıyorsunuz ve programlama esnasında sigorta ayarları ne durumda oluyor bir bakarmısınız.

Ete

efehurkan

Programlayıcım daki sigorta ayarlarına dikkat ettim disable olarak görünmekteydi, sizin göndermiş olduğunuz hex dosyasını kullandım. Resimlerde görüldüğü gibidir ayarları. Buton direnç bağlantımda sorun olabilir mi acaba? 1k yerine başka değermi gerekir acaba bu giriş için?

ete

Her şey normal gözüküyor. İşlemcinin besleme bacakları arasına 100nf kondansatör bağlamayı ihmal etme. Direk bacakların üzerine lehimle.
Programda bir iki sigorta ayarını eklememişiz. Onları ekledim Eskisi ile değiştirdim. Oradan yeniden yükle ve onuda bir dene istersen.

Bu sorunu yalnızca PORTA.5 de bağlı olan buton yapıyor ise buton kontakları arasına 100nf bağla ve öyle bir dene bakalım.

Derlenen program 16F628A işlemcisine aittir aslında pek fark etmemesi gerekir. Sorun yinede devam ediyor ise programda kaplı olan while:wend dingülerini açıp yeniden derleyip denemek gerekebilir.

Ete

efehurkan

Merhaba ETE bey son göndermiş olduğunuz hex dosyasını yükledim yine MCLR buton girişindeki butona basılınca toggle ve bazande reset işlemi yaparak çalışmaya devam etti. MCLR girişine 100nf kondansatör taktığımda ise resetleme ve toggle çalışması durdu, fakat başka butonlara basılınca MCLR girişindeki butona basılmış gibi  rölesi çekmeye başladı, tüm buton girişlerine 100nf kondansatör taktığımda tüm butonlara ait röleler normal çalıştı, ilginize ve ayırmış olduğunuz zaman için çok teşekkür ederim. :D 

Çalışmanın videosuna aşağıdaki linkten ulaşabilirsiniz.
5sn röle kartı

efehurkan

ETE bey rölelerin bırakmada gecikme süreleri en fazla kaç sn veya dk olarak artırılabilir acaba?

ete

3sn istemiştin 3 sn yapmıştım. Gerekirse artırılabilir. Ancak onu sen yapman lazım ben yapacağımı yaptım.

Ete

efehurkan

Merhaba Hocam, bir şeyler yazmaya çalıştım ama olmadı, 4 ad. butonum var, birinci buton ile ilk 4 ledi sırasıyla yakıp söndürüyorum fakat diğerlerini yapamadım,

1.Butona 1 kez basıp bırakıldığında  1. ledi  3sn yakıp söndürecek
1.Butona 1 kez basıp bırakıldığında  2. ledi  3sn yakıp söndürecek
1.Butona 1 kez basıp bırakıldığında  3. ledi  3sn yakıp söndürecek
1.Butona 1 kez basıp bırakıldığında  4. ledi  3sn yakıp söndürecek
1.Butona 1 kez basıp bırakıldığında  1. led den başlayarak işlemleri sırasıyla yerine getirecek.
2.Butona 1 kez basıp bırakıldığında  5. ledi  3sn yakıp söndürecek
2.Butona 1 kez basıp bırakıldığında  6. ledi  3sn yakıp söndürecek
2.Butona 1 kez basıp bırakıldığında  5. led den başlayarak işlemleri sırasıyla yerine getirecek.
3.Butona 1 kez basıp bırakıldığında  7. ledi  3sn yakıp söndürecek
4.Butona 1 kez basıp bırakıldığında  8. ledi  3sn yakıp söndürecek

@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _LVP_OFF & _CP_OFF & _BODEN_OFF & _PWRTE_ON

DEFINE OSC 4

CMCON=7
TRISA=%11111111
TRISB=%00000000
PORTA=0
PORTB=0
CMCON=7


SAYI var byte

BASLA:
IF PORTA.0=0 THEN
        IF SAYI=0 THEN
           SAYI=1
        ELSE
           SAYI=SAYI*2
           IF SAYI=16 THEN SAYI=1
        ENDIF
        while PortA.0=0
        portb=SAYI
        pause 3000
        wend
      ENDIF
      PORTB=0
      PAUSE 50

IF PORTA.1=0 THEN
        IF SAYI=0 THEN
           SAYI=1
        ELSE
           SAYI=SAYI*2
           IF SAYI=8 THEN SAYI=1
        ENDIF
        while PortA.1=0
        PORTB.4=SAYI
        PORTB.5=SAYI
        pause 3000
        wend
      ENDIF
      PORTB.4=0
      PAUSE 50     
     
           GOTO BASLA
      end

veli dayı


sayac var byte
poz var byte
sayac=0
poz=0

BASLA:
IF PORTA.0=0 and poz=0 THEN
pause 100
sayac=sayac+1
poz=1
else
poz=0
  ENDIF
ıf sayac=5 then
sayac=0
endıf
Select Case sayac   

     Case 1 hıgh led1'3 saniyede 1 flaş atacak
gosub sure
low led1
gosub sure

case2
case3
.
.
.
.
.
.
.
End Select   

sure:
for i=0 to 3
pause 1000
next
return   

buna benzer bir mantıktan olması lazım.şu an iş yerinden yazıyorum bunu derleyip deneyebileceğim programlar yok bilgisayarda tahmini bir şeyler yazdım fikir vermesi açısından

KA

Arkadaşlar ekteki sayıcı devresinde tek tek bastıkça sayım yapması için nasıl düzenleme yapmam lazım

ete

      IF TUSA=0 THEN 
        SAYI=SAYI+1 :PAUSE 150
        IF SAYI=100 THEN SAYI=99
        WHILE TUSA=0:WEND
        PAUSE 50
      ENDIF
     
      IF TUSB=0 THEN
        SAYI=SAYI-1:PAUSE 150
        IF SAYI=255 THEN SAYI=0
        WHILE TUSB=0:WEND
         PAUSE 50
      ENDIF


Ete

Powered by EzPortal