tek timer ı birden fazla zamanlayıcı olarak nasıl ayarlayabilirim??

Başlatan nofearkartal, 23 Aralık 2010, 21:40:40

nofearkartal

projemin son aşaması için timer kullanmaya başladım.ancak kafama takılan şeyler var.proje tıkandı kaldı.diyelim ki a anahtarı kapanınca x ledi 12 sn. yanıyor ve sönüyor.b anahtarı da kapanınca x ledi bu sefer 5  sn. yanıyor ve sönüyor.Ben  timer0 ı kullanıyorum.60 ms. de bir kesme bayrağını 1 yapıyor olarak ayarladım.200 kere dönecek şekilde kesme alt programı yazdım :60ms x 200=12000 ms = 12sn
KESME
    BCF	INTCON,2	; TMR0 kesmesini sonrakilere hazırla
	MOVLW	D'0'		; TMR0 ilk sayısı = d'0'
	MOVWF	TMR0		; TMR0 saymaya başlar
	INCF	SAY,F	; sayacı 1 arttır
	MOVLW	d'200'		; W ? d'200'
	SUBWF	SAY,W	; W = SAY - W
	BTFSS	STATUS,Z	; SAY = 200 oldu mu?
	GOTO	KESME_SONU	; Hayır, ana programa git ve bekle.
	CLRF	 SAY	;Evet, sayacı sıfırla
	CLRF PORTB ;x ledi portB ye bağlı olsun

KESME_SONU
RETFIE


şimdi a anahtarı kapandığında timer0 ı aktif hale getiriyorum.12 sn. sonra sönüyor.Burası tamam.problem şu:
0. saniyede a anahtarı kapanıyor. 5. saniyede  b anahtarı kapanırsa x ledi nin 10. saniyede sönmesi gerekiyor.yani x ledinin yanıp sönmesi birden fazla şarta bağlı.hangi şart daha sonra gerçekleşirse mikrodenetleyicinin o işlevi yapması gerekiyor.
Ya da tam tersi :
0. saniyede b anahtarı kapanıyor.3. saniyede a anahtarı kapanırsa x ledinin 15. saniyede sönmesi gerekir.

İkinci sorum ise kodda görüleceği üzere a anahtarı için 12. saniyede x ledi söndürülüyor.b anahtarı için de benzer şekilde bir döngü oluşturup kesme alt programına atmam mı gerekir.yada döngü içinde döngü falan mı kurmam gerekir.ne yapmam gerekir??
Yardımcı olanlara ve olmaya çalışanlara şimdiden teşekkürler.

FEHMİ_ASM

Arkadaşım anladığım kadarıyla butonların süreleri birbirine eklenmeyecek ve A Butonu için belirlenen süre 12sn,  B Butonu için 15 sn. Doğru mu?

nofearkartal

aynen öyle.süreleri,anahtarları vs örnek olarak verdim 5 sn. olur 15 sn. olur farketmez.bir ledi mesela 3 adet anahtarın ve bir sensörün durumuna göre kontrol etmem gerekecek.Şu ikili için bi algoritma mantığını çözebilirsem daha fazla anahtar ve led için de kendim kodu yazabilirim diye düşünüyorum.ama dediğiniz gibi süre eklenmeyecek.

t2

timeri 1 saniye ayarladın diyelim. kesme kodunu amacına uygun düzenlersin
zaman1, zaman2 zaman3 gibi değişkenler olsun. kesme oluşunca bunların herbirini 1 sn artırırsın. istediğin şarları kıyaslar istediğin çıkışı açıp kapatırsın. Uygun şartlar oluştuysa bazı süreyi sıfırlar kimini yeniden başlatırsın. Bu şekilde süreler birbirinden bağımsız olur. tek bağımlı kısmı tümü aynı kesmede 1 er saniye artmış olmalarıdır.



bakın basicde ne kadar kolay.

kesme:  '1sn

zaman1= zaman1+1
zaman2= zaman2+1
...
if zaman1 = 10 then high led1
if zaman2 = 5 then high led2
....



KESMEye de gerek yok


Ana:

   if. .. then ..led yak 
    if.. then  düdük aç 
   ' bu kodların 1sn den çok daha kısa sürdüğü varsayıldı

       gosub gecik1sn
goto ana

gecik1sn: 
     zaman1 = zaman1+1
     zaman2 = zaman2+1
     ...
     delayms 1000
     return

Tagli

Yani her anahtarın ön tanımlı ve sabit bir süre kadar LED'in yakıp söndürmesi gerekiyor ve birden çok anahtarın olduğu bu düzenekte sistem sadece durumu en son değişen anahtara göre işlem yapacak. Doğru mu anlamışım? Ama anahtarlar eski haline geldiğinde ne olacak o kısmı anlamadım.

Şimdi, burada ilk göze çarpan durum şu ki sen timer0 kesmesini kapalı bile tutsan TMR0 çalışmaya devam eder. Bu durumda sen kesmeyi açtıktan hemen sonra veya 60 ms sonra kesmeye gidebilirsin. Zaman konusunda hassaslık önemli değilse bu 60 ms'lik kayma sorun olmayabilir.

Anahtar değişimlerini zaten normal program döngüsü içinde okutuyorsun. Yapman gereken şey, başlangıçta tüm portu temsil edecek 0 veya h'FF' değerini bir register'da saklamak. Döngüde porttan okuduğun değeri bu değişken ile XOR işlemine sokarsan (ve de her işlemden sonra bu değişkeni de güncelleyerek) değişen anahtarı rahatlıkla belirleyebilirsin.

Kesme kodunda artma değil azalma yöntemini kullanman daha kolay olur, böylece çıkarma işlemi yapıp Z'ye bakmaktan kurtulursun. DECFSZ komutu işini görecektir. Ana döngüde ise değişen anahtara göre kesmede kullandığın "say" değişkeninin atamasını yaparsan sorunun çözülür.

Kolay gelsin...
Gökçe Tağlıoğlu

FEHMİ_ASM

KESME
    BCF   INTCON,2   ; TMR0 kesmesini sonrakilere hazırla
   MOVLW   D'0'      ; TMR0 ilk sayısı = d'0'
   MOVWF   TMR0      ; TMR0 saymaya başlar
   INCF   SAY,F   ; sayacı 1 arttır

BUTON1_TEST
        MOVF BUTONA_FF,W
        BCF STATUS,Z
        SUBLW H'FF'
    BTFSS STATUS,Z
         GOTO BUTON2
         MOVF SAY,W
         BCF STATUS,Z
        SUBLW D'250'     ;15 Saniye doldu mu?
    BTFSS STATUS,Z
       GOTO KESME_SONU
       CLRF BUTONA_FF
       CLRF SAY
       CLRF PORTB
       GOTO KESME_SONU
   
  BUTON2
   MOVLW   d'200'      ; W ? d'200'
        BCF STATUS,C
   SUBWF   SAY,W   ; W = SAY - W
     BTFSS   STATUS,C   ; SAY = EN AZ 200 oldu mu?
   GOTO   KESME_SONU   ; Hayır, ana programa git ve bekle.
   CLRF    SAY   ;Evet, sayacı sıfırla
   CLRF PORTB ;x ledi portB ye bağlı olsun

KESME_SONU
RETFIE



ÖNEMLİ NOT:  BUTON1'e basıldığında BUTON1_FF değişkenine H'FF' yükleyip,
                        BUTON2'ye basıldığında bu değeri silmelisin