avatar_POWER

Eksi derece gösteren Termometre

Başlatan POWER, 07 Aralık 2016, 00:09:00

POWER

Herkeze iyi geceler,
Elimde 3 digit led display ile ds18b20 kullanılarak yapılmış bir termometre devresi var.Genel çalışmasında problem yok.Sadece eksi derece gösterirken 0 ile 9 derece arasını -0.1  .......   -9.9 şeklinde,  sonrasını -10  -11   -12    -13 ........  şeklinde (3 digit olduğundan) gösdermesini istiyorum. tüm çabama rağmen tarif ettiğim gibi düzenleyemedim malesef.
isis dosyasını ekliyorum.
DEFINE OSC 4
Include "MODEDEFS.BAS"
TRISB=%00010000   
TRISA=%00000000 
PORTA=0
PORTB=0
'-------------------------------------------------------------------------------
@ DEVICE pic16F628A                      'işlemci 16F628                               
@ DEVICE pic16F628A, WDT_ON              'Watch Dog timer açık
@ DEVICE pic16F628A, PWRT_ON             'Power on timer açık
@ DEVICE pic16F628A, PROTECT_ON          'Kod Protek açık
@ DEVICE pic16F628A, MCLR_off            'MCLR pini kullanıımıyor.
@ DEVICE pic16F628A, INTRC_OSC_NOCLKOUT  'Dahili osilatör kullanılacak
'-------------------------------------------------------------------------------
OPTION_REG=1   'Pull up dirençleri iptal
CMCON=7        '16F628 de komparatör pinleri iptal hepsi giriş çıkış
'-------------------------------------------------------------------------------
Comm_Pin    VAR Portb.4  ' One-wire Data-Pin "DQ" PortB.0 da
Busy        VAR BIT      ' Busy Status-Bit
HAM         VAR WORD     ' Sensör HAM okuma değeri
ISI         VAR WORD     ' Hesaplanmış ISI değeri
ISI1        VAR BYTE     ' Holds remainder for + temp C display
ISI2        VAR BYTE
X           VAR WORD 
SAYI        VAR BYTE
SYMBOL      DP=PORTB.0 

SIGN_BITI   VAR HAM.11'Bit11' +/- sıcaklık İşaret biti,  1 = olursa eksi sıcaklık
Negat_ISI   CON 1        ' Negatif_Cold = 1
Deg         CON 223      ' ° işareti
SIGN        VAR BYTE     ' ISI değeri için  +/-  işaret
TEMP        VAR BYTE     ' Div32 bit hesap için geçici değişken

gosub sensoryaz
gosub sensoroku
PAUSE 500
BASLA:
         GOSUB SENSOROKU
         IF Sign = "+" then GOSUB EKRAN1
         IF Sign = "-" Then GOSUB EKRAN2
       
GOTO BASLA


