butonla kontrolü led

Başlatan kotan04, 19 Şubat 2011, 20:33:15

kotan04

merhaba arkadaşlar ben basic pro da ledlere çeşitli efektler yapıyorum lakin benim şöyle bir sıkıntım var yaptığım yazılımda 5 adet led efekti var ve ben bu efektleri portb de çalıştırıyorum ve ben portbde çalışan efeklerin kanal sayısını tek butonla düşürmek istiyorum örneğin devreye enerji verdiğimde butona 5 defa bastığımda yatıptığım efektler portb nin 5 kanalında çalışacak 6 defa bastığımda efektler 6 kanalında çalışacak bu şekilde 8 kanala kadar müdahale edebilmek istiyorum ve bununda 628a nın hafızasında kalmasını sağlıyabilirmiyim? butonla kaç defa bastıysam okadar kanalda led efekleri çalışacak ve elektrik gittiğinde program nasıl ayarlandıysa öyle kalması gerekiyor yazdığım efekler aşşağıda incelerseniz sevinirimnasıl bir kod yazarsam sorun çözülür
??
@ DEVICE pic16F628a                             'MCU 16F628              
@ DEVICE pic16F628a, WDT_ON              '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ılaca
TRISB=0
TRISA=1
PORTB=0
PORTA=1
LED VAR BYTE           'DEĞİŞKEN ATADIK

KARA:
FOR LED=0 TO 7 
HIGH LED
PAUSE 100
LOW LED

NEXT LED
PORTB=0
PORTA=0
FOR LED=7 TO 0  STEP -1
HIGH LED
PAUSE 100
LOW LED
NEXT LED

PORTB=%11111111
PAUSE 500

PORTB=%10101010
PAUSE 500

PORTB=%01010101
PAUSE 500
 

GOTO KARA


kkkkoootttaaannn000444

ete

Bu mesaja nerden başlasam diye çok düşündüm.
Çünki programa baktım ve bir sürü mantıksız işler gördüm.
Anlatılanlara baktım brogramla uyuşmadığını gördüm.
Açıklamana baktım kanal lafının ne anlama geldiğini düşündüm ve sonunda pin olduğunda karar kıldım doğrumu düşündüm acaba?

Önce mantıksız işlerle başlayalım;
Programın başında ;
TRISA=1
PORTB=0
PORTA=1
şeklinde komutların var. TRISA=1 demekle PORTA.0 pinini giriş olarak atamış oluyorsun. Artık buradan girenleri okuyabilir ve bu pine kendin bir değer veremezsin. Peki ne yapmışsın. PORTA=1 komutu ile PORTA.0 pinine 1 değerini vermişsin. İşte bu yanlış. Giriş olarak atanmış bir pine program içinden değer vermezsin.

LED isimli byte cinsinden bir değişkenin var.
Programın başında
KARA:
FOR LED=0 TO 7
HIGH LED
PAUSE 100
LOW LED
NEXT LED

Şeklinde komutların var. Bu komutların ne işe yaradığını söyleyebilirmisin yada hangi amaçla yazdın bu komutları,
LED değişkenini kullanarak bir döngü kurup sonra döngü içinde HIGH LED şeklinde bir komut kullanamazsın.
Bu nedenle kullanıdğın bu komutların hiç bir anlamı yok. Hadi diyelimki LED HIGH oldu peki bunu nerden göreceğiz?
Hiç bir yer çünki LED yalnızca bir byte değişkeni high olmuş low olmuş fark etmez olmasıda sana bir şey kazandırmaz.
Ayrıca bu şekilde bir byte değişkenine HIGH yada LOW şeklinde komut vermezsin. Heleki led isimli bir döngü kurmuş isen hiç vermezsin.
Çünki LED değişkeni döngü değişkenidir artık ona bir komut ile değer yükleyemezsin. En azından döngü bitene kadar bunu yapamazsın.

