selam değerli üstatlarım benim sorunum16F84A ile tablodan 255 den sonra değer alamıyorum araştırdım sarun pclath kullanamadığımdan kaynaklanıyor araştırdım ama konuyu anlayamadım lütfen bana yardımcı olurmusunuz şimdiden teşekkür ederim
örnek:
cound
incf birler
btfss portb.4
goto cound
birler dosyası 255 olunca tablodan değer almıyor
MOVFW BİRLER
CALL TABLO
MOVWF PORTB
ilgili komut PCL register'ine etki etmektedir. register 8 bit olması nedeniyle ondalık sayı olarak 255'e kadar adreslenebilir.
bunun çözümü için
ORG 0x00 başlangıc adresi
TABLO1
;255'inci satıra kadar tablo oluşturabilirsin.
ORG 0x100
TABLO2
; 2'inci 255 satırlık alan kullanabilirsin.
ORG 0x200
TABLO3
; 3'üncü 255 satırlık alan kullanabilirsin.
ORG 0x300
TABLO4
; 4'üncü 255 satırlık alan kullanabilirsin.
Not TABLO1 programda hangi satırdan başlıyor ise 255 - (başlangıç satırı) = kadar veri yazabilirsin
Aslında tablo 256'lık alandan taşabilir, yani daha büyük olabilir. Yani tablonun kafa kısmı (ADDWF PCL,F ve öncesindeki komutlar) haricinde FF ile biten bir adresten 00 ile biten bir adrese taşmasında sıkıntı yoktur, ancak bu durumda fazladan birkaç satır kod yazmak gerekir. Öncelikle taşma olup olmadığı kontrol edilmelidir. ADDWF PCL,W denilerek toplama işlemi yapılır ancak PC güncellenmez (tabi öncelikle atlama değerinin bir yerde yedeği olduğunu varsayıyorum). Onun yerine STATUS,C'ye bakılarak taşma olup olmadığı kontrol edilir. Eğer taşma varsa önce PCLATH 1 arttırılır, sonra da normalde eklenmesi gereken değer ADDWF PCL,F ile PC'a eklenerek atlama yapılır.
Tabloyu 256'dan büyük yapmak için toplanacak değerin de iki register'da saklanması gerekir. Tablonun kafa kısmının PCLATH değeri ile PCL register'ları 2 byte'lık bir adres değeri gibi düşünülür ve uygun şekilde toplama işlemi yapılır, ancak PCL hemen güncellenmez. Öncelikle sonucun büyük byte'ı PCLATH'a yazılır, sonra PCL'ye sonucun küçük byte'ı yazılarak atlama yapılır.
Dönüşte PCLATH için bir ayara gerek yoktur ancak döndükten sonra PCLATH eski haline getirilmezse sonraki GOTO ve CALL komutlarında sorun çıkacaktır.
sayın taglı ilginiz için teşekkür ederim pclath ile anlattığınız şekilde bazı yazılımlarda görmüştüm ama 255 üzerine çıkmadığım için konuyu öğrenemedim sayın hocam cok kısa olarak anlatıgınız konuyu asm olarak ekleyebilirmisiniz çok tesekkür ederim hoşçakalın
Konuyu biraz daha açayım. İşin temelini anlatmak açısından 14 bitlik komutlara sahip 16 (10 ve 12 için de geçerli) serisi PIC'lere göre durumu anlatacağım. Zira 18 serisi (ve sonrası) PIC'lerde durum biraz daha farklı.
Bilindiği üzere PIC'in program hafızasında her alanın bir adres değeri vardır. Bu değer genelde 16'lık tabanda ifade edilir. 16 serisi PIC'lerde program akışı içinde, programın o anda nerde olduğunu tutan bir sayaç vardır ki buna Program Counter (PC) denir. PC 13 bitlik bir sayıdır, yani 8192 alanı adresleyebilir.
16 serisi PIC'lerin program alanları 14 bitliktir ve her komut 1 alan kaplar. GOTO ve CALL komutları başka bir program alanına atlamayı gerektirdiğinden içlerinde 13 bitlik adres değerini bulundurmaları gerekir. Ama sorun şudur ki zaten 14 bitlik olan kumutların içine, komutun ne olduğunu tanımlayacak birkaç bit gerektiğini de düşünürsek 13 bitlik bir adresi sığdırmak mümkün değildir. O yüzden komutlarda adresin sadece küçük 11 bitine yer verilir. GOTO ve CALL komutu çağrıldığında diğer 2 bit PCLATH register'ındaki değerlerden alınarak atlama yapılır.
PC'ın düşük 8 biti RAM alanında adreslenmiştir, yani kullanıcı tarafından doğrudan ulaşılabilir. Bu alanda değişiklik yapıldığında atlama adresinin geriye kalan 5 biti PCLATH'den gelir.
Önce bir RETLW tablosunun normal yapısını inceleyelim. "SIRA" değişkeni tabloda gitmek istediğimiz yerin indeksi olsun ve tablo çağrılmadan bu değişkenin (register'ın) doldurulduğunu varsayalım.
ORG 100 ;Örnek adres değeri
TABLO
MOVF SIRA,W ;SIRA'daki değer W'ye alındı
ADDWF PCL,F ;PC değiştirilerek atlama yapılıyor
RETLW .....
RETLW .....
Burda CALL TABLO ile tabloya gidilmeden önce genelde "pageselw TABLO" yazılarak assembler'ın PCLATH'ı TABLO'nun adresine göre ayarlaması sağlanır. Tablonun başlangıç adresi, bu iki satırlık kafa koduyla mümkün olan en geniş alana sahip olmak için genelde sonu 00 ile biten bir adrese alanır. Çünkü tablonun içinde adres değerlerinde mesela 2FF'den 300'e geçme varsa burda sorun çıkmaktadır. Bunun sebebi de bu geçiş sırasında PC'ın 8. bitinin değişmesidir, yani PCLATH'ın en küçük biti. ADDWF PCL,F PCLATH'a müdahele etmez.
Şimdi de böyle bir taşmaya karşı nasıl önlem alınacağını görelim. Burda tablo yine 256'dan büyük değil, ama hafızada bulunduğu bölgede mesela 00FF'den 0100'e taşma olmuş.
TABLO
MOVF SIRA,W ;SIRA'daki değer W'ye alındı
ADDWF PCL,W ;Test amaçlı toplama işlemi yapılıyor
BTFSC STATUS,C ;Taşma olmuş mu?
INCF PCLATH,F ;Taşma varsa PCLATH 1 arttırılacak
MOVF SIRA,W ;SIRA'daki değer tekrardan W'ye alındı
ADDWF PCL,F ;PC değiştirilerek atlama yapılıyor.
RETLW ....
RETLW ....
Bu arada, daha önce bahsetmeyi unutmuşum, derlediğin (daha doğrusu assemble ettiğin) kodun hafızada nereye düştüğünü MPLAB'de View -> Program Memory seçeneğine tıklayarak görebilirsin. Bunu yapmak için önce kodu derlemen gerekir.
Şimdi de tablonun 256'dan büyük olduğu durumu ele alalım. Burda 2 byte'a ihtiyacımız var. Küçük byte'ı SIRA0, büyük byte'ı SIRA1 ile ifade edelim.
TABLO
MOVF SIRA0,W ;Küçük byte W'ye alındı
ADDWF PCL,W ;Test amaçlı toplama işlemi yapılıyor
BTFSC STATUS,C ;Taşma olmuş mu?
INCF PCLATH,F ;Taşma varsa PCLATH 1 arttırılacak
MOVF SIRA1,W ;Büyük byte W'ye alındı
ADDWF PCLATH,F ;PCLATH büyük byte ile toplanarak güncellendi
MOVF SIRA0,W ;Küçük byte W'ye alındı
ADDWF PCL,F ;PC değiştirilerek atlama yapılıyor.
RETLW ....
RETLW ....
Daha önce de belirttiğim gibi, TABLO'ya CALL ile gidilmeden önce PCLATH'ın uygun şekilde ayarlanması ("pageselw TABLO" yazılırsa MPLAB bu işi yapar) ve kafa kısmı dediğim, yani RETLW'lerden önceki bölümün xxFF'den xx00'a taşan bir adreste bulunmaması gerekiyor. Ayrıca GOTO tabloları için yukarıda bahsettiğim yöntemler geçerli değil, çünkü GOTO'ların hedeflerinin GOTO ile aynı page'de (2048'lik hafıza alanı) olması gerekir. Bu şart sağlanırsa ancak yukarda bahsettiğim kodlar GOTO tabloları için kullanılabilir. Bu arada, pageselw'nin aslında bir MOVLW - MOVWF ikilisi olduğu kullanıldığında W'deki mevcut değeri bozacağı unutulmamalı.
Umarım yazdıklarım yeterince açıklayıcı olmuştur. Bir hata yaptıysam affola.
sayın taglı hocam tekkür ederim yazdıklarını iyice anlayıp takıldığım yerleri tekrar soracağım ben yeni başladım yaş 50 biraz ağır oluyor kusura bakma tesekkürler.....73
sayın tagli hocam
burada yapmak istediğimi anlatayım sana kolaylık olsun
INCF TEMP dasyasını bir artırıyoruz ve kapasiteyi kontrol ediyoruz
doluysa temp in iceriğini W yüklüyoruz W yi tekrar HEXLSB yüklüyoruz
hexlsb dekadeye cevirip displeyde gösteriyoruz işlem şöyle
hexlsb 100 çikarıp kontrol ediyoruz 100 den fazla ise yüzlere 1 ekliyoruz
hexlsb dende 100 çikarıyoruz kalanı tekrar kontrol ediyoruz
onlara gecip aynı işlemleri tekrar ediyoruz işlem bitince
yüzler .. onlar.. ve birler içindeki değerleri displeye gönderiyoruz
hocam mümkünse
aşağıda asm ye pclath eklesen sevinirim teşekkür ederim
;--- deneme 255 sonra 256 gelmiyor---------
COUNT
INCF TEMP, F ;TEMPA SAYACINI 1 ARTTIR
BTFSS PORTA, 4 ;KONDANSATÖR DOLDU MU?
GOTO COUNT
;---------------------------------------------------------
MOVF TEMP,W ;dolduysa temp W yükle
MOVWF HEXLSB ;W yi hexlsb yükle
;---------------------------------------------------------
YÜZLER_KONT
MOVLW 0X64 ;W = 0X64 (100)
SUBWF HEXLSB, W ;HEXLSB'DEN 100 ÇIKART.
BTFSS STATUS, C ;SONUÇ >= 100 DEN BÜYÜKMÜ
GOTO ONLAR_KONT ;HAYIR İSE ONLAR KONTROL ET.
INCF YÜZLER, F ;EVET İSE YÜZLER BİR ARTIR.
MOVLW 0X64 ;W = 0X64 (100)
SUBWF HEXLSB, F ;HEXLSB'DEN 100 ÇIKART.
GOTO YÜZLER_KONT ;ONLAR'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 YÜZLER_KONT ;ONLAR'I YENİDEN KONTROL ET.
BİRLER_KONT
MOVF HEXLSB, W ;W = HEXLSB
MOVWF BİRLER ;BİRLER = W,
;---burada display secimi yapıyoruz--------------------
;---ve displeye yazdırmak için tobloya gidiyoruz
;----TABLO--------------------------------------
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
;-----------------------------------
16F84'ün hafızası zaten 1024 word olduğundan GOTO ve CALL'larla ilgili bir sorun olmayacaktır. Sanırım şu şekilde yazman yeterli olur:
TABLO
pageselw $ ;PCLATH bulunulan yere göre ayarlanıyor
ADDWF PCL,F
RETLW...
RETLW...
Tablo zaten küçük. Bunun için FF'ten 00'a taşma kontrolü yapmaktansa tabloyu uygun şekilde yerleştirmek çok daha kolay olacaktır. Programının hafızaya nasıl yerleştiğini bilemem. Bunu anlamak için daha önce de bahsettiğim üzere MPLAB'den Program Memory bölümüne bakmalısın. O zaman bir taşma olup olmadığını görebilirsin. Bu taşmalar kabaca 256 satırda bir olur (aslında tam olarak 256 komutta bir olur). Yani bu tabloyu alıp programın başlarında bir yere koyarsan muhtemelen pageselw $ yazmana bile gerek kalmaz.
sayın taglı hocam tekkür ederim yazdıklarını toparlamaya çalışıyorum
bildiginiz gibi proğramı yazmak ayrı bir sorun protoboart a devreyi kurup çalıştırma ayrı bir dert tekrar yardımını isteyeceğim cok sağol
bu arada sayın bigbey selam vereyim
sayın bigbey
ilginiz için çok teşekkür ederim anladıgım kadarı ile
tablo 1 İLE 0.....255 kadar saydır
tablo 2 İLE 255.....512
tablo 3 İLE 512 .....768 kadar saydır diyorsun
olayı tam kavrayamadım sayıları örneklersem
;--------------------------------------
COUNT
INCF TEMP, F ;TEMPA SAYACINI 1 ARTTIR
BTFSS PORTA, 4 ;KONDANSATÖR DOLDU MU? DOLDUYSA EĞER
GOTO COUNT
;---------------------------------------
MOVF TEMP, W
CALL TABLO1
MOVWF PORTB
;---------------------------------------
TABLO1
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
;-----------------------------------------
TABLO2
ADDWF PCL,F
devamını gene retlw 1,2,3,,,0 diyemi yazacağız
bende 255 kadar sayıyor 256 gecin ce 000...001...002 diye devam ediyor
burayı biraz açarmısın teşekkürler
TA5EK...73...
Tablo boyutu zaten 10 değil mi? Yani 10 rakam için 7 segmentli göstergede kullanılacak değerleri döndürecek, doğru mu anlamışım? Tablonun sonunda neden tekrardan 0 olduğunu anlamadım. Ayrıca neden birden fazla tablo gerektiğini de anlamadım.
Selam,
Alıntı yapılan: "mustafaaxu"benim sorunum16F84A ile tablodan 255 den sonra değer alamıyorum araştırdım sarun pclath kullanamadığımdan kaynaklanıyor
Sorudan anladığım 255 ten daha fazla tablo değerini nasıl kullanabileceğimiz diye anladım va buna göre bir örnek verdim. soruyu doğrumu anladım?
Burada sonradan gördüğüm kadarıyle 0 - 9 arası 7segment değerlerini oluşturmak olarak görünüyor.
Benim sorudan anladığım sanırım farklı oldu.
Alıntı yapılan: "bigbey"Sorudan anladığım 255 ten daha fazla tablo değerini nasıl kullanabileceğimiz diye anladım va buna göre bir örnek verdim. soruyu doğrumu anladım?
Ben de öyle anlamıştım. Ama şimdi kafam karışmış durumda.
@mustafaaxu, konuya açıklık getirirsen sevinirim.
sayın bigbey ve tagli
özür dilerim galiba hata benden kaynaklanıyor konuyu tam anlatamadım eğer incelemek isterseniz tam asm kodu ekliyebilirim
konuyu sizlerin yardımıile öğrenmek istiyorum
tablo da haklısınız acele ile tabloyu yapıştırırken fazladan almışım sıfır yok kod üzerinde düzeltim
tekrarlarsam şöyle toparlıyayım bir dosyanın içindeki bir sayıyı arttırıyorum kapasitemiz dolana kadar saydırıyoruz sonra bu dosyayı içeriğinden yüz çıkarıyoruz 100 den fazlamı kontrol ediyoruz fazla ise yüzleri 1 artiriyoruz
yüzden kücük se onlara aynı işlemi yapıyoruz kalanıda birlere ekliyoruz
displeye yüzler ..onlar...ve birleri yazdırınca sonucu görüyoruz
sorunbenim yaptığım bu kondansatörü şarz eden ayarlı direnci 255 sayısını gösterecek sekilde ayarlıyorum sonra trimpotu degerini değiştirerek 256 göstermesini istediğimde 000..001 gösteriyor
burada 255 den sonra 256 gelmesi için ne yapmalıyız
teşekkür ederim
siz analog bir değer okuyorsunuz öylemi
yazdığınız kodları bi koyun buraya olayı daha hızlı kavrar çözeriz
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..
Burada bir yanlış anlama var. 16F84a analog okuma yapamaz böyle bir donanıma sahip değil.
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
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.
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.
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
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.
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
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
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:
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...
sayın bigbey sayın tagli
2 byte'lık bir sayaç için yardımlarınızı bekliyorum teşekkürler.
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
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ı
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.
sayın taglisayın bigbey
semayı eklemeyi beceremedim
50 kohm ayarli direncin değeri ile oynadıkça kapasitenin dolumunda geçen süreyi dekadeye çevirip göreceğiz önceki verdiğim kod ile 225 kadar getiriyorum 255 den sonra 0000 geliyor anlattıklarınız ve verdiginiz örneklerden ile konuyu iyice anladım dosyanın içerigi 8 bit lik sayı alabiliyor b'11111111' buda 255 eşit biz taşma yı kontrol ederek üst byte
1 eliyecegiz üstbyte 1 değerinide kullanarak 256 yapacağız işte tam burda kopuyorum. hocam birde nasıl çizim i ekliyeceğim epey uğraştim olmadı şemayı ekliyemedim
porta,4 te gnd den ra4 100 nf vcc den 50 kohm trimpot ra4
{-}gnd-----100 nf----->PORTA,4>-----50KOHM-----VCC{+}
selamlar
sayın tagli
verviş olduğunuz örnek kod u derledim derlemede sorun yok hex i 16f84 yükledim devreyi çalıştırdığımda sorun displeylerde bazı oo10 gigi degişik rakamlar beliriyor sayıcı0 -sayıcı1 icine
MOVLW d'255'
MOVWF SAYAC1
MOVLW d'150'
MOVWF SAYAC0
rasgele değerleri yükledim gene sonuc alamadım
selamlar
Carry Bit'in çalışmasıyla ilgili bazı büyük dikkatsizlikler yapmışım, şöyle ki btfsc'lerin yerine btfss olması gerekiyor. Ama bu da yeterli değil. Bu dikkatsizliğim haricinde decf komutunun 16 serisinde C'yi etkilemediği gözümden kaçmış. Aslında datasheet'e bakma ihtiyacı duymuştum ama o sırada yanımda kağıda çıkarılmış 18F452 komut seti vardı ve ondan bakmıştım. 18 serisinde decf C'yi de etkiliyor. Beni yanıltan bu oldu. Kodu düzeltince yenisini buraya eklerim. Hatalar ve gecikme için üzgünüm...
(http://img198.imageshack.us/img198/7889/upcount.th.jpg) (http://img198.imageshack.us/i/upcount.jpg/)
Daha önceki mesajımda bulunan kodu düzelttim. Oradan alabilirsin. Kodu (kendi yazdığım parçalayıcıyı) denedim, çalışıyor gibi. Yine de gözümden birşey kaçmışsa haber ver.
Ufak bir hatırlatma, kod 9999'dan büyük bir sayı için çalışmayacaktır, çok garip sonuçlar verebilir, ama belki de vermez, emin değilim. En iyi ihtimalle küçük 4 basamağı görebilirsin.
sayın tagli
düzelttiğiniz kodu ekleyerek yeniden derleyip akşam evde deneyeceğim
evde foruma giremiyorum problemleri paylaşırız
semayı görebildinizmi sizin dediğiniz gibi yaptım
acaba başkaları görebiliyormu
selamlar
sayın tagli
son düzeltme yaptığınız kodu
üzerinde sayıcı 0000-9999 olarak caliştiğimiz asm ekledim ve derledim
deney setinde çalıştırdım bir iki sorun var ra4 te bağlı olan r-50 k ve c-100nf
ikilisinden r ile değer değistirdiğimde 232 nin alttında 487 gösteriyor
TABLO
232-----altını göstermiyor
...........
sayac0 değeri
229------>485 gösteriyor hatalı
230------>486 gösteriyor hatalı
231------>487 gösteriyor hatalı
.....232 üstü...........................
232------>232 gösteriyor doğru
233------>233 gösteriyor doğru
234------>234 gösteriyor doğru
235------>235 gösteriyor doğru
236------>236 gösteriyor doğru
>> >>
255------>255 gösteriyor doğru
COUNT
BCF STATUS,C
INCF sayac0, F ;TEMP değerini 1 arttır
BTFSC STATUS,C
INCF sayac1,F
BTFSS PORTA, 4 ;kapasite dolduysa 1 atla
GOTO COUNT ;kapasite dolmadıysa goro cound
?count dongüsü uygunmu ?
sayac0 sayac1 count dongüsünde tablodaki hatali gösterimler oluyor
***********************************************
bu hataların count sayıcısından olabilir diyerek sayac0 sayac1
direk değer girdim
movlw b'11111111'
movwf sayac0
movlw b'00000001'
movwf sayac1
sayac0=255
sayac1=1
sayac0=254 sayac1=1------>511 gösteriyor doğru
sayac0=40 sayac1=1------>296 gösteriyor doğru
sayac0=10 sayac1=1------>778 gösteriyor yanlış
sayac0=26 sayac1=1------>794 gösteriyor yanlış
yine 232 in altı hatalı görüküyor
yukarıdaki uygulamada sayıları direk girersem
acaba yanlışmı düşünüyorum
sayac0=10
sayac1=1------->265 görmemiz gerekiyor
hocam problemler bunlar teşekkür ederim
mustafaaxu, uyarın üzerine ben de testler yaptım. Gerçekten de 232'nin altında sorun vardı, ki bu sorun muhtemelen senin test etmediğin daha büyük sayılarda da kendini gösterecek nitelikteydi. Ancak yanlış sonuç verdiğini raporladığın bazı testlerde ise sorunla karşılaşmadım, mesela sayac0=26 sayac1=1 ikilisi doğru bir şekilde 282 gösteriyor idi.
Hata binler basamağının hesabındaki son bölümden kaynaklanıyormuş. Şu şekilde değiştirilmesi gerekiyor (yukarıdaki kodda da düzelttim):
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
Ayrıca;
Görünen o ki bigbey de Carry Bit konusunda benimle aynı hataya düşmüş, count döngüsünde hata var. Çünkü 16 serisi PIC'lerde incf komutunun C üzerinde etkisi yok, sadece Z'yi etkiliyor. Bu durumda C'yi Z yapmak sorunun çözümü için yeterli olacaktır. Şöyle ki:
COUNT
INCF sayac0, F ;TEMP değerini 1 arttır
BTFSC STATUS,Z
INCF sayac1,F
BTFSS PORTA, 4 ;kapasite dolduysa 1 atla
GOTO COUNT ;kapasite dolmadıysa goro cound
İşlemden önce Z'nin sıfırlanmasına gerek olmadığından o satırı sildim.
Umarım başka hata yoktur. Kusra bakma, kodu yazdıktan sonra kapsamlı bir test yapmak pek mümkün olmuyor ve böyle hatalar çıkabiliyor. Umarım başka yoktur. Varsa da ben yine buradayım :).
sayıın tagli
değerli arkadaşım yardımların için çok teşekkür ederim
umarım bu konuyu takip eden benim gibi yeni başlıyanlar sizin bilğinizden faydalanmışlardır.
hocam bende status,c ile sorun yaşadım iki byte sayarken status,c etkilemek için daha önce aşağıdaki çikarma işlemini uyguladım
COUNT
INCF HEXLSB, F ;HEXLSB SAYACINI 1 ARTTIR
MOVLW D'255'
SUBWF HEXLSB, W
BTFSC STATUS, C ;CARRY FLAG 1 Mİ?
INCF HEXMSB, F ;HEXMSB SAYACINI 1 ARTTIR
BTFSS PORTA, 4 ;KONDANSATÖR DOLDU MU? DOLDUYSA EĞER
GOTO COUNT
----------------------------------------------------------------
status,c sizin kodu ile değiştirerek derleyeceğim
COUNT
INCF sayac0, F ;TEMP değerini 1 arttır
BTFSC STATUS,Z
INCF sayac1,F
BTFSS PORTA, 4 ;kapasite dolduysa 1 atla
GOTO COUNT ;kapasite dolmadıysa goro cound
hocam akşam denedikten sonra hata olursa detayları bildiririm
sellamlar
sayın tagli
hocam son yaptığınız değişiklerle tekrar derledim
tamam sonuç çok iyi 0000->1500 e kadar saydırdım
hocam tam olarak düzenlenmiş asm ve hex kodu veriyorum
bu haliyle problem yok
çok sağol
hocam müsait olduğunuzda şu cblock ve fsr birde porttan keypet ile
W ye nasıl sayı giebiliriz bu konuyu mümkünse öğretebilirmisin.
;-----sayıcı--thanksgiving to tagli----------------------------
; 0000 dan 9999 kadar sayıcı
; port a 4 kontrollu
;-----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'
birler EQU H'1B'
HEXLSB EQU H'1C'
onlar EQU H'1D'
yuzler EQU H'1F'
binler EQU H'21'
sayac0 EQU H'18'
sayac1 EQU H'19'
;------------------------------------------------------------------------------
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 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
;-------------------------------------------------------------
MOVLW d'100'
MOVWF SAYAC ;ekranda kalma süresi
;------------------------------------------------------------
degeroku
CALL DESARJ ;kapasitenin boşalmalması için bekleme
BSF PORTA, 4 ;port a,4 giris ayarlandı
;-----sayıcı----------------------------------------------
COUNT
INCF sayac0, F ;TEMP değerini 1 arttır
BTFSC STATUS,Z
INCF sayac1,F
BTFSS PORTA, 4 ;kapasite dolduysa 1 atla
GOTO COUNT ;kapasite dolmadıysa goro cound
; movlw b'00001010' ;direk sayac0 icine yüklme
; movwf sayac0
; movlw b'00000000' ;direk sayac1 icine yüklme
; movwf sayac1
;------binary dekade convert-----------------------------------------------------
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
;---display secimi--------------------------------------------------
DISPLEY_SEC_YAZ
BSF PORTA, 0
BCF PORTA, 1 ;display seç '00'( DISPLAY 0)
BCF PORTA, 2
BCF PORTA, 3
MOVF binler, 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ç '00'( DISPLAY 0)
BCF PORTA, 2
BCF PORTA, 3
MOVF yuzler, W
CALL TABLO
MOVWF PORTB ;yüzleri port b ye gönder
CALL gecikme ;displey gecikme süresi
BCF PORTA, 0
BCF PORTA, 1 ;display seç '01'( DİSPLAY 1)
BSF 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)
BCF PORTA, 2
BSF PORTA, 3
MOVF birler, W
CALL TABLO
MOVWF PORTB ;birleri port b ye gönder
CALL gecikme ;displey gecikme süresi
BCF PORTA, 0
BCF PORTA, 1 ;DİSP TEMİZLE
BCF PORTA, 2
BCF PORTA, 3
DECFSZ SAYAC, F ;sayac 00 olana kadar ekranı göster
GOTO DISPLEY_SEC_YAZ ;sayac 00 olana kadar GÖSTER
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
hex kodu
;*************************************************
;****hex kodu*************************************
:100000008316003085000030860083129D019F0119
:10001000A10164309A006B200516980A0319990A09
:10002000051E0D289D019F01A101E83098020318CB
:100030001D28990803192A28990303309902031CE3
:100040002328A10A1528E83098070318990A0330D5
:1000500099072C28E8309807643098020318342850
:1000600099080319362899039F0A2C2864309807A9
:100070000A309802031C3E289D0A38280A30980747
:1000800018089B0098010514851005118511210899
:1000900078208600902005108514051185111F0811
:1000A00078208600902005108510051585111D0803
:1000B00078208600902005108510051185151B08F5
:1000C00078208600902005108510051185119A0B67
:1000D0004328832000288316051283120512FF305F
:1000E0009500FF309600960B7328950B7128080039
:1000F0008207C034F934A434B03499349234823451
:10010000F83480349034143092001430930014305A
:100110009400940B8928930B8728920B852808005C
:100120002D3090002D309100910B9428900B922847
:10013000080064308C0064308D008D0B9D288C0B82
:040140009B280800F0
:02400E00F93F78
:00000001FF
;------------------------------------------------
sağol
sayın tagli
selamlar count döngüsünde anlayamadiğim bir şey var
yapmak istediğim sizin yazdığınız ondalık çeviriciyi
0 dan 1-2-3-4-5----------->9999 saydırmak
hocam yazılımda BTFSS PORTA, 4 işlenirken sorun yok burada
kapasite dolarken geçen süreyi saydırıyoruz şunu denedim
; BTFSS PORTA, 4 atlayıp
GOTO COUNT atlayıp sayac0 içeriği 255 den sonra sayac1 yapabilirmiyiz denedim olmuyor
rica etsem bu konuda yardımcı olurmusun toparlarsak tam olarak
BTFSS PORTA, 4 ;kapasite dolduysa 1 atla
bu komutu kullanmadan sayac0 ve sayac1 saydıracağız
su an çalışan kod nasıl bir değişiklik yapalım
teşekkür ederim
;-----sayıcı----------------------------------------------
COUNT
INCF sayac0, F ;TEMP değerini 1 arttır
BTFSC STATUS,Z ; status,z 0 mi 0 ise atla
INCF sayac1,F ;status,z 1 ise sayac1 1 arttır
BTFSS PORTA, 4 ;kapasite dolduysa 1 atla
GOTO COUNT ;kapasite dolmadıysa goro cound
;------binary dekade convert-----------------------------
sayın mustafaaxu anladığım kadarıyla kondansatör dolum işlemini değil, normal 0-9999 arası saydırmak istiyorsunuz. O zaman kod şöyle olmalı:
;-----sayıcı----------------------------------------------
COUNT
INCF sayac0, F ;TEMP değerini 1 arttır
BTFSC STATUS,Z ; status,z 0 mi 0 ise atla
INCF sayac1,F ;status,z 1 ise sayac1 1 arttır
call gecik_ ;BURAYA BİR GECİKME KOYMAK GEREKİYOR Kİ SAYMA İŞLEMİ GÖRÜLEBİLSİN..
;GOTO COUNT ;kapasite dolmadıysa goro cound !BU SATIR DA SİLİNECEK!!!!
;------binary dekade convert-----------------------------
Siz btfss porta,4 satırını silfdiğiniz için program COUNT içinde sonsuz döngüye giriyor. goto count komutundan dolayı bu komutu da silin ve araya yukarıdaki gibi bir gecikme koyun böylece istediğiniz sürede saydırırsınız.
güzel bi başlık olmuş, benim de düşündüğüm ama kod yazmaya üşendiğim bir konuydu , elinize aklınıza sağlık:)
ben displayleri 74hc595 port çoklayıcı ile çalıştırmıştım , fakat siz aynı dataları bütün displaylere bağlayıp tarama yapıyorsunuz sanırım.
Sormak istediğim bir pic çıkışına kaç tane bu şekilde display bağlanabilir.
Daha doğrusu bu 4 adet displayi aynı anda aktif edersek pic'in çıkışı bunu kaldırabilir mi?
Tarama ile sırayla çalıştığından bir yüklenme olmuyor sanırım..?
4 adet gösterge (veya daha fazla) hiçbir zaman aynı anda yanmıyor. Çekilen akım aslında her göstergede en fazla kaç LED'in yandığıyla ilgili, ki noktayı da sayarsak en fazla 8 adet olabilir. Elektronikten pek anlamadığım için (daha çok programlama işene yönelmiş bulunmaktayım) riske girmeyip transistör kullanmıştım bir uygulamamda. Belki de hiç gerek yoktu, bunu bilemem. İnternette bu ortak anotların (veya katotların) PIC'e doğrudan bağlandığını gösteren şemalar da gördüm. Aslında bu göstergede kullanılan LED'lerin özelliğine de bağlı. PIC ile sürmeden önce bir breadboard'a bağlanıp tüm LED'ler yakılarak ne kadar akım çektiğine bakılabilir, sonra da bunun PIC'in sınırları içinde olup olmadığı kontrol edilir (25 mA civarında).
Bu Başlık bu konuda ders notu kalitesinde olmuş:)
Ben bu yazdığınız kodları ortak katot , 4'lü 7 segment için 0-9999 sayıcı şeklinde tekrardan düzenledim.
Yazdığım ilk programda hazırladığınız kodları bozmamaya çalıştım fakat bu kodlar ile Tarama yöntemi ile 7 segment sürülmesi verimli değil. Çünkü Tarama işlemin yaptıktan sonra program tekrar ana kodlara döndüğü zaman 7 segmentte gösterilecek 2 sayı arası bekleme yapıyor. Yani 4 basamaklı sayımız sürekli bir şekilde displayde gözükmüyor. Tabi şu an ki program sadece 9999 sayıcı olduğu için böyle bir etki görülmedi ama uzun programlarda sorun çıkartacağı kesin. O yüzden displayde tarama ile sayı gösterme Tagli 'nın dediği gibi kesme ile yapılmalı yani ana programa paralel bir şekilde çalışmalı.
Tagli'nin kodlarını çözdüğümde bu programı o şekilde düzelteceğim:)
Tamam tarama yöntemi ile sadece 1 bölme 7 segmentin harcadığı kadar enerji harcanıyor ama enerjinin sınırlı olmadığı yerlerde bu yöntemi kullanmak çok hammallık. Şahsen Sadece tarama ile çalıştırılabilen bu 4lü 7 segmentleri kullanmak yerine teklilerden 4 tane alıp 74595 ile tarama yapmadan sürerim , bence daha iyi.
Son olarak da aşağıdaki devreye 74595 ekleyince 16f84 display dışında başka işlemler de yapabilecek hale gelecektir.
Konu başlığı da değiştirilirse iyi olur.
(http://img87.imageshack.us/img87/9196/adsz1g.th.jpg) (http://img87.imageshack.us/i/adsz1g.jpg/)
;Buton ile 4'lü 7 Segment LED'li 0-9999 Sayıcı
;1.BUTONA BASILDIĞINDA PROGRAM ÇALIŞMAYA BAŞLAR
;7 Segment LED ortak KATOT(-) uçludur.
;Kristal tipi HS olduğundan 4-20MHz osilatör seçilebilir
LIST P=16F84A
include "P16F84A.inc"
__CONFIG _WDT_OFF & _HS_OSC & _PWRTE_ON & _CP_OFF
ORG 0x00
GOTO PRG
;=========Kaydediciler=========
DONGU1 EQU 0C
DONGU2 EQU 0D
dtekrar EQU 0E
onlar EQU 10
yuzler EQU 11
binler EQU 12
birler EQU 13
sayac0 EQU 14
sayac1 EQU 15
sayici0 EQU 16
sayici1 EQU 17
;=========Display Tarama Gecikmesi=====
GECIKME
movlw .100
movwf DONGU1
B000
movlw .10
movwf DONGU2
B011
decfsz DONGU2,F
GOTO B011
decfsz DONGU1,F
GOTO B000
RETURN
;==========2byte binary 'den 4 basamak decimal'e dönüşüm===========
SAYI_CEVIR
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,0 ;Kalan değer W'ye alındı
movwf birler ;Birler sayacı ayarlandı
clrf sayac0 ;Sonraki işlemler için sayac0 sıfırlanıyor
RETURN
;==========Gösterilecek Sayının binary karşılığı ORTAK KATOT=======
TABLO
addwf PCL,1
DT 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x7,0x7F,0x6F
return
;==========7 Segment TARAMA===============
DISPLEY_SEC_YAZ
bcf PORTA, 0 ;( DISPLAY 0)
bsf PORTA, 1
bsf PORTA, 2
bsf PORTA, 3
movf binler, W
CALL TABLO
movwf PORTB ;binleri port b ye gönder
CALL GECIKME ;displey gecikme süresi
bsf PORTA, 0
bcf PORTA, 1 ;( DISPLAY 1)
bsf PORTA, 2
bsf PORTA, 3
movf yuzler, W
CALL TABLO
movwf PORTB ;yüzleri port b ye gönder
CALL GECIKME ;displey gecikme süresi
bsf PORTA, 0
bsf PORTA, 1
bcf PORTA, 2 ;( DİSPLAY 2)
bsf PORTA, 3
movf onlar, W
CALL TABLO
movwf PORTB ;onları port b ye gönder
CALL GECIKME ;displey gecikme süresi
bsf PORTA, 0
bsf PORTA, 1 ;( DİSPLAY 3)
bsf PORTA, 2
BCF PORTA, 3
movf birler, W
CALL TABLO
movwf PORTB ;birleri port b ye gönder
CALL GECIKME ;displey gecikme süresi
DECFSZ dtekrar, F ;sayac 0 olana kadar ekranı göster
GOTO DISPLEY_SEC_YAZ ;sayac 00 olana kadar GÖSTER
bsf PORTA, 0
bsf PORTA, 1 ;DİSP TEMİZLE
bsf PORTA, 2
bsf PORTA, 3
RETURN
;==========KONFİGÜRASYON===========
PRG
bsf STATUS,5 ;Bank1'e geç
movlw b'00000000'
movwf TRISB ;B portunu çıkış olarak ata
movlw b'11110000' ;RA4 giriş,diğerleri çıkş
movwf TRISA
bcf STATUS,5 ;Bank0'a geç
movlw b'00001111' ;Display'ler kapalı
movwf PORTA
movlw b'00000000'
movwf PORTB
;==========ANA PROGRAM=============
KONTROL
btfss PORTA,4 ;RA0 1 ise 1 satır atla ;Butona Basıldı mı?
GOTO KONTROL
SIFIRLA
clrf sayici0
clrf sayici1
SAYICI ;0-9999 arası sürekli olarak sayan program
incf sayici0, F ;sayici0 ve sayici1 'den oluşan 2byte'lik sayıcı
btfsc STATUS,Z ;sayici0 alcak değerlikli,sayici1 yüksek değerlikli
incf sayici1,F
movf sayici0,w ;sayici0 ve sayici1 , 10'luk sisteme çevirilmek üzere sayac0 ve sayac1'e yazılır.
movwf sayac0
movf sayici1,w
movwf sayac1
movlw 3 ;7 Segment tekrarlama sayısı
movwf dtekrar
CALL SAYI_CEVIR ;16bitlik binary sayıyı 10'luk bileşenine ayırır
CALL DISPLEY_SEC_YAZ ;4 basamaklı sayıyı 7segmentte gösterir
movlw b'00100111' ;sayici 9999 oldu mu?
subwf sayici1,w
btfss STATUS,Z ;sonuc 0 mı,0'sa 1 satır atla
GOTO SAYICI
movlw b'00001111'
subwf sayici0,w
btfss STATUS,Z ;sonuc 0'mı ,0'sa 1 satır atla
GOTO SAYICI
GOTO SIFIRLA
END
Merhaba Arkadaşlar,
Konu PCLATH ile başlayıp, sonrasında proje çözümlemesine doğru gitmiş görünüyor...
Hazır PCLATH'ın dumanı tüterken, 22.Ekim.2204'te hazırladığım bir bilgi dökümanını sizinle paylaşayım.
PCLATH.pdf (http://rapidshare.com/files/264522463/pclath.pdf.html) Rapidshare.com'da..... (http://rapidshare.com/files/264577438/pclath.rar)
Ayrıca,
PCLATH.pdf (http://www.4shared.com/file/123408665/cccbecf1/pclath.html) 4Shared.com'da.....
Dilerim işinize yarar...
Saygılarımla....
Bu da Aynı devrenin 74595 ile yapılmış hali , B portu bu şekilde tamamen boşta:
(http://img259.imageshack.us/img259/756/bportubos.jpg)
;Buton ile 4'lü 7 Segment LED'li 0-9999 Sayıcı 07.08.2009
;2 Adet 74hc595 ile Port çoklama yapılmıştır
;1.BUTONA BASILDIĞINDA PROGRAM ÇALIŞMAYA BAŞLAR
;7 Segment LED ortak KATOT(-) uçludur.
;Kristal tipi HS olduğundan 4-20MHz osilatör seçilebilir
LIST P=16F84A
include "P16F84A.inc"
__CONFIG _WDT_OFF & _HS_OSC & _PWRTE_ON & _CP_OFF
ORG 0x00
GOTO PRG
;=========Kaydediciler=========
DONGU1 EQU 0C
DONGU2 EQU 0D
dtekrar EQU 0E
onlar EQU 10
yuzler EQU 11
binler EQU 12
birler EQU 13
sayac0 EQU 14
sayac1 EQU 15
sayici0 EQU 16
sayici1 EQU 17
;=========Display Tarama Gecikmesi=====
GECIKME
movlw .100
movwf DONGU1
B000
movlw .10
movwf DONGU2
B011
decfsz DONGU2,F
GOTO B011
decfsz DONGU1,F
GOTO B000
RETURN
;==========2byte binary 'den 4 basamak decimal'e dönüşüm===========
SAYI_CEVIR
movf sayici0,w ;sayici0 ve sayici1 , 10'luk sisteme çevirilmek üzere sayac0 ve sayac1'e yazılır.
movwf sayac0
movf sayici1,w
movwf sayac1
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,0 ;Kalan değer W'ye alındı
movwf birler ;Birler sayacı ayarlandı
clrf sayac0 ;Sonraki işlemler için sayac0 sıfırlanıyor
RETURN
;==========Gösterilecek Sayının binary karşılığı ORTAK KATOT=======
TABLO
addwf PCL,1
DT 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x7,0x7F,0x6F
return
;==========7 Segment TARAMA===============
DISPLEY_SEC_YAZ
bcf PORTA, 0 ;( DISPLAY 0)
bsf PORTA, 1
bsf PORTA, 2
bsf PORTA, 3
movf binler, W
CALL TABLO
movwf PORTB ;binleri port b ye gönder
CALL GECIKME ;displey gecikme süresi
bsf PORTA, 0
bcf PORTA, 1 ;( DISPLAY 1)
bsf PORTA, 2
bsf PORTA, 3
movf yuzler, W
CALL TABLO
movwf PORTB ;yüzleri port b ye gönder
CALL GECIKME ;displey gecikme süresi
bsf PORTA, 0
bsf PORTA, 1
bcf PORTA, 2 ;( DİSPLAY 2)
bsf PORTA, 3
movf onlar, W
CALL TABLO
movwf PORTB ;onları port b ye gönder
CALL GECIKME ;displey gecikme süresi
bsf PORTA, 0
bsf PORTA, 1 ;( DİSPLAY 3)
bsf PORTA, 2
BCF PORTA, 3
movf birler, W
CALL TABLO
movwf PORTB ;birleri port b ye gönder
CALL GECIKME ;displey gecikme süresi
DECFSZ dtekrar, F ;sayac 0 olana kadar ekranı göster
GOTO DISPLEY_SEC_YAZ ;sayac 00 olana kadar GÖSTER
bsf PORTA, 0
bsf PORTA, 1 ;DİSP TEMİZLE
bsf PORTA, 2
bsf PORTA, 3
RETURN
;==========KONFİGÜRASYON===========
PRG
bsf STATUS,5 ;Bank1'e geç
movlw b'00000000'
movwf TRISB ;B portunu çıkış olarak ata
movlw b'11110000' ;RA4 giriş,diğerleri çıkş
movwf TRISA
bcf STATUS,5 ;Bank0'a geç
movlw b'00001111' ;Display'ler kapalı
movwf PORTA
movlw b'00000000'
movwf PORTB
;==========ANA PROGRAM=============
KONTROL
btfss PORTA,4 ;RA0 1 ise 1 satır atla ;Butona Basıldı mı?
GOTO KONTROL
SIFIRLA
clrf sayici0
clrf sayici1
SAYICI ;0-9999 arası sürekli olarak sayan program
incf sayici0, F ;sayici0 ve sayici1 'den oluşan 2byte'lik sayıcı
btfsc STATUS,Z ;sayici0 alcak değerlikli,sayici1 yüksek değerlikli
incf sayici1,F
movlw 3 ;7 Segment tekrarlama sayısı
movwf dtekrar
CALL SAYI_CEVIR ;16bitlik binary sayıyı 10'luk bileşenine ayırır
CALL DISPLEY_SEC_YAZ ;4 basamaklı sayıyı 7segmentte gösterir
movlw b'00100111' ;sayici 9999 oldu mu?
subwf sayici1,w
btfss STATUS,Z ;sonuc 0 mı,0'sa 1 satır atla
GOTO SAYICI
movlw b'00001111'
subwf sayici0,w
btfss STATUS,Z ;sonuc 0'mı ,0'sa 1 satır atla
GOTO SAYICI
GOTO SIFIRLA
END