16F84 ile Led Uygulaması Hakkında Yardım

Katılım
19 Nis 2008
Mesajlar
55
Puanları
1
Yaş
37
Arkadaşlar hepinize kolay gelsin,
PIC16F84 ile Port A yada Port B bacaklarından sadece bir tanesi ( örenğin RB5 veya RA1 ) kullanılarak bu bacağa bağlı olan ledin bir kere yanması ve sonrasında sönmesi isteniyor. Bu işlem bu şekilde devam edecek yani öncelik farketmez ilk yan ise belirlli bir süre sonra sönecek belirli bir süre tekrar yanacak ( süre o kadarda önemli değil sadece ledin yanıp sönmesi gözle algılanabilir bir sürede olsun yeterli ).
Öncelikle Port B yi kulaanarak yapmayı planmalım ve şöyle düşündüm.

Port B deki bilgileri sıfırla
Bank 0 dan Bank 1 e geç
Port B uçlarını çıkış yap
Bank 1 den Bank 0 a geç
W registerine değeri ata (mesela 1 bitini ledin yanması için )
W registerindan File registerine atanan değeri taşı
W registerine değeri at ( mesela 0 bitini ledin sönmesi için )
W registerindan File registerine atanan değeri taşı
Döngüye gir
Programı sonlandır.

Bu şekilde hazırladığım algoritmayı hocamıza gösterdim. Hocam sonsuz döngüye girdiğin anda son değer ne ise devamlı olarak o değeri koruyacağını söyledi. Yani led devamlı olaraka sönecek yada yanacak. Bu istenmiyen bir durum benim için. Hocamız sayaç kullanarak bu durumu çözeceğimi savundu. Pice yeni başladığım için zorlanıyorum. Sayaç işlemini nasıl kullanacağım.

Siz değerli arkadaşlardan bu konu hakkında yardım bekliyorum.
 
LIST P=16F84
INCLUDE "P16F84.INC"
SAY1 EQU H'21'
SAY2 EQU H'22'
ORG H'00'
;------PORT AYARLARI-------
BSF STATUS,5;
CLRF TRİSB;
BCF STATUS,5;
;-------PROGRAM------------

DEVAM:
BSF PORTB,7;
CALL ZAMAN
BCF PORTB,7;
CALL ZAMAN
GOTO DEVAM
;--------ZAMAN ALT PROGRAM-------
MOVLW D'250'
MOVWF SAY1
DON2:
MOVLW D'250'
MOVWF SAY2
DON1:
DECFSZ SAY2,F
GOTO DON1
DECFSZ SAY1,F
GOTO DON2
RETURN
END
;-----------SON----------------------


Arkadaşım aklımda kaldığı kadarıyla programı yazmaya çalıştım. Bu şekilde led sürekli yanıp söner.
Eğer led sadece 1 kere yanıp sönecekse :

;-------PROGRAM------------

BSF PORTB,7;
CALL ZAMAN
BCF PORTB,7;


şeklinde değişiklik yaparsan led bir kere yanar ve söner.

PİC e yeni başladım diye belirmişsin büyük ihtimalle zaman gecikmesinin nasıl yapıldıgını henüz görmemişsinizdir.
zaman gecikmesinin nasıl yapıldıgını görmediğinizi varsayarak programı başka şekilde yazıyorum

;--------PROGRAM------
MOVLW B'10000000'
MOVWF PORTB
NOP
NOP
NOP
NOP
NOP
.
.
.
.
.
.
.NOP
MOVLW B'00000000'
MOVWF PORTB

BURADAKİ NOP(No operation-Hiçbir işlem yapma) komutu mikrosaniye düzeyinde bir gecikme sağlar.Gecikme çok kısa olduğu için algılamayız ,bu yüzden peşpeşe birçok NOP komutu yazmak gerekir.
 
elkgazi arkadaşım ilgin ve cevabın için teşekkür ederim.
Orhan Altınbaşak'ın Mikrodenetleyiciler ve Pic Programlama kitabından biraz bakındım ve zaman gecikmesi konusunda bir iki örnek buldun inceledim MPLAB ta programı yazdım ve proteusta çizimi yaptıktan sonra simule ettim. Sonuç olarak ledi yakıp söndürmeyi başardım. Program aşağıda.

;==============================FIRST PROGRAM=============
LIST P=16F84
STATUS EQU h'03'
PORTB EQU h'06'
TRISB EQU h'86'


SAYAC1 EQU h'0C'
SAYAC2 EQU h'0D'
CLRF PORTB
BSF STATUS,5
CLRF TRISB
BCF STATUS,5
TEKRAR
MOVLW h'00'
MOVWF PORTB

CALL GECIKME

MOVLW h'01'
MOVWF PORTB

CALL GECIKME
GOTO TEKRAR
GECIKME
MOVLW h'FF'
MOVWF SAYAC1
DONGU1
MOVLW h'FF'
MOVWF SAYAC2
DONGU2
DECFSZ SAYAC2, F
GOTO DONGU2
DECFSZ SAYAC1, F
GOTO DONGU1
RETURN
END

