iyi günler assembly diliyle pic programlama çalışıyorum.Kafama takılan bazı noktalar var aşağıda verdiğim kodlar üzerinden yardımcı olursanız sevinirim.
Aşağıdaki kodlara göre 1 sn aralıklarla 10 defa ledleri yakan ve son yanışta ledler devamlı yanmaya devam edecek.
LIST P=16F628A
INCLUDE "P16F628A.INC"
__CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _BODEN_OFF & _LVP_OFF & _CPD_OFF & _CP_OFF
;----------------------------------------------------------
SAYAC EQU h'20' ;SAYAC saklayıcısını tanımla
SAYAC1 EQU h'21' ;SAYAC saklayıcısını tanımla
SAYAC2 EQU h'22' ;SAYAC saklayıcısını tanımla
BANKSEL TRISB ;BANK1'e geç
CLRF TRISB ;PORTB uçları çıkış
BANKSEL PORTB ;BANK0'a geç
CLRF PORTB ;PortB'deki LED'leri söndür.
BASLA
CLRF PORTB ;portB'yi sil
CLRF SAYAC ;SAYAC'ı sil
TEKRAR
CALL GECIKME
COMF PORTB,F ;W saklayıcıyı PortB'ye gönder
CALL GECIKME
MOVF SAYAC, W ;SAYAC'ı W'ye yükle(sıfırla)
INCF SAYAC, F ;SAYAC <-- SAYAC+1
MOVLW h'13' ;W saklayıcıya h'13' (desimal 19) yükle.
SUBWF SAYAC, W ;W <-- SAYAC-W
BTFSS STATUS, 2 ;STATUS bit2=1 mi? (Zero flag)
GOTO TEKRAR ;Hayır, TEKRAR'a git
DONGU
GOTO DONGU
GECIKME ;Alt program başlangıcı
MOVLW h'FF' ;Dış döngü (M sayısı)
MOVWF SAYAC1
DONGU1
MOVLW h'FF' ;İç döngü (Nsayısı)
MOVWF SAYAC2
DONGU2
DECFSZ SAYAC2, F
GOTO DONGU2
DECFSZ SAYAC1, F
GOTO DONGU1
RETURN
Yukardaki kodların işleyişinde basamakları ilerlettiğimde ben 20 defa yanıp sönmesi gerektiğini anlıyorum.Ama programı derleyip çalıştırdığımda program 10 defa yanıp sönüyor. Nedenini açıklarsanız sevinirim. Ayrıca tekrar etiketinin altında çalışan SUBWF SAYAC,W basamağında sonuç W=h'01'- h'13'= -h'12' bu sonuca göre -h'12'<h'01' den olacak ve status bayrağı durumundan dolayı tekrar etiketine dönecek buradan birer azalarak döngü devam etmeyecek mi?
Aslında 20 defa durum değişimi var. Yanma ve sönmenin her biri bir durum değişimidir. Bu durumda 10 kez (yan + sön) yapıyor diyebiliriz.
Zero flag sadece işlem sonucu 0 olduğunda 1 olur. Bu da sadece işleme giren sayılar birbirine eşit ise gerçekleşir. Büyüklük veya küçüklük durumlarını düşünmene gerek yok.
Ben bu tür döngüleri yazarken DECFSZ komutunu kullanmayı tercih ediyorum, daha rahat oluyor. Azaltmayı ve 0 kontrolünü tek seferde yapıyor, ayrıca Z'yi kontrol etmeye gerek kalmıyor.
Bir kaç forumu takip edince böyle oluyor :)
https://www.kontrolkalemi.com/forum/konu/pic16f628a-assemblyde-sublw-subwf-btfss-ve-status-saklay%C4%B1c%C4%B1s%C4%B1-hakk%C4%B1nda-soru.121974/#post-781729
Alıntı yapılan: karaapak, post: 781724, member: 207448h'13'=onluk tabanda 19,
önce SAYAC arttırılıp sonra 19 oldumu diye kontrol edildiğinden,
SAYAC 0:19 dahil 20 değer alırken,
döngüde 20 defa tekrarlanır,
TEKRAR ile goto TEKRAR arası 20 defa çalışır çünkü
SUBWF SAYAC,W işleminin sonucunda sadece STATUS,Z yani Zero flag a bakılmış yani
eğer aritmetik işlemin sonucu 0 ise Zero bayrağı 1 olur,
Subwf işleminin sonucunun 0 olabilmesi için SAYAC = h'13' onluk tabanda 19 olması gerekir.
20 defa yanıp sönmez neden,
döngüye girilmeden önce PORTB sıfırlanmış durumda ve
döngüden her geçişte COMF PORTB,F komutu ile PORTB tamamen terslenmiş,
yanıyorsa sönsün sönükse yansın denmiş,
program döngüye girer girmez ilk seferde PORTB yi tamamen 1 yapar ledlerin anodu PORTB ye bağlıysa ledler yanarama bundan önce gecikme olduğu için ledlerin sönük durumu gözükmektedir,
bu sırada SAYAC 0 dan 1 e arttırılır sonra 19 oldu mu diye bakılır,
döngüden ikinci geçişte ledler söner,
böyle sayarsan ledler 9 defa söner 10 defa yanar ve
döngü sonunda yanık kalır.
Devre başta enerjisizse ledler sönük olacağından o durumuda hesaba katabilirsin ama
normalde devre hep enerjili ve resetlenirse nasıl çalışır diye düşünmek gerekir.
Birde bu programı CALL GECIKME kısmını bir defa kullanarak yaz.