LCD Aydınlatma Hk.

Başlatan solidus, 24 Haziran 2009, 01:00:02

solidus

Merhaba Arkadaşlar,
16f876 ve 4 satır LCD ile bir dual termometre ve Termostat uygulamasında sona geldim. LCD aydınlatması ile ilgili bi sorunum var. 3 tane butonum var. Bu butonlara basıldığı zaman işlevlerini yerine getirmesini ve LCD'nin aydınlanmasını ve ilk basıştan sonra mesela 5 sn içerisinde butona basılmazsa LCD ışığının sönmesini istiyorum. Sürücü transistör dışında ilave bir malzeme kullanmadan nasıl yapabilirim ?
Kimine göre kralım kimine göre yalanım… Herkes rahatına baksın, ben adamına göre adamım..

tayyar

Timer kullanarak çözülebilir bence. tuşlara basıldıgında timer resetlenir timer saydıgı süre içersinde ışık yanık kalır (resetlendikçe saymayı bitiremez) eger tuşlara basılmadıysa timer resetlenmez ve sona ulaşır sona ulaştıgında ışık söner.


Atıyorum i adında bir değişkenin olsun timerinide 1 saniyeye kurdugunu varsayalım. Boşta olan bir pinden transistörü tetiklersin (transistör aydınlatmayı sürecek şekilde bağlanmış olacak.)

Timer her 1 saniyede taşmaya gittiğinde i yi 1 arttırır, i=5 olup olmadıgını kontrol edersin. Sayma sırasında bir tuşa basılırsa i=0 a döner; eğer basılmazsa i=5 e ulaşır ve sorgulama sonucunda ışıgın sönme vakti geldigine karar verilir.

Bu karar verme sonucunda ilgili pin durum değiştirir ve aydınlatma söner.
--EGEMENLİK KAYITSIZ ŞARTSIZ MİLLETİNDİR--

solidus

@tayyar,
Hocam bunu kısa bir kodla anlatırsanız daha iyi anlayabilirim..
Kimine göre kralım kimine göre yalanım… Herkes rahatına baksın, ben adamına göre adamım..

tayyar

Timeri 1 saniyeye kurdugunu varsayıyorum

//Define kısmı
#define button pin_b1
#define isik bin_b2
int i=0;


//Timer1 kesme alt programı içerisinde kesme oluştugunda şurası işlenecek:
#INT_TIMER1 
void timer_kesme() 
{
i=i+1; 
if(i==5)
{

output_low(isik);
disable_interrupts(INT_TIMER1); //ışık söndügü için timer interruptu kapatıldı
}

if(i<5)
{
output_high(isik);

}
}


Void Main()
{
while(true)
{
if(input(button)) //bu if döngüsü buttonla ilgili yerlere eklenecek
{
   enable_interrupts(INT_TIMER1); //buttona basıldıgı için timer interruptu aktif hale getirildi
i=0;  //buttona basıldıgı için i, 0 a çekildi eğer basılmasaydı i artmaya devam edecekti
}


//burada while döngüsündeki diger fonksiyonlar olacak



}

}




Işık söndügünde timeri kapatmazsanız timer saymaya devam eder, i degişkenimiz int formatında oldugu için 255 e kadar cıkabilir. 5ten 255 e kadar olan kısımda problem yoktur ancak int formatındaki degişken taşmaya gittiginde tekrar sıfıra döner ve 0-5 arası kısımda ışık tekrar yanmaya başlar.

Farklı timer modülleriylede yapılabilir ancak gerekli ayarlamalar yapılmalıdır.
--EGEMENLİK KAYITSIZ ŞARTSIZ MİLLETİNDİR--

dijital74

Mesela şöyle;


If portb.0=1 then 'İlgili tüm butonlar için uygulanabilir.
For i= 1 to 5 ' 5 adım
high porta.0 
pause 1000
next i 
low porta.0
endif


Bunu bir etiket olarak atarsın. Bu arada üstadlar ilk kez kod yazıyorum forumda, yanlışımız olursa düzeltin lütfen.

solidus

PBP de kod yazmaya çalışıyorum. Yanılmıyorsam pause komutunu kullandığımız yerde program tamamıyla durup süre sonunda kaldığı yerden devam ediyor. Yanlışmıyım..
T1CON=%00100001 'Timer tanımlamaları

TMR1IF VAR PIR1.0
output portB.1
low portB.1
IF PORTB.0=1 OR PORTB.1=1 OR PORTB.2=1 THEN
IF PIR1.0=1 then  'timerin degerinin 65535 oldugu anda portB.1 i high yap
PIR1.0=0
Endif
high PORTB.1
ENDIF

şeklinde bişey denedim ama butonlara basmadan lamba kendi kandine yanıp sönüyor..
Kimine göre kralım kimine göre yalanım… Herkes rahatına baksın, ben adamına göre adamım..

dijital74

PBPda Interrupta bağlı zaman gecikmesinin nasıl yapıldığını henüz tam öğrenemedim. Fakat Pause 1000 komutu 1 sn lik bir gecikme yapıyor.

Bu gecikmeyi yaparken tuşlar diğer fonksiyonlarını yerine getiremeyebilir. Yazdığım kod bence bu yüzden olmayacak.

tayyar

PBp de pause koduyla işlemci "durdurulur" (yanlız bu tam olarak bir durdurma değildir. işlemci arka planda sayı sayarak sizin yazdıgınız kodla ilgilenmez) bu durma esnasında Dijital74 ünde dedigi gibi pic buttonlara yada başka bişeye tepki vermez o nedenle timer kesmesini tercih ettim. Dikkat ederseniz örnek olması amacıyla verdigim kodda herhngi bir delay komutu yok.

