16f84a pclath öğrenmek istiyorum

Başlatan mustafaaxu, 20 Nisan 2009, 18:34:23

mustafaaxu

değerli bigbey
doğrudur anolog değer okuyorum  elimdede 16f84a var biraz
yazılımı da16f84a  uydurmaya çalışıyorum anladığınız gibi  
kodun tamamı evdeki pc de yarın inşallah sabahtan eklerim
teşekkür ederim ilgin için
TA5EK ..73..

bigbey

Burada bir yanlış anlama var. 16F84a analog okuma yapamaz böyle bir donanıma sahip değil.
TA6R

mustafaaxu

sayın bigbey
doğrudur 16f84a anolog değeri okumuyor
ama kodu tamamını ekliyorum
burada ki uygulamamız porta 4 deki değer 0 dan 1 olana kadar temp dosyasını 1 arttırıyoruz  bu şekilde temp değeri  kapasite ile  doğru orantılı olarak değişiyor doğrumudur hocam
bu şekildeki bir uygulamada 255 den sonra 256 gelmiyor konunun özü bu
belki sizleri eksik bilgi ile farklı düşündürdüm
affola  
sayın bigbey radyo amatörümüsünüz.
TA5EK..73..
;-----sayıcı------
;-----bir kapasitenin dolarken geçen süreyi sayma-------
LIST P=16F84
		INCLUDE "P16F84A.INC"
		__CONFIG  _CP_OFF &_WDT_OFF &_XT_OSC &_PWRTE_OFF

SAYACA		EQU	H'10'	
SAYACB		EQU	H'11'	
SAYAC1		EQU	H'12'	
SAYAC2		EQU	H'13'	
SAYAC3		EQU	H'14'
GCKSAY1		EQU	H'15'
GCKSAY2		EQU	H'16'   
TEMP		EQU	H'17'	
SAYAC	        EQU	H'1A'
SAY1		EQU	H'0C'	
SAY2		EQU	H'0D'	
BİRLER		EQU	H'1B'
HEXLSB		EQU	H'1C'
ONLAR		EQU	H'1D'
YÜZLER		EQU	H'1F'
ONLAR1		EQU	H'21'
;------------------------------------------------------------------------------
START
	BSF	STATUS, 5	;BANK 1'E GEÇ
	
	MOVLW	B'00000000'	;0 değeri portu çıkış yapar
	MOVWF	TRISA		;PORT A ra0-ra1-ra2-ra3-ra4 çıkış (00000000) porta hepsi çıkış
                               
	MOVLW	B'00000000'	;0 değeri portu çıkış yapar
	MOVWF	TRISB		;PORT B rb0,1,2,3,4,5,6,7 ÇIKIŞ (00000000) portb hepsi çıkış
	
	BCF	STATUS, 5	;BANK 0'A GEÇ
	
;-------------------------------------------------------------------------	
   CLRF	PORTA
   CLRF	PORTB
   CLRF	SAYACA
   CLRF	SAYACB
   CLRF	SAYAC
   CLRF	TEMP        
;-------------------------------------------------------------------------------
	MOVLW	d'100'
	MOVWF	SAYAC		;ekranda kalma süresi                                      
;-------------------------------------------------------------------------------
degeroku
	CALL	DESARJ		;kapasitenin boşalmalması için bekleme
	BSF	STATUS, 5	;bank1
	BSF	TRISA, 4	;port a,4 giris ayarlandı
	BCF	STATUS, 5	;bank0

;----------------------------------------------------------------------------
COUNT
	INCF	TEMP, F        ;TEMP değerini 1 arttır
	BTFSS	PORTA, 4       ;kapasite dolduysa 1 atla
	GOTO	COUNT	       ;kapasite dolmadıysa goro cound	
;-------------------------------------------------------------------------		
	MOVF 	TEMP,W		;temp değerini W ye yaz

	MOVWF	HEXLSB		;temp değerini hexlsb yükle
;--------------------------------------------------------------------------
HEXTODEC
	CLRF ONLAR			;ONLAR = 0
	CLRF BİRLER			;BİRLER = 0
	CLRF YÜZLER