Burada anlamadığım tek nokta şurası ; bu zaman gecikmesini sağlamak amacıyla kullanılan sayac1 ve sayac 2 parametrelerine atanan 'FF' veyahut başka bir hexadesimal sayı faketmez bunu nasıl belirliyoruz. Orhan Altınbaşak kitapta çok karışık bir vaziyette anlatmış anlaşılması güç biraz. Bu programda ledin yanması 198 ms sönük kalması 198 ms dir. Düşündüm bir sayac daha ekleyeyim dedim bu sefer yanması veya sönük kalması zamanı 50 s ye sürdü. Buna ait programda aşağıda verilmiştir. Sorum şu; ne kadarlık bir gecikme zamanını isteğimize göre ayarlamak için bu sayaçlara atanan sayıyı belirlememiz gerekir. Bu sayı en fazla FF olmakta . O zaman istediğimiz zamanı elde etmek için sayaçlarımıartıracaz artırırkende fazladan eklediğimiz sayaç ne kadarlık bir gecikme katacak bunun cevabını ve hesaplamasını arıyorum.

herkese kolay gelsin.
 
;=================third program====================
LIST P=16F84
STATUS EQU h'03'
PORTB EQU h'06'
TRISB EQU h'86'


SAYAC1 EQU h'0C'
SAYAC2 EQU h'0D'
SAYAC3 EQU h'0E'
CLRF PORTB
BSF STATUS,5
CLRF TRISB
BCF STATUS,5
TEKRAR
MOVLW h'00'
MOVWF PORTB

CALL GECIKME

MOVLW h'01'
MOVWF PORTB

CALL GECIKME
GOTO TEKRAR
GECIKME
MOVLW h'FF'
MOVWF SAYAC1
DONGU1
MOVLW h'FF'
MOVWF SAYAC2
DONGU2
MOVLW h'FF'
MOVWF SAYAC3

DONGU3
DECFSZ SAYAC3, F
GOTO DONGU3
DECFSZ SAYAC2, F
GOTO DONGU2
DECFSZ SAYAC1, F
GOTO DONGU1
RETURN
END
 
Arkadaşım onun bir hesaplama yöntemi vardı ama şuanda aklımda değil. Akşam üzeri eski notlarıma bir göz atıp sana zaman gecikmesinin nasıl hesaplandığı anlatmaya çalışırım.
 
mrb arkadaşım. zaman gecikmesinin kaç saniye oldugunu hesaplamak için uzunca işlemler yapmak gerekiyor ama ben sana iki tane formül yazıcam bu iki formülü kullanarak çok az bir sapmayla kaç saniye zaman gecikmesi oldugunu hesaplayabilirsin.

1. 10 mhz kristal ve iki kaydedici kullanarak zaman gecikme hesabı yapmak için aşağıdaki işlemleri takip ediyoruz
(birinci kaydedicimizin içine ilk olarak desimal 20 ikincisinede desimal 100 sayısını atadığımızı varsayalım)

Komut frekansı = OSC. frekansı /4

Komut frekansı =10 Mhz/4=2,5 MHZ

Komut süresi =1/2,5 MHZ

Komut süresi =0,4 mik. saniye

Formül
Toplam saykıl= 3*birinci kaydediciye atanan değer*ikinci kaydediciye atanan değer
Toplam saykıl= 3*20*100
Toplam saykıl= 6000saykıl
Toplam zaman gecikmesi = Toplam saykıl* Komut süresi
Toplam zaman gecikmesi = 6000*0,4
Toplam zaman gecikmesi = 2400 mikro saniye

demekki birinci kaydediciye 20 ikinciye 100 değerini atarsak 2400 mik. saniye gecikme sağlanıyormuş

2.12 mhz kristal ve üç kaydedici kullanarak zaman gecikme hesabı yapmak için aşağıdaki işlemleri takip ediyoruz
(birinci kaydedicimizin içine ilk olarak desimal 25 ikincisinede desimal 50 ve üçüncüsüne desimal 100 sayısını atadığımızı varsayalım)

Komut frekansı = OSC. frekansı /4

Komut frekansı =12 Mhz/4=3 MHZ

Komut süresi =1/3 MHZ

Komut süresi =0,333333 mik. saniye

Formül
Toplam saykıl= 3*birinci kaydediciye atanan değer*ikinci kaydediciye atanan değer*üçüncü kaydediciye atanan değer + 5*birinci kaydediciye atanan değer*ikinci kaydediciye atanan değer

Toplam saykıl=3*25*50*100 + 5*25*50
Toplam saykıl=381385 saykıl
Toplam zaman gecikmesi = Toplam saykıl* Komut süresi
Toplam zaman gecikmesi = 381385*0,333333
Toplam zaman gecikmesi =127082,0625 mik. saniye =0,12 saniye

umarım yararlı olmuştur. kolay gelsin
 
Aklıma gelmişken birşey daha ekleyeyim

programı yazarken kullanılacak özel amaçlı kaydedicilerin adresleri ve isimlerini tek tek tanımlamak yerine
programın başına

İnclude "P16f84.inc" yazabilirsin.
 