Program içinde Buton kontrolü de hiç yapmamışsın. Halbuki butona kaç defa basılmış ise program onu yapsın istiyorsun.

Yanlış anlama eksiklerini ve kusurularını belirtmeye çalışıyorumki bir daha yapmayasın bu hataları.

Son olarak programda tek bir animasyon mevcut oda bütün portB pinleri kullanılarak önce hepsi 1 sonra birer atlamalı %10 şeklinde ve sonra birler ile sıfırların yeri değiştirilerek bir animasyon yapılmış.
Şimdi soruyorum,
Butona 2 defa basılmış ise program ne yapacak? 2 nolu portB pininden bir çıkış verecek ama nasıl bir çıkış verecek?
Butona 4 defa basılmış ise bu seferde 4 nolu portb pininden çıkış verilecek ama nasıl bir çıkış.
Açıkçası kafandan geçenleri anlamak gerçekten zor. Daha detaylı açıklama verirsen bu sorununada bir çare bulabiliriz belki.

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

kotan04

sayın hocam özür dilerim üst üste aynı sayfada çalıştım bazılarını silmeyi unutmuşum
örnekteki kod larda  portb de çeşitli şekilerde ledleri yakıp söndürüyorum ben bu kodlara şöyle bir özellik eklemek istiyorum örneğin bir buton olsun devreye enerji verdiğim zaman butona 5 defa bastığımda port b de çalışan led efektleri 5pinde çalışsın butona 6 defa bastığımda hazırladığım led efektleri portb de 6 pinde çalışsın 8 pine kadar bu şekilde kontrol etmek istiyorum ve butonla kaç pini seçtiysem bu efektler okadar pinde çalışsın elektrik kesilse bile en son kaç pini butonla aktif ettiysem o pinlerde aynı efektler çalışsın hocam anlatımımdaki hatalardan dolayı özür dilerim.. ben bu istediğimi devreyi her çalıştırdığımda yapmıyacağım gerekmedikçe pin sayısını ellemeyeceğim örneğin karaşimşek devresi yaptım ve içinde 5 farklı şekilde ledleri yakan bir program yaptım 8 led bu şekilde yanıyor devreyi kappattım  enerji verdim devre daha çalışmadan butana 5 defa bastım hazırladığım led efektleri beş pinde çalışsın devreyi çalıştırdığımda kaç pini seçtiysem yaptığım efektler okadar pinde çalışsın istiyorum :S
kkkkoootttaaannn000444

kotan04

arkadaşlar yardımcı olabilirmisiniz ? sabahlamayı düşünüyorum bugün ..
kkkkoootttaaannn000444

dombilik

Öncelikle RB0 harici interrupt'ını aktif edelim.PORTB nin RB0 hariç diğer pinlerini çıkış yapalım.
RB0 a bir buton bağlayalım.Bu butona basıldığında oluşacak kesme rutininde bir değişkene
(mesela A olsun) A=1 değerini atayalım.Bu değeri eeprom alanımıza kayıt edelim ki
herhangi bir sebepden programımız tekrar baştan çalışmaya başlarsa eepromun ilgili
adresinden A değerini alıp işine devam etsin.
Ana program döngümüz içerisinde A=1 iken hangi pin yada pinlerin aktif edileceğini yazalım(sizin tabiriniz ile efektler).
RB0 girişimizdeki butona tekrar bastığımızda ikinci bir kesme oluşturarak
A değerimizi A=A+1 ile A=2 değerine getirelim.Tabii kesme alt programı içerisinde A değerini
sürekli kontrol edip belirli bir değerin üstüne çıkarsa  sıfırlayalım yada belli bir rakama sabitleyelim (burası size kalmış).
Ana programımız içerisinde A değerine bağımlı olarak istediğimiz efektleri yapalım..
Kolay gelsin...
Bildiklerini kime miras bıraktın?kimseyemi? O zaman bildiklerinin ne önemi kalır. ******** /////////// ******** PROTON-ASM PROTEUS 7.4 SP3 EAGLE 5.40