YÜZLER_KONT
	MOVLW	0X64			;W = 0X64 (100)
	SUBWF	HEXLSB, W		;HEXLSB'DEN 100 ÇIKART.
	BTFSS	STATUS, C		;SONUÇ >= 100 MU?
	GOTO	ONLAR_KONT		;ONLAR'I YENİDEN KONTROL ET.
	INCF	YÜZLER, F		;EVET İSE ONLARI BİR ARTIR.
	MOVLW	0X64			;W = 0X64 (100)
	SUBWF	HEXLSB, F		;HEXLSB'DEN 100 ÇIKART.
	GOTO	YÜZLER_KONT		;YÜZLER'I YENİDEN KONTROL ET.

ONLAR_KONT
	MOVLW	0X0A			;W = 0X0A (10)
	SUBWF	HEXLSB, W		;HEXLSB'DEN 10 ÇIKART.
	BTFSS	STATUS, C		;SONUÇ >= 10 MU?
	GOTO	BİRLER_KONT		;HAYIR İSE BİRLERİ KONTROL ET.
	INCF	ONLAR, F		;EVET İSE ONLARI BİR ARTIR.
	MOVLW	0X0A			;W = 0X0A (10)
	SUBWF	HEXLSB, F		;HEXLSB'DEN 10 ÇIKART.
	GOTO	ONLAR_KONT		;ONLAR'I YENİDEN KONTROL ET.
BİRLER_KONT
	MOVF	HEXLSB, W		;W = HEXLSB
	MOVWF	BİRLER			;BİRLER = W, DÖNÜŞÜM İŞLEMİ TAMAM.
					
;---display secimi--------------------------------------------------

TEMPDISP
	
	BSF	PORTA, 0	
	BCF	PORTA, 1	;display seç '00'( DISPLAY 0)
	BCF	PORTA, 2	
	BCF	PORTA, 3        	

	MOVF	YÜZLER, W
	CALL	TABLO
	MOVWF	PORTB		;yüzleri port b ye gönder
	CALL    gecikme 	;displey gecikme süresi
        

	BCF	PORTA, 0	
	BSF	PORTA, 1	;display seç '01'( DİSPLAY 1)
	BCF	PORTA, 2	
	BCF	PORTA, 3

	MOVF	ONLAR, W
	CALL	TABLO
	MOVWF	PORTB		;onları port b ye gönder
	CALL    gecikme 	;displey gecikme süresi
        

	BCF	PORTA, 0	
	BCF	PORTA, 1	;display seç '10'( DİSPLAY 2)
	BSF	PORTA, 2	
	BCF	PORTA, 3

	MOVF	BİRLER, W
	CALL	TABLO
	MOVWF	PORTB		;birleri port b ye gönder
	CALL    gecikme 	;displey gecikme süresi
        	

	BCF	PORTA, 0	
	BCF	PORTA, 1	;display seç '11'( DİSPLAY 3)
	BCF	PORTA, 2	
	BSF	PORTA, 3

	MOVF	TEMPD, W
	CALL	TABLO
	MOVWF	PORTB		;birleri port b ye gönder
	CALL    gecikme 	;displey gecikme süresi
        			
	BCF	PORTA, 0	
	BCF	PORTA, 1	;display seç '11'( DİSPLAY 3)
	BCF	PORTA, 2	
	BCF	PORTA, 3       	


	DECFSZ	SAYAC, F	;sayac 00 olana kadar  ekranı göster
	GOTO	TEMPDISP	;sayac 00 olana kadar goto tempdisp git
	CALL	DİSPLAYSÖNME    ;sayac 00 oldu  
	GOTO	START		;goto start git
        		
;-----------------------------------------------------------
DESARJ

	BSF	STATUS, 5	;bank1
	BCF	TRISA, 4	;porta,4 çıkış
	BCF	STATUS, 5	;bank0
	BCF	PORTA, 4	;
	
	MOVLW	d'255'
	MOVWF	GCKSAY1

DONGU1
	MOVLW	d'255'
	MOVWF	GCKSAY2
	