elkgazi arkadaşım bilgilerin için çok teşekkür ederim.

Yazdığın formullerden çıkardığım sonuç ; eğer 4 kaydedici kullanırsam

Toplam saykıl= 3*birinci kaydediciye atanan değer*ikinci kaydediciye atanan değer*üçüncü kaydediciye atanan değer*dördüncü kaydediciye atanan değer + 5*birinci kaydediciye atanan değer*ikinci kaydediciye atanan değer*üçüncü kaydediciye atanan değer + 7*birinci kaydediciye atanan değer*ikinci kaydediciye atanan değer

şeklindemi olacak.

Örneğin yapacağım örnek aşağıdaki gibi olsun.

16F84 ün osilator frekansı 4MHz olsun ve PortB ye bağlı ledler 1 sn lik ara ile sırayla yanarak ilk ledten son lede kadar bu şekilde devam etsin. Yukarıda yazdığın bağıntıları gayet iyi anladım eline sağlık. Şimdi bu bağıntılardan yola çıkalım.

Komut frekansı = OSC. frekansı /4

Komut frekansı =4 Mhz/4=1 MHZ

Komut süresi =1/1 MHZ

Komut süresi =0,1 mik. saniye

Bu kısımdan sonrası sorun. Şimdi kaydedicilerin içine hangi değeri atamam lazımki ve kaç döngü kullanmam lazımki zaman gecikmesi 1 sn ye olsun.


Toplam zaman gecikmesi = Toplam saykıl* Komut süresi

1 000 000 mik.sn = Toplam Saykıl*0.1mik.sn

10 000 000 = Toplam Saykıl

Sorun burdan sonra başlamakta benim için. Toplam saykıl değerini buldum. Ben bu değere ulaşmam için iki döngü kullansam ;

Toplam saykıl= 3*birinci kaydediciye atanan değer*ikinci kaydediciye atanan değer

Kaydediciler içine atanan değeri en büyük seçeyim yani desimal 255

Toplam saykıl= 3*255*255 = 195 075 çıkmakta ki burdan anlaşılan ik döngü kullanılarak bu değer ulaşamam.

Birde 3 döngü kullanayım.

Toplam saykıl= 3*birinci kaydediciye atanan değer*ikinci kaydediciye atanan değer*üçüncü kaydediciye atanan değer + 5*birinci kaydediciye atanan değer*ikinci kaydediciye atanan değer

Gene aynı şekilde değerleri aynı ve en büyük seçelim.

10 000 000 = 3*255*255*255 + 5*255*255 = 50 069 250 çıkmakta .

sonuç : iki döngü en büyük sayı kullanılarak yetmemekte ve üç döngü için en büyük sayı kullanıldığında bu değeri aşmakta ama ne alacam ? Muallak....

Birde şöyle deneyelim. Sayıları birbirine eşit seçelim.

10 000 000 = 3*m^3 + 5*m^2 şimdi de hesap makinası vasıtasıyla deneme yanılma sayıyı yaklaşık olarak bulmaya çalışayım.

yaklaşık 149 çıktı desimal olarak .

Bunun daha mantıklı yolu yokmu elkgazi arkadaşım. Birde yukarıda yazdığım dört döngü kullanmak zorunda kaldığım vakit formul ne olacak ?

İlgin alakan için çok teşekkür ederim.


İyi geceler
 
bulduğum desimal 149 değerini kullanarak program yazdım ve proteusta simule ettim elkgazi arkadaşım zaman gecikmesini 10 sn olarak verdi ( program led bir yansın bir sönsün şeklinde )

___________________________________________________________________

Bu farkın sebebi ne olabilir acaba elkgazi arkadaşım. Yani hesaplamar doğru ama simüle edince neden 10 katı bir fark ortaya çıktı ??

Deli oldum bu duruma ya. Neyse tekrardan iyi geceler

Arka arkaya mesaj yazmak yasaktır.Lütfen son mesajınızın sağ üstünde bulunan Değiştir butonunu kullanınız.
Düzenleme:
korkmaz_design
 
mrb arkadaşım. 10 sn olarak bulmuşsun çünkü ;

Komut süresini hesaplarken 1/1Mhz= 0,1 mik. saniye olarak hesaplamışsın. Burası 1 mikro saniye olacak. İşlemleri yapmak isterdim ama zamanım kısıtlı. Birde bu sonuca göre işlemleri tekrar yapmayı dene. Bildiğim daha basit bir yolu yok. Assembly de bu iş biraz zor ama diğer dillerde zaman hesaplarıyla hiç uğraşmıyorsun kaç saniye gecikme yapmak istiyorsan direkt değerini giriyorsun.

Sonucu bekliyorum kolay gelsin....
Düzenleme:

Arkadaşım kaydedicilere atayacağın değeri 68,7 olarak buldum. Birde bu değeri kullanarak dene bakalım olacak mı...
 

Yeni mesajlar

Forum istatistikleri

Konular
128,190
Mesajlar
915,724
Kullanıcılar
449,960
Son üye
katzeimar

Yeni konular

Çevrimiçi üyeler

Geri
Üst