pic16f628a assemblyde sublw, subwf,btfss ve status saklayıcısı hakkında soru

Başlatan ahmetguvenn, 21 Temmuz 2018, 16:52:59

ahmetguvenn

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.

Kod Seç
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
,;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?

Tagli

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.
Gökçe Tağlıoğlu

RaMu

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.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html