Basic kitabına bir göz atıp basic içinde bir örnek yazmak isterdim ancak kitabımı bulamıyorum sanırım birine verdim ve geri gelmedi :(
--EGEMENLİK KAYITSIZ ŞARTSIZ MİLLETİNDİR--

dijital74

Yapacağınız projede kaç buton kullanacaksınız bilmem ama 4 buton yetiyorsa RB4-RB7 kesmeleri aydınlatma için kullanılabilir.

solidus

@tayyar
hocam yazdığınız koddan anladığım kadarıyla pbp ye çevirmeye çalıştım ama dediğim gibi lamba kendi kendine yanıp sönüyor. Bu durumda yapmak istediğim:
butonlardan herhangi birine basıldığında kesmenin devreye girmesi, belirlenen süre dahilinde butonlardan birine basıldı ise kesmenin devre de kalması basılmadı ise kesme süresinin sonunda disable olması. Şu anda kendi kendine enable oluyor ve kendi kendine disable oluyor..

@dijital74,
son dediğinizi tam olarak anlayamadım. Özür dilerim..
Kimine göre kralım kimine göre yalanım… Herkes rahatına baksın, ben adamına göre adamım..

tayyar

Şöyle açıklayalım:

- timer kesmesini 1 saniyeye kuruyoruz. Yani 1 saniyede bir timer kesmeye gidiyor.
- Timer kesme alt programında bir değişkeni 5 e kadar saydırıyoruz(i=i+1)
- Eğer i değişkenimiz 5 e ulaşmışsa 5 saniyedir her hangi bir buttona dokunulmamış demektir bu durumda ışığı söndürüyoruz (if(i==5) kısmı)
- ışığı söndürdükten sonra timer kesmesinin saymaya devam etmemesi için disable ediyoruz (timer kesmesini kapatıyoruz)
- Eğer i değişkeni içeriği 5 ten küçükse ışığı açıyoruz (if(i<5) kısmı)
- program içerisinde (ana program döngüsünde) her buton kontrolünden sonra (pbp deki if portb.01 then... kısmından sonra) i değişkeninin sıfırlıyoruz

Böylece her butona basıldıgında yeni bir 5 saniyelik periyot başlıyor; bu periyot sonunda i=5 oldugu için (eger baska bir tusa basılmaz ise) ışık söndürülüyor. Eğer bu 5 saniyelik periyor içerisinde tekrar bir buttona basılırsa yeni bir 5 saniyelik periyot başlıyor.

- Ayrıca buttona basıldıgında bu 5 saniyelik periyodu hesaplaması için timer kesmesini enable ediyoruz (aktif hale getiriyoruz - daha sonra i, 5 e ulaştıgında kesme alt programında disable edilecek)
--EGEMENLİK KAYITSIZ ŞARTSIZ MİLLETİNDİR--

mustafa_cmbz

hpwm ile kontrol edersen çok daha iyi olur gibime geliyor....

solidus

[img=http://img198.imageshack.us/img198/2115/forml.th.jpg]

Timer1 i 1 sn kuramıyorum fakat linkteki gibi bir formül buldum. 4 mhz kristal ile 16f876 kullanıyorum.Timer 1 registerini T1CON=%00110101 şeklinde yazıyorum. Formüle yerleştirdiğim zaman 1 sn bulmam mı gerekiyor..? Pic basic te bir örnek verbilecek bir arkadaşım varsa daha eğitici olacak.
Kimine göre kralım kimine göre yalanım… Herkes rahatına baksın, ben adamına göre adamım..

solidus

'pic16F876  @4MHz  

ADCON1=7
TRISA=%11111111
TRISB.1=0
TRISC=%01111111
T1CON=%00000001
PIR1.0 = 0                  ' clear timer1 overflow flag                      
PIE1 = %00000001            ' enable interrupt on timer1 overflow 
INTCON.6 = 1                ' enable peripheral (unmasked) interrupts
INTCON.7 = 1                ' enable global interrupts
on interrupt goto KESME
              
'LCD B/L DEĞİŞKENLERİ
SAYAC var word
TMR1IF VAR PIR1.0
PORTB.1=0
          "
          "
          "
          "
          "
          "
disable
KESME:
T1CON.0 = 0                 ' stop timer1
if portc.0=1 or portc.1=1 or portc.2=1 then
HIGH PORTB.1
endif
SAYAC=SAYAC+1
IF SAYAC=5 THEN
LOW PORTB.1
ENDIF
resume
enable 
END

LCD B/L sürmek için TMR1 kesmesini kullanmak üzere yazdığım son kod bu şekilde. PORTC.0,C.1 VE C.2 ye bağlı butonlardan herhangi birine basınca led çok kısa bir süre yanıp sönüyor. bu süreyi 5 sn' ye çıkartamıyorum.Yardım edermisiniz ?
Kimine göre kralım kimine göre yalanım… Herkes rahatına baksın, ben adamına göre adamım..

tayyar

Sayac bilgisini 5 ten yukarı çek mesela 10 yap kendine göre ayarla süreyi biraz deneme yanılma :)

bu program bir takım hesaplamaları yapmak için yardımcı olabilir hem basic koduda oluşturuyor.
--EGEMENLİK KAYITSIZ ŞARTSIZ MİLLETİNDİR--