kotan04

hocam çok teşekürler yardımcı olduğunuz için  bana örnek bir kod yabazilirseniz çok sevinirim yeni yeni kendimi geliştirmekteyim yazacağınız örnek kod bana çok güzel bir referans olur bende onu geliştirmek için gerekli çabayı sarfetmeye hazırım çok saolun..
kkkkoootttaaannn000444

kotan04

arkadaşlar kimse yokmu yanıt yazacak lütfen ..
kkkkoootttaaannn000444

kotan04

Alıntı yapılan: dombilik - 20 Şubat 2011, 00:48:52
Öncelikle RB0 harici interrupt'ını aktif edelim.PORTB nin RB0 hariç diğer pinlerini çıkış yapalım.
RB0 a bir buton bağlayalım.Bu butona basıldığında oluşacak kesme rutininde bir değişkene
(mesela A olsun) A=1 değerini atayalım.Bu değeri eeprom alanımıza kayıt edelim ki
herhangi bir sebepden programımız tekrar baştan çalışmaya başlarsa eepromun ilgili
adresinden A değerini alıp işine devam etsin.
Ana program döngümüz içerisinde A=1 iken hangi pin yada pinlerin aktif edileceğini yazalım(sizin tabiriniz ile efektler).
RB0 girişimizdeki butona tekrar bastığımızda ikinci bir kesme oluşturarak
A değerimizi A=A+1 ile A=2 değerine getirelim.Tabii kesme alt programı içerisinde A değerini
sürekli kontrol edip belirli bir değerin üstüne çıkarsa  sıfırlayalım yada belli bir rakama sabitleyelim (burası size kalmış).
Ana programımız içerisinde A değerine bağımlı olarak istediğimiz efektleri yapalım..
Kolay gelsin...

hocam öncelikle teşekürler ilgilendiğiniz için peki bu bahsettiğiniz örneği bana örnek bir komut ile gösterebilirmisiniz benim için çok iyi olur iyi çalışmalar
kkkkoootttaaannn000444

ete

Aşağıdaki kodu bir dene bakalım.

Ete
'****************************************************************
'*  Name    : ANIMA.BAS                                      *
'*  Author  : [Erol Tahir Erdal]                                *
'*  Notice  : Copyright (c) 2005 [ETE]                          *
'*          : All Rights Reserved                               *
'*  Date    : 23.04.2005                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
PORTA=0
TRISB=%00000001   'PortB.0 giriş diğerleri çıkış yapıldı.
TRISA=%00000000   'A portu tamamı çıkış yapıldı.
'-----------------------------------------------------------------
@ DEVICE pic16F628                      'işlemci 16F628                                
@ DEVICE pic16F628, WDT_on              'Watch Dog timer açık
@ DEVICE pic16F628, PWRT_ON             'Power on timer açık
@ DEVICE pic16F628, PROTECT_OFF         'Kod Protek kapalı
@ DEVICE pic16F628, MCLR_OFF             'MCLR pini kullanılıyor.
@ DEVICE pic16F628, INTRC_OSC_NOCLKOUT  'Dahili osilatör kullanılacak 
'-----------------------------------------------------------------
ON INTERRUPT GoTo KESME   'kesme oluşursa KESME adlı etikete git.
OPTION_REG=%0000000    'dahili Pull up dirençleri aktif edildi ayrıca pullup direncine gerek yok.
INTCON=%10010000  'Kesmeler aktif ve RB0/INT kesmesi aktif