EKRAN1:
       X=ISI1 Dig 1  'ISI1'in onlar basamağı((2.hane)
       GoSub AL
       IF X=0 THEN SAYI=0 
       GOSUB Cevir
       PORTB.1=1
       PAUSE 3
       PORTB.1=0
           
       X=ISI1 Dig 0  'ISI1'in birler basamağı(3.hane)
       GoSub AL
       GOSUB Cevir
       DP=1
       PORTB.2=1
       PAUSE 3
       PORTB.2=0
                             
       X=ISI2 Dig 0  'ISI2'nin birler basamağı(4.hane)
       GoSub AL
       GOSUB Cevir
       DP=0
       PORTB.3=1
       PAUSE 3
       PORTB.3=0
     
       RETURN

EKRAN2:
       IF Sign = "-" then                 '(2.hane)
       SAYI=64
       else
       SAYI=0
       endif
       GOSUB Cevir
       PORTB.1=1
       PAUSE 3
       PORTB.1=0
     
       X=ISI1 Dig 1  'ISI1'in onlar basamağı(3.hane)
       GoSub AL
       GOSUB Cevir
       PORTB.2=1
       PAUSE 3
       PORTB.2=0
                             
       X=ISI1 Dig 0  'ISI1'nin birler basamağı(4.hane)
       GoSub AL
       GOSUB Cevir
       PORTB.3=1
       PAUSE 3
       PORTB.3=0       
       
       Return 


AL:    LookUp X,[63,6,91,79,102,109,125,7,127,111,64],SAYI
       Return

Cevir:
PORTA.0=SAYI.0
PORTA.1=SAYI.1
PORTA.2=SAYI.2
PORTA.3=SAYI.3
PORTA.4=SAYI.4
PORTA.6=SAYI.5
PORTA.7=SAYI.6
RETURN
   
SENSOROKU:
OWOUT   Comm_Pin, 1, [$CC, $44]' ISI değerini oku
Bekle:
OWIN    Comm_Pin, 4, [Busy]    ' Busy değerini oku
IF      Busy = 0 THEN Bekle  ' hala meşgulmü? , evet ise goto Bekle..!
OWOUT   Comm_Pin, 1, [$CC, $BE]' scratchpad memory oku
OWIN    Comm_Pin, 2, [HAM.Lowbyte, HAM.Highbyte]' İki byte oku ve okumayı bitir.
GOSUB   Hesapla
        RETURN

SENSORYAZ: 'okumaya hazırlan..         
OWOUT   Comm_Pin, 1, [$CC,$4E,$FF,$FF,$7F];Hassasiyet 12 bit olarak ayarlanıyor
OWOUT   Comm_Pin, 1, [$CC,$48]         
OWOUT   Comm_Pin, 1, [$CC,$B8]         
OWOUT   Comm_Pin, 1, [$CC,$BE]         
return

Hesapla:                 ' Ham değerden Santigrat derece hesabı
    Sign  = "+"
    IF SIGN_BITI = NEGAT_ISI THEN    'yani 1 ise
       Sign   = "-" 
       HAM=($FFFF-HAM)+1
    endif
    ISI = ham*10/16       '
GEC:
    ISI2 = (ISI //10)
    ISI1=ISI/10
RETURN       '
'Burada ISI1=sıcaklığın tam sayı kısmını,ISI2 ise ondalık kısmını göstermektedir.

END

Hattuşa

HAM=($FFFF-HAM)+1


hocam basicte yazılmış bende proton var simülede değişkenleri göremedim ama bence kodda;
eğer derece eksi ise kısmında ham değerinden çıkardığınız $FFFF değerinden kaynaklandığını düşünüyorum.

ete

#2
Bu iş de ip ucu ISI değerinin 100 (10,0) dereceden küçük olma durumudur. Bunu test ederek bu işi gerçekleştirmek gerekir. Öylede yaptım. Ekran2 isimli etiket altındakileri sil yerine aşağıdakileri yaz.
EKRAN2:
       SAYI=64 :GOSUB Cevir
       PULSOUT PORTB.1,300
   
       IF ISI<100 THEN
         X=ISI1:GOSUB al:GOSUB CEVIR:DP=1
         PULSOUT PORTB.2,300:DP=0
         X=ISI2:GOSUB al:GOSUB CEVIR
         PULSOUT PORTB.3,300
       ELSE
         X=ISI1 DIG 1:GOSUB al:GOSUB CEVIR
         PULSOUT PORTB.2,300
         X=ISI1 DIG 0:GOSUB al:GOSUB CEVIR
         PULSOUT PORTB.3,300     
       ENDIF
       RETURN


Ekran2 isimli etikete zaten Sign=- ise gidilebiliyor. Hal böyle iken birdaha orada;
If Sıgn=- then   gibi komutlara gerek varmı? yok elbette. Önceden test edip oraya o şart gerçekleştiği için geldin zaten. Bu nedenle o if satırlarını sildim.
Benzer durum aslında programın oraya gelmesini sağlayan satırlarda da var,
BASLA: 
         GOSUB SENSOROKU
         IF Sign = "+" then GOSUB EKRAN1
         IF Sign = "-" Then GOSUB EKRAN2       
         GOTO BASLA

Sign byte değişkeni olmasına rağmen program içinde değeri ya + yada - olabilmektedir. Başka bir alternatif olmadığına göre Önce değerinin eksi olup olmadığına bakılır değilse zaten otomatikman artı dır. O halde artı konumunu test etmeye gerek yoktur. Oraya;
BASLA: 
         GOSUB SENSOROKU
         IF Sign = "-" then GOSUB EKRAN2
         GOSUB EKRAN1       
         GOTO BASLA
yazılabilir.

Ete

POWER

ete hocam çok teşekkür ederim değerli bilgilerinizden dolayı.söylediğiniz şekide sorunsuz çalışıyor.
SENSOROKU: 
OWOUT   Comm_Pin, 1, [$CC, $44]' ISI değerini oku
Bekle:
OWIN    Comm_Pin, 4, [Busy]    ' Busy değerini oku
IF      Busy = 0 THEN Bekle  ' hala meşgulmü? , evet ise goto Bekle..!
OWOUT   Comm_Pin, 1, [$CC, $BE]' scratchpad memory oku
OWIN    Comm_Pin, 2, [HAM.Lowbyte, HAM.Highbyte]' İki byte oku ve okumayı bitir.
GOSUB   Hesapla
        RETURN

Hocam sensör okuma kısmındaki alttaki satırı iptal etmediğim zaman dısplay flaş yapıyor.Pause süreleri ilede oynadım değişmedi.lcd ile yapılmış saat-tetmometre devresinden de hatırlıyorum bu bahsettiğim satırı aktif edersem saniye düzensiz sayardı. 1-2-4-5-6 gibi.sonuç olarak bu satırın iptal edilmesi yanlış ısı ölçümü yapmamıza sebep olurmu?

IF      Busy = 0 THEN Bekle  ' hala meşgulmü? , evet ise goto Bekle..!

ete

Bu sensörün. Bir sıcaklık değeri okuması yaklaşık 750 ms sürmektedir. Önce okuma emrini veriyorsun sonra  busy bitine bakarak okuma işleminin bitip bitmediğini kontrol ediyorsun. Kısaca busy ye bakmakla 750 ms lik süreyi doldurmaya çalışıyorsun. Ben son dönemde önce okuma emrini vererek oradan ayrılıyorum. Böylece 750 ms boşuna orada beklemektense yapılacak başka işleri yapıp sonra tekrar busy okuma kısmına dönerek 750 ms lik sürenin çoğunu başka işlerle uğraşarak geçiriyorum. Şayet başka işlerde 750 ms net zaman harcamış isem busy ye bakmaya gerek yoktur. Sensör otomatikman işini bitirip sıcaklığı ilgili registerine yazmış olur sanada sadece o tegisteri okumak kalır. Ama süre tam olarak dolmamoş ise busy bitine bakmakta fayda var. Süre dolmadan ve busy bitine bakmadan sıcaklığı okumaya çalışırsan daima bir önceki okuma değerini okursun. Zira registerde o kayıtlıdır. Ardışık okumalarda bu zarar getirmez ama doğrusu benim açıkladığım şekilde yapmaktır.
Ete

Powered by EzPortal