Pic16f628 Pic Basic ile Saat Termometre Devreleri

PIC-16F628 ile yapılmış 7 adet SAAT ve TERMOMETRE Devresi
![]()
Arkadaşlar, PIC16F628 ile gerçekleştirmiş olduğum muhtelif saat ve termometre devrelerini aşağıda açıklıyorum. Projelerin hepsinde kullanılan Isı sensörü DS18B20 dir.
Devre-1: Bu devrede saat sinyalini kesme yöntemi ile oluşturdum. Gösterge olarak LCD ekran kullandım. Isı sensörü olarak DS18B20 sensörü kullandım.
'********************************* '* Name : KESMETMR0.BAS '* Author : [Erol Tahir Erdal] '* Notice : Copyright (c) 2005 [ETE] '* : All Rights Reserved '* Date : 23.04.2005 '* Version : 1.0 '* Notes : '* : (1) LCD '********************************* PORTA=0:portb=0 TRISB=%11110000 'PortB tamamı giriş yapıldı. TRISA=%00000111 'A portu tamamı çıkış yapıldı. '---------------------------------------------------------------- @ DEVICE pic16F628 'işlemci 16F628 @ DEVICE pic16F628, WDT_ON 'Watch Dog timer açık @ DEVICE pic16F628, PWRT_ON 'Power on timer açık @ DEVICE pic16F628, PROTECT_OFF 'Kod Protek kapalı @ DEVICE pic16F628, MCLR_off 'MCLR pini kullanılıyor. @ DEVICE pic16F628, XT_OSC '@ DEVICE pic16F628, INTRC_OSC_NOCLKOUT 'Dahili osilatör kullanılacak '----------------------------------------------------------------- DEFINE LCD_DREG PORTB 'LCD data bacakları hangi porta bağlı? DEFINE LCD_DBIT 4 'LCD data bacakları hangi bitten başlıyor? DEFINE LCD_EREG PORTB 'LCD Enable Bacağı Hangi Porta bağlı? DEFINE LCD_EBIT 3 'LCD Enable Bacağı Hangi bite bağlı ? define LCD RWREG PORTB 'LCD R/W Bacağı Hangi Porta bağlı? define LCD_RWBIT 2 'LCD R/W Bacağı Hangi bite bağlı ? DEFINE LCD_RSREG PORTB 'LCD RS Bacağı Hangi Porta bağlı ? DEFINE LCD_RSBIT 1 'LCD RS bacağı Hangi Bite bağlı ? DEFINE LCD_BITS 4 'LCD 4 bit mi yoksa 8 bit olarak bağlı? DEFINE LCD_LINES 2 'LCD Kaç sıra yazabiliyor 'DEFINE OSC 4 '----------------------------------------------------------------- ON INTERRUPT GoTo KESME 'kesme oluşursa KESME adlı etikete git. OPTION_REG=%10000101 'Pull up dirençleri İPTAL- Bölme oranı 1/64. INTCON=%10100000 'Kesmeler aktif ve TMR0 kesmesi aktif TMR0=0 CMCON=7 '16F628 de komparatör pinleri iptal hepsi giriş çıkış '----------------------------------------------------------------- Comm_Pin VAR Portb.0 ' 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 Float VAR WORD ' Holds remainder for + temp C display X VAR WORD SIGN_BITI VAR HAM.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 SAYAC VAR BYTE SN VAR BYTE DAK VAR BYTE SAAT VAR BYTE GUN VAR BYTE symbol SEC=PORTA.0 SYMBOL YUKARI=PORTA.2 SYMBOL ASAGI =PORTA.1 '------------------------------------------ CLEAR 'tüm değişkenler sıfırlandı PAUSE 200 LCDOUT $FE,1 '----------------------------------------- BASLA: GOSUB EKRAN0 'SAATİ EKRANA YAZ if SEC=0 THEN AYAR 'MODE TUŞUNA BASILMIŞ İSE AYAR'A GİT gosub SENSOROKU 'SONSÖR OKU VE SICAKLIĞI EKRANA YAZ GOTO BASLA EKRAN0: LCDOUT $FE,$84,DEC2 SAAT,":",DEC2 DAK:RETURN AYAR: WHILE SEC=0 WEND HOUR: GOSUB EKRAN0 LCDOUT $FE,$84 lcdout $FE,$0E 'ÇİZGİLİ KURSÖR AÇIK IF SEC=0 THEN MINBIR IF YUKARI=0 THEN SAAT=SAAT+1 IF SAAT=24 THEN SAAT=0 ENDIF IF ASAGI=0 THEN SAAT=SAAT-1 IF SAAT=255 THEN SAAT=23 ENDIF GOSUB GECIKME GOTO HOUR MINBIR: WHILE SEC=0 WEND MINUTE: GOSUB EKRAN0 LCDOUT $FE,$87 IF SEC=0 THEN SECBIR IF YUKARI=0 THEN DAK=DAK+1 IF DAK=60 THEN DAK=0 ENDIF IF ASAGI=0 THEN DAK=DAK-1 IF DAK=255 THEN DAK=59 ENDIF GOSUB GECIKME GOTO MINUTE SECBIR: WHILE SEC=0 WEND SECOND: GOSUB EKRAN0 LCDOUT $FE,$8A IF SEC=0 THEN ARA IF YUKARI=0 THEN SN=SN+1 IF SN=60 THEN SN=0 ENDIF IF ASAGI=0 THEN SN=SN-1 IF SN=255 THEN SN=0 ENDIF GOSUB GECIKME GOTO SECOND GECIKME: FOR X=0 TO 1800 PAUSEUS 100 NEXT RETURN ARA: LCDOUT $FE,$0C WHILE SEC=0 wend ' gosub GECIKME goto BASLA '-------ISI SENSÖR OKUMA BÖLÜMÜ ---------- SENSOROKU: 'ham=$FE6F:Gosub hesapla:RETURN bu satır normal devrede silinecek 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 Hesapla: ' Ham değerden Santigrat derece hesabı Sign = "+" IF SIGN_BITI = NEGAT_ISI THEN Sign = "-" temp=($ffff-ham+1)*625 ISI = DIV32 10 GOTO GEC endif TEMP = 625 * (HAM+1) ' ISI = DIV32 10 ' Div32 hassas derece hesabı için 32 bit bölme yapıyoruz. GEC: FLOAT = (ISI //1000)/100 ISI=ISI/1000 LCDOUT $FE,$C4,Sign,DEC ISI,".",DEC1 (Float)," ",Deg,"C " '2. satırda ısı RETURN DISABLE KESME: SAYAC=SAYAC+1 'kesme sayacı 1 sn= 61(sayac) x 256 (Tmr0) x 64 (bölme) IF SAYAC=61 then '61 adet kesme olunca 1 sn. süre geçiyor.(999424 us) SAYAC=0 'sayaç sıfırlanıyor SN=SN+1 toggle portb.0 'saniye değeri bir artırılıyor IF SN=60 THEN 'saniye 60 olmuş ise 1 dakika süre geçti ohalde SN=0 ' saniye sıfırlanıyor DAK=DAK+1 ' dakika değeri bir artırılıyor IF DAK=60 then 'dakika 60 olmuş ise 1 saat süre geçti DAK=0 ' dakika sıfırlanıyor SAAT=SAAT+1 ' saat değeri bir artırılıyor IF SAAT=24 THEN 'saat 24 olmuş ise 1 gün geçti SAAT=0 'saat sıfırlanıyor ' GUN=GUN+1 'gün değeri bir artırılıyor ' IF GUN=365 THEN GUN=0 'gün 365 olmuş ise endif 'gün sıfırlanıyor 1 yıl geçti ENDIF ENDIF lcdout $fe,$89,":",DEC2 SN ENDIF CIK: INTCON.2=0 'TMR0 Kesme bayrağı sıfırlanıyor RESUME ENABLE END
![]()
Devre-2: Bu devrede saat ve dakika göstergesi olarak 7 segment display kullandım. Saat sinyalini yine kesme yöntemi ile oluşturdum.
'*****************************
'* Name : KESMETMR0.BAS
'* Author : [Erol Tahir Erdal]
'* Notice : Copyright (c) 2005 [ETE]
'* : All Rights Reserved
'* Date : 23.04.2005
'* Version : 1.0
'* Notes :
'* : LED (2)
'*****************************
PORTA=0:portb=0
TRISB=0 'PortB tamamı giriş yapıldı.
TRISA=%00000111 'A portu tamamı çıkış yapıldı.
'-----------------------------------------------------------------
@ DEVICE pic16F628 'işlemci 16F628
@ DEVICE pic16F628, WDT_ON 'Watch Dog timer açık
@ DEVICE pic16F628, PWRT_ON 'Power on timer açık
@ DEVICE pic16F628, PROTECT_OFF 'Kod Protek kapalı
@ DEVICE pic16F628, MCLR_off 'MCLR pini kullanılıyor.
'@ DEVICE pic16F628, XT_OSC
@ DEVICE pic16F628, INTRC_OSC_NOCLKOUT 'Dahili osilatör kullanılacak
'---------------------------------------------------------------
'DEFINE OSC 4
'----------------------------------------------------------------
ON INTERRUPT GoTo KESME 'kesme oluşursa KESME adlı etikete git.
OPTION_REG=%00000101 'Pull up dirençleri İPTAL- Bölme oranı 1/64.
INTCON=%10100000 'Kesmeler aktif ve TMR0 kesmesi aktif
TMR0=0
CMCON=7 '16F628 de komparatör pinleri iptal hepsi giriş çıkış
'----------------------------------------------------------------
Comm_Pin VAR PortA.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
Float VAR WORD ' Holds remainder for + temp C display
X VAR WORD
Y VAR BYTE
SAYI VAR BYTE
SIGN_BITI VAR HAM.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
SAYAC VAR BYTE
SN VAR BYTE
DAK VAR BYTE
SAAT VAR BYTE
GUN VAR BYTE
symbol SEC=PORTA.0
SYMBOL YUKARI=PORTA.2
SYMBOL ASAGI =PORTA.1
'------------------------------
CLEAR 'tüm değişkenler sıfırlandı
PAUSE 200
SAAT=13:DAK=24 : PORTB=255
'------------------------------
HIGH PORTA.3
BASLA:
IF Y>6 THEN
IF Y>=11 THEN Y=1
GOSUB EKRAN1
GOTO ATLA
ENDIF
GOSUB EKRAN0
ATLA: if SEC=0 THEN AYAR 'MODE TUŞUNA BASILMIŞ İSE AYAR'A GİT
gosub SENSOROKU 'SONSÖR OKU VE SICAKLIĞI EKRANA YAZ
GOTO BASLA
EKRAN0:
if sayac=30 then low porta.3
X= SAAT DIG 1:GOSUB AL
SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]
HIGH PORTB.2:PAUSEUS 2:LOW PORTB.2
X= SAAT DIG 0:GOSUB AL
SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]
HIGH PORTB.3:PAUSEUS 2:LOW PORTB.3
X= SN DIG 1:GOSUB AL
SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]
HIGH PORTB.4:PAUSEUS 2:LOW PORTB.4
X= SN DIG 0:GOSUB AL
SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]
HIGH PORTB.5:PAUSEUS 2:LOW PORTB.5
' X= sn DIG 1:GOSUB AL
' SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]
' HIGH PORTB.6:PAUSEUS 2:LOW PORTB.6
' X= SN DIG 0:GOSUB AL
' SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]
' HIGH PORTB.7:PAUSEUS 2:LOW PORTB.7
RETURN
AL: LOOKUP X,[63,6,91,79,102,109,125,7,127,111,99,57],SAYI :RETURN
EKRAN1:
LOW PORTA.3 :SAYI=0
SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]
HIGH PORTB.2:PAUSEUS 2:LOW PORTB.2
IF SIGN_BITI = NEGAT_ISI THEN SAYI=64
SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]
HIGH PORTB.3:PAUSEUS 2:LOW PORTB.3
x=(ISI DIG 1):GOSUB AL
SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]
HIGH PORTB.4:PAUSEUS 2:LOW PORTB.4
x=(ISI DIG 0):GOSUB AL
SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]
HIGH PORTB.5:PAUSEUS 2:LOW PORTB.5
X=10:GOSUB AL
SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]
HIGH PORTB.6:PAUSEUS 2:LOW PORTB.6
X=11:GOSUB AL
SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]
HIGH PORTB.7:PAUSEUS 2:LOW PORTB.7
RETURN
AYAR:
WHILE SEC=0
WEND
HOUR: GOSUB EKRAN0
LOW PORTA.3
IF SEC=0 THEN MINBIR
IF YUKARI=0 THEN
SAAT=SAAT+1
IF SAAT=24 THEN SAAT=0
ENDIF
IF ASAGI=0 THEN
SAAT=SAAT-1
IF SAAT=255 THEN SAAT=23
ENDIF
GOSUB GECIKME
GOTO HOUR
MINBIR: WHILE SEC=0
WEND
MINUTE: GOSUB eKRAN0
LOW PORTA.3
IF SEC=0 THEN ara
IF YUKARI=0 THEN
DAK=DAK+1
IF DAK=60 THEN DAK=0
ENDIF
IF ASAGI=0 THEN
DAK=DAK-1
IF DAK=255 THEN DAK=59
ENDIF
GOSUB GECIKME
GOTO MINUTE
SECBIR: WHILE SEC=0
WEND
GECIKME:
FOR X=0 TO 1800
PAUSEUS 100
NEXT
RETURN
ARA: HIGH PORTA.3
WHILE SEC=0
wend
goto BASLA
'-------ISI SENSÖR OKUMA BÖLÜMÜ ----------
SENSOROKU:
ham=$ff5e:Gosub hesapla:return 'NORMAL ÇALIŞMADA BU SATIR SİLİNECEK
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
Hesapla: ' Ham değerden Santigrat derece hesabı
Sign = "+"
IF SIGN_BITI = NEGAT_ISI THEN
Sign = "-"
temp=($ffff-ham+1)*625
ISI = DIV32 10
GOTO GEC
endif
TEMP = 625 * (HAM+1) '
ISI = DIV32 10 ' Div32 hassas derece hesabı için 32 bit bölme yapıyoruz.
' ISI = (HAM & $0FF0) >> 4 'ortadaki 8 biti maskele, ve sağa doğru 4 hane kaydır.
GEC:
FLOAT = (ISI //1000)/100
ISI=ISI/1000
' Float = ((HAM.Lowbyte & $0F) * 625) ' Küsürat hesabı
' LCDOUT $FE,$C4,Sign,DEC ISI,".",DEC1 (Float)," ",Deg,"C " '2. satırda ısı
RETURN
DISABLE
KESME:
SAYAC=SAYAC+1 'kesme sayacı 1 sn= 61(sayac) x 256 (Tmr0) x 64 (bölme)
IF SAYAC=58 then '61 adet kesme olunca 1 sn. süre geçiyor.(999424 us)
SAYAC=0 'sayaç sıfırlanıyor
SN=SN+1
Y=Y+1 'saniye değeri bir artırılıyor
if y<7 then high porta.3
IF SN=60 THEN 'saniye 60 olmuş ise 1 dakika süre geçti ohalde
SN=0 ' saniye sıfırlanıyor
DAK=DAK+1 ' dakika değeri bir artırılıyor
IF DAK=60 then 'dakika 60 olmuş ise 1 saat süre geçti
DAK=0 ' dakika sıfırlanıyor
SAAT=SAAT+1 ' saat değeri bir artırılıyor
IF SAAT=24 THEN 'saat 24 olmuş ise 1 gün geçti
SAAT=0 'saat sıfırlanıyor
' GUN=GUN+1 'gün değeri bir artırılıyor
' IF GUN=365 THEN GUN=0 'gün 365 olmuş ise
endif 'gün sıfırlanıyor 1 yıl geçti
ENDIF
ENDIF
' lcdout $fe,$89,":",DEC2 SN
ENDIF
CIK: INTCON.2=0 'TMR0 Kesme bayrağı sıfırlanıyor
RESUME
ENABLE
END
Yazar: Ete
Yazarımızın 320volt.com Blog üzerinde şu an okuduğunuz yazı dahil 23 yazısı bulunmaktadır. Yazarımız hakkında bilgileri ve diğer yazılarını görmek için bakınız; Ete














Bu devreyi yapıp bu hale getiren kişinin ellerine emeğine sağlık. Bu devre ile ilgili soracağım tek konu lcd ekranda veya 7sekment de o anlık değerleri okuduk peki bu değerleri kaydedebilmek için bir hafıza kartına nasıl bağlayabilirim. bağlandıkdan sonra bu verileri 15 sn de bir karta taşımasını istesek bu programı nasıl değiştirmeliyiz ve nasıl bağlamalıyız devremize. Şimdiden teşekkür ederim kolay gelsin iyi çalışmalar.
arkadasım projen çok güzel ama bana sadece ldc de gösteren lazım kodlarla birlike eger bulursan bana ulaşırmısın