CMCON=7    '16F628 de komparatör pinleri iptal hepsi giriş çıkış
'OPTION_REG.7=1  'portB deki dahili PULL-UP lar iptal edildi.
'-----------------------------------------------------------------
SYMBOL TUS=PORTB.0
SAYI  VAR BYTE  56
SAYAC VAR BYTE  57
RAKAM VAR BYTE  58 
I     VAR BYTE
'-------------------------------------------------------------------
BASLA: 'Ana program bölümünde program bir şey yapmayacak
     SELECT CASE SAYAC
     CASE 0
     GOTO BASLA
     CASE 1
     SAYI=2
     case 2
     SAYI=6
     CASE 3
     SAYI=14
     CASE 4
     SAYI=30
     CASE 5
     SAYI=62
     CASE 6
     SAYI=126
     CASE 7
     SAYI=254
     END SELECT
     
     PORTB=SAYI
     GOSUB DELAY
     RAKAM=SAYI/3
     PORTB=RAKAM
     GOSUB DELAY
     PORTB=(SAYI ^ RAKAM)
     GOSUB DELAY
         
     GOTO BASLA
DELAY:
      for I=0 to 255
      pauseus 10
      pauseus 10
      next
      return
           
DISABLE  'yeniden kesme oluşması önleniyor  
KESME: 'program buraya geldiğinde kesme oluşmuş demektir.
       SAYAC=SAYAC+1
       IF SAYAC>7 then SAYAC=0
       INTCON.1=0  'RB0/INT Bayrağı (flag) silindi.
       Resume      'geldiğin yere dön.
	   Enable      'kesmeler yeniden aktif.
End		
	                
   
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

kotan04

kodları aldım hocam şimdi inceliyorum. en son butonla kaç pini ayarladıysam bunu eprom özelliğini kullanarak içine kaydetme özelliği eklemem mümkün olurmu elektrik kesildiğinde en son haliyle çalışması açısından her defasında ayrlamamak için?
kkkkoootttaaannn000444

kotan04

#10
hocam kodlarda değişiklik yaptım ve portb ve porta çıkışlarına 1 yaptım fakat  ra5 ve ra4 pinlerinden verdiğim çıkışı alamıyorum

programın bu kısmına ekledim BASLA: 'Ana program bölümünde program bir şey yapmayacak
     SELECT CASE SAYAC
      CASE     0
     
      portb=%11111110
      porta=%11111111
      pause 500
     
      portb=%00000000
      porta=%00000000
      pause 500

     

   
     
     GOTO BASLA
     CASE 1
     SAYI=2
     case 2
     SAYI=6
  ayrıca mclr pinine direnç 100nf kondansatör bağlantılarını da yaptım ama sadece bu iki pin çıkış veremiyor acaba kesme kullanınca pasif konumamı geçiyor?
kkkkoootttaaannn000444

Mucit23

MCLR pini zaten çıkış olamaz bu sevdadan vazgeç. .RA4 ise open collektör olduğu için direk led bağlayıp yakamazsın. Ya transistör bağlayıp transistör ile süreceksin. Yada RA4 pinini 220 ohm gibi bir dirençle +5 volta bağlıyacaksın. Sonra ledide direk RA4 pinine tekrar direnç kullanmadan bağlıycaksın. İki yöntemden birini kullanabilirsin.

ete

#12
A portu nerden çıktı anlamadım. Başlangıçta bundan bahsetmemiştin.
A portunda çıkış olarak kullanabileceğin pinler, A0-A1-A2-A3-A4 (ancak open collector)-A6-A7 pinleridir. Son iki pin Dahili OSC kullanılırsa ancak I/O pini olarak kullanılabilir değilse bunlar kristal bağlantı bacaklarıdır.

Eeproma kayıt için yapman gereken biraz düşünmek ve yapmak. Yol göstermek gerekirse;
Kayıt edilecek bilgi yalnızca SAYAC değişken değeridir. Bunun için Kesme kısmında bit bazında bir işaret değişkeni kullanmak ve bu değişken 1 ise eproma kayıt yapmak ve sonra işaret değişkenini sıfırlamak gerekir.
Tabiiki öncelikle değişken tanımlama kısmında ;
FLAG VAR BIT  şeklinde bir değişken tanımlamak gerekiyor. Kaydın gerçekleşmesi için
başla satırından sonra bir iki satır ilave ederek bunu şöyle yapabilirsin;
BASLA:
IF FLAG=1 then
   WRITE 0,SAYAC:GOSUB DELAY
   FLAG=0