DONGU2
	DECFSZ	GCKSAY2, F
	GOTO	DONGU2
	DECFSZ	GCKSAY1, F
	GOTO	DONGU1
	RETURN

;------display ortak anot tablosu-----------------------------
TABLO
	ADDWF	PCL,F
	RETLW b'11000000' ; 0
	RETLW b'11111001' ; 1
	RETLW b'10100100' ; 2
	RETLW b'10110000' ; 3
	RETLW b'10011001' ; 4
	RETLW b'10010010' ; 5
	RETLW b'10000010' ; 6
	RETLW b'11111000' ; 7
	RETLW b'10000000' ; 8
	RETLW b'10010000' ; 9
;-------------------------------------------------------------
DİSPLAYSÖNME 
        movlw   d'20' 
        movwf   SAYAC1 
dona1 
        
        movlw   d'20' 
        movwf   SAYAC2
dona2
        movlw   d'20' 
        movwf   SAYAC3
dona3  
        
        decfsz  SAYAC3,f
        goto    dona3 
        decfsz  SAYAC2,f 
        goto    dona2
        decfsz  SAYAC1,f 
        goto    dona1  
        return 

;-------------------------------------------------------------
gecikme 
        movlw   d'45' 
        movwf   SAYACA 
don1 
        movlw   d'45' 
        movwf   SAYACB 
don2 
        
        decfsz  SAYACB,f
        goto    don2 
        decfsz  SAYACA,f 
        goto    don1 
        return 
;-------------------------------------------------------------
DELAY 
        movlw   d'100' 
        movwf   SAY1 
STEP1 
        movlw   d'100' 
        movwf   SAY2
STEP2 
        
        decfsz  SAY2,f
        goto    STEP2 
        decfsz  SAY1,f 
        goto    STEP1 
        return 
;--------------------------------------------------------------
	END

Tagli

Sorunun PCLATH ile ilgisi yok. TEMP sonuçta 1 byte'lık bir değişken olduğu için 255'ten yukarı gidememesi normal. Daha büyük bir sayı için 2 belki de 3 byte kullanmak gerekir. Ama belki bu da yeterli olmaz. Çünkü PIC'i 4 MHz'lik kristal ile çalıştırdığını varsayarsak, 4 us'de bir sayaç artar. Yani 2 byte kullanarak değişken sınırını 65535'e çıkarsan bile yaklaşık 0.26 saniye içinde sayaç yine taşacaktır. Gerçi bilmiyorum, kapasitörün dolma süresi nedir. Eğer 0.26 saniye içinde kapasitör dolar diyorsan 2 byte kullanmak yeterli. Yok yetmez diyorsan önünde iki seçenek var: 1) Sayaç (temp) için daha fazla byte kullanmak. 2) Sayaç döngüsünün içine bekleme koymak, ki ben olsam bunu yapardım, daha kolay olduğu için. Ama zaman ölçümünün hassasiyetini de azaltmış olursun. Uygulamanın ihtiyaçlarına göre bu seçimi yapman gerekli. Bu arada, iki durumda da dönen sayının biriminin us olmadığını hatırlatayım. İlk durumda dönen sayı 4 ile çarpılarak geçen zamanın us cinsinden değeri bulunur. Araya bekleme döngüsü koyarsan bu katsayı artacaktır.

Programla ilgili bir diğer tavsiyem de 7 segmentli göstergenin sürümünü timer2 kesmesi ile yapman. Böylece program kodunu rahatlatırsın. Kendi yazdığım bir programdan örnek vereyim:
TARA                                            ;Kesme sırasındaki tarama işlemi
                call            HANE_ADRESI     ;Basılacak değerin yeri belirleniyor
                clrf            PORTA           ;Göstergeler kapatıldı
                movwf           FSR             ;Dolaylı adresleme yapıldı
                movf            INDF,W          ;Yeni hane değeri W'ye alındı
                movwf           PORTB           ;Gösterim değeri PORTB'ye yüklendi
                call            HANE_TARAMA     ;Transistör seçim değeri okundu
                movwf           PORTA           ;Değer PORTA'ya yerleştirildi
                decfsz          haneci,F        ;Döngü kontrol ediliyor
                goto            KESME_0         ;Sıfırlanmamışsa kesmeden dönülecek
                movlw           d'4'            ;Başlangıç değeri W'ye yüklendi
                movwf           haneci          ;haneci başlangıç değerine ayarlandı
                goto            KESME_0         ;Kesmeden dönülüyor
                
HANE_ADRESI                                     ;haneci değerine göre PORTB'ye yüklenecek değer
                movf            haneci,W        ;haneci W'ye alınıyor
                addwf           PCL,F           ;PC değiştirilerek atlama yapılıyor
                nop
                retlw           h'20'           ;Hane0 adresi dönüyor
                retlw           h'21'           ;Hane1 adresi dönüyor
                retlw           h'22'           ;Hane2 adresi dönüyor
                retlw           h'23'           ;Hane3 adresi dönüyor

HANE_TARAMA                                     ;haneci değerine göre PORTA değeri alınıyor
                movf            haneci,W        ;haneci W'ye alınıyor
                addwf           PCL,F           ;PC değiştirilerek atlama yapılıyor
                nop
                retlw           b'00001000'     ;Hane0 açılıyor
                retlw           b'00000001'     ;Hane1 açılıyor
                retlw           b'00000010'     ;Hane2 açılıyor
                retlw           b'00000100'     ;Hane3 açılıyor
Burada, göstergeyi güncellemek için h'20'den h'23'e kadar olan 4 alana rakamları yazmak yeterli. Gerisi kesme içinde yapılıyor. Senin için ortaya çıkabilecek bir sorun kesmelerin ölçüm işini bozması. Ama ölçüm sırasında kesmeyi kapatabilir ve temp değeri netleşince kesmeleri açarak ekranda sayının gösterilmesini sağlayabilirsin. Elbette yukarda verdiğim kodun tamamı değil. Fikir versin diye paylaştım, ilgilenirsen ayrıntılarına girebilirim.

Ayrıca daha önce bahsettiğim TABLO meselesine de dikkat et. Şu haliyle sorun çıkarmıyor olabilir, ama yine de TABLO etiketinden hemen sonra "pageselw $" yazman, veya daha da iyisi bu tabloyu programın başlarında bir yere taşıman ilerde karşına çıkabilecek muhtemel sorunları engeller.

Ekleme: Şimdi farkettim de sayaç döngüsünde mutlaka bekleme koyman gerekiyor. 2 byte kullnmış olsan bile diyelim ki sonuç 40000 çıktı, bunu göstergede gösteremezsin. Tabi göstergenin 4 haneli olduğunu varsayıyorum.
Gökçe Tağlıoğlu

bigbey

Alıntı yapılan: "mustafaaxu"sayın bigbey radyo amatörümüsünüz.
Evet radyo amatörüyüm. Aynı zamanda Telsiz genel müdürlüğü Samsun bölge müdürlüğü teknik personeli olarak çalıştım şu an emekliyim. Kurumun şimdiki adı Bilgi teknolojileri ve iletişim kurumu.

Sizin şu an yatığınız yazılımı inceledim ve TEMP registeri 8 bitlik bir register olduğu için registerin taştığını kontrol ederek TEMP1 diye bir register daha artırıp 16 bitlik register olarak işlem yapabilirsiniz. size bir örnek yazıyorum.
COUNT 
   BCF     STATUS,C
   INCF   TEMP, F        ;TEMP değerini 1 arttır 
   BTFSC  STATUS,C
   INCF   TEMP1,F
   BTFSS   PORTA, 4       ;kapasite dolduysa 1 atla 
   GOTO   COUNT          ;kapasite dolmadıysa goro cound    

Bu şekilde yazılıma ilave yaparsanız 16 bitlik sayı elde edeceksiniz.
Bu işinizi görecekse bu sayının BCD olarak (ondalık) dönüştürüşüp displayde gösterilmesi işine geçebiliriz.
TA6R

mustafaaxu

hocam bu verdiğiniz örnekte dediğiniz gibi kesme ve fsr problem olabilir inanın o konuları bilmiyorum iki bayt durumunu biraz öğrendim bendeki koda iki bayt ekliyebilirmiyim  ve nasıl dekadeye çevirebilirim
teşekkür ederim simdiden

Tagli

Yalnız burada şöyle bir sorun var: 2 byte'lık bir sayaç da yaklaşık 0.46 saniye içinde 655535'e dayanıp taşacaktır (4 MHz kristal ile). Bu süre kapasitörün dolması için yeterli mi? Ki elde 4 basamaklı bir gösterge varsa bu sayı 9999 ile sınırlı olmak zorunda.

Daha önce de bahsettiğim gibi, sayaç döngüsünün içine bekleme koymak her ne kadar hassasiyeti azaltsa da uzun sürelerin ölçümünün gerektiği durumlarda tercih edilebilir. Şunun gibi mesela:
COUNT
   CALL   BEKLE_5MS
   INCF   TEMP, F
   BTFSS   PORTA, 4
   GOTO   COUNT


Bir diğer yöntem de kodda değişiklik yapmadan düşük frekanslı bir kristal kullanmak olabilir.
Gökçe Tağlıoğlu

mustafaaxu

sayın Bigbey
tacall book tan TA6R  baktım tam olarak birşey göremedim güncelleme  veye değşiklik varmı benim kodum TA5EK a sınıfı mersin amatörüm fazla aktif değilim maalesef     formda devamlı online olamıyorum
gec cevaplarsam özür dilerim
sayın hocam dediğiğiniz gibi konu 16 bitlik sayı ile  olacak
bcd kod 16 biti ondalığa dönüşümü bilmiyorum
zamanınız varsa 16 biti dönüştürüşüp displayde gösterilmesi işine geçebiliriz. teşekkür ederim
TA5EK 73

mustafaaxu

sayın tagli
2 byte'lık bir sayaç da benim işimi görür 9999 kadar sayması benim için yeterlidir  iki baytlık değer onluga cevirip displayde göstermek benim için yeterli  kapasite zaten kücük     r-ayarlı 50 kohm  c-100 nf

bigbey

Alıntı yapılan: "mustafaaxu"sayın Bigbey
tacall book tan TA6R  baktım tam olarak birşey göremedim
Ben kayıtlı değilim. havaya çıkmayanlardanım. :oops:
TA6R

mustafaaxu

sayın bigbey
bende amator olmadan önce baya bir heves vardı   şimdi  bende havaya çıkmıyorum amatör telsizciliği karadan götürüyoruz mersinde trac ilk kuranlardan biriydim sonra ayrıldım şimdi herhangi bir amatör derneğe kayıtlı değilim  selamlar 73...

mustafaaxu

sayın bigbey  sayın tagli
2 byte'lık bir sayaç için yardımlarınızı bekliyorum teşekkürler.

Tagli

2 byte'lık sayacın nasıl arttırılacağını bigbey daha önceki bir mesajında (ilk sayfada) anlatmıştı. Aşağıdaki kod küçük byte'ı sayac0, büyük byte'ı sayac1 olan bir sayacı işleyerek birler, onlar, yuzler ve binler değişkenlerinin içini doldurur. Ama kodu deneme fırsatım olmadı. Hata yapmış olabilirim (ki gözle kontrol ederken birkaç tane yakalayıp düzelttim). Hata varsa programın hangi girdiye hangi hatalı çıktıyı verdiğini de belirterek haber verirsen tekrardan bakarım.

Düzeltme: Daha önceden hatalı verilen kod 2. kez düzeltilmiştir.

               clrf            onlar           ;Onlar basamağı sayacı sıfırlanıyor
                clrf            yuzler          ;Yuzler basamağı sayacı sıfırlanıyor
                clrf            binler          ;Binler basamağı sayacı sıfırlanıyor

BINLER_HESAPLA
                movlw           b'11101000'     ;1000'in küçük byte'ı W'ye yüklendi
                subwf           sayac0,F        ;W, sayacın küçük byte'ından çıkarıldı
                btfsc           STATUS,C        ;Sonuç eksili mi?
                goto            $+5             ;Değilse büyük byte işlenecek
                movf            sayac1,F        ;Eksili ise sayac1 test için kendi üzerine yazılıyor
                btfsc           STATUS,Z        ;sayac1 0 mıymış? (büyük byte da mı kurtarmadı?)
                goto            BINLER_CIK_0    ;Demek ki döngü bitmis, (1000'in küçüğü) geri eklenecek
                decf            sayac1,F        ;sayac1 1 azaltılıyor
                movlw           b'00000011'     ;1000'in büyük byte'ı W'ye yüklendi
                subwf           sayac1,F        ;W, sayacın büyük byte'ından çıkarıldı
                btfss           STATUS,C        ;Sonuç eksili mi?
                goto            BINLER_CIK_1    ;Evet ise döngü bitmiş, sayaca 1000 eklenecek
                incf            binler,F        ;Binler sayacı 1 arttırılıyor
                goto            BINLER_HESAPLA  ;Döngüye devam ediliyor
BINLER_CIK_1
                movlw           b'11101000'     ;1000'in küçük byte'ı W'ye yüklendi
                addwf           sayac0,F        ;Sayacın küçük byte'ı eski haline getiriliyor
                btfsc           STATUS,C        ;Taşma var mı?
                incf            sayac1,F        ;Taşma varsa sayac1 1 arttırılacak
                movlw           b'00000011'     ;1000'in büyük byte'ı W'ye yüklendi
                addwf           sayac1,F        ;Sayacın büyük byte'ı eski haline getiriliyor
                goto            YUZLER_HESAPLA  ;Sonraki adıma geçiliyor
BINLER_CIK_0
                movlw           b'11101000'     ;1000'in küçük byte'ı W'ye yüklendi
                addwf           sayac0,F        ;Sayacın küçük byte'ı eski haline getiriliyor

YUZLER_HESAPLA
                movlw           d'100'          ;100 W'ye yüklendi
                subwf           sayac0,F        ;W, sayacın küçük byte'ından çıkarıldı
                btfsc           STATUS,C        ;Sonuç eksili mi?
                goto            $+5             ;Değilse yüzler sayacı artar
                movf            sayac1,F        ;Eksili ise sayac1 test için kendi üzerine yazılıyor
                btfsc           STATUS,Z        ;sayac1 0 mıymış? (büyük byte da mı kurtarmadı?)
                goto            YUZLER_CIK_0    ;Demek ki döngü bitmis, 100 geri eklenecek
                decf            sayac1,F        ;sayac1 1 azaltılıyor
                incf            yuzler,F        ;Yüzler sayacı 1 arttırılıyor
                goto            YUZLER_HESAPLA  ;Döngüye devam ediliyor
YUZLER_CIK_0
                movlw           d'100'          ;100 W'ye yüklendi
                addwf           sayac0,F        ;Sayacın küçük byte'ı eski haline getiriliyor

ONLAR_HESAPLA
                movlw           d'10'           ;10 W'ye yüklendi
                subwf           sayac0,F        ;W, sayacın küçük byte'ından çıkarıldı
                btfss           STATUS,C        ;Sonuç eksili mi?
                goto            ONLAR_CIK_0     ;Demek ki döngü bitmis, 10 geri eklenecek
                incf            onlar,F         ;Onlar sayacı 1 arttırılıyor
                goto            ONLAR_HESAPLA   ;Döngüye devam ediliyor
ONLAR_CIK_0
                movlw           d'10'           ;10 W'ye yüklendi
                addwf           sayac0,F        ;Sayacın küçük byte'ı eski haline getiriliyor

                movf            sayac0,W        ;Kalan değer W'ye alındı
                movwf           birler          ;Birler sayacı ayarlandı
                clrf            sayac0          ;Sonraki işlemler için sayac0 sıfırlanıyor
Gökçe Tağlıoğlu

mustafaaxu

buradaki silinme nedeni sayın taglinin düzeltmeleri sonucu hatasız çalışan
may/05/2009 daki tam kod eklendiği için buada çok yer kaplaması

bigbey

PortA,4 girişinde nasıl bir devre var?
proteusta simulasyon için bir çiziminiz varmı. Denemek için bir çizim yapalım. ama portA,4 teki uçta neler var bilmiyorum.
TA6R