ENDIF

Tabiiki programın başla satırından evvel epromdan ilgili değeri ilk çalıştırmada okuması için bir satırda ilave etmek gerekir.
READ 0,SAYAC
IF SAYAC=255 THEN SAYAC=7

Burada hiç sayac kaydı yapılmamış ise sayac değeri 255 olarak okunur. Bu değer 255 okunursa okunacak değeri 7 olarak verdim. Sen istediğin değeri verebilirsin. Aralık 0-7 arasında bir sayı olmalıdır.

Programın KESME kısmında ise çıkıştan önce FLAG=1 şeklinde bir komut ilave ederek flag değişkenini Set etmen de gerekiyor. Bu, sayac değişkeni değiştirildi yeni değerin kayıt edilmesi gerek şeklinde anlaşılmalıdır.
Hepsi bu kadar gerisini artık halletmen gerekiyor.

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

kotan04

Alıntı yapılan: ete - 21 Şubat 2011, 08:17:58
A portu nerden çıktı anlamadım. Başlangıçta bundan bahsetmemiştin.
A portunda çıkış olarak kullanabileceğin pinler, A0-A1-A2-A3-A4 (ancak open collector)-A6-A7 pinleridir. Son iki pin Dahili OSC kullanılırsa ancak I/O pini olarak kullanılabilir değilse bunlar kristal bağlantı bacaklarıdır.

Eeproma kayıt için yapman gereken biraz düşünmek ve yapmak. Yol göstermek gerekirse;
Kayıt edilecek bilgi yalnızca SAYAC değişken değeridir. Bunun için Kesme kısmında bit bazında bir işaret değişkeni kullanmak ve bu değişken 1 ise eproma kayıt yapmak ve sonra işaret değişkenini sıfırlamak gerekir.
Tabiiki öncelikle değişken tanımlama kısmında ;
FLAG VAR BIT  şeklinde bir değişken tanımlamak gerekiyor. Kaydın gerçekleşmesi için
başla satırından sonra bir iki satır ilave ederek bunu şöyle yapabilirsin;
BASLA:
IF FLAG=1 then
   WRITE 0,SAYAC:GOSUB DELAY
   FLAG=0
ENDIF

Tabiiki programın başla satırından evvel epromdan ilgili değeri ilk çalıştırmada okuması için bir satırda ilave etmek gerekir.
READ 0,SAYAC
IF SAYAC=255 THEN SAYAC=7

Burada hiç sayac kaydı yapılmamış ise sayac değeri 255 olarak okunur. Bu değer 255 okunursa okunacak değeri 7 olarak verdim. Sen istediğin değeri verebilirsin. Aralık 0-7 arasında bir sayı olmalıdır.

Programın KESME kısmında ise çıkıştan önce FLAG=1 şeklinde bir komut ilave ederek flag değişkenini Set etmen de gerekiyor. Bu, sayac değişkeni değiştirildi yeni değerin kayıt edilmesi gerek şeklinde anlaşılmalıdır.
Hepsi bu kadar gerisini artık halletmen gerekiyor.

Ete

hocam örnek kodlarla istediğim uygulamayı yaptım fakat şöyle bir sorunum oluştu ben 628a dan 15 pinde bu uygulamayı yapmayı amaçlamıştım portb.0 bitini kesmeden dolayı butona bağladık mclr bacağı ise kullanım dışı oluyor en fazla bu yazılım ile 14 pin kullanabiliyorum amacım 15 pinde çalışmayı uygulamaktı özürdilerim ne yapacağımı bilemiyorum farklı bir yol izleyebilirmiyim acaba ? ne yapabilirim
kkkkoootttaaannn000444

kotan04

hocam yardımlarınızı bekliyorum :S
kkkkoootttaaannn000444