DS 18B20 ile termometre yaptım. Displayleri tarama yöntemi ile sürüyorum. (2.5msn de bir bir display yanıyor.) Fakat DS18B20 den okuma yaparken kesme gelince yanlış bilgiler alıyorum.
Ne yapmamı tavsiye edersiniz...
#include <16F628A.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES PUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES BROWNOUT //No brownout reset
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#use delay(clock=4000000,RESTART_WDT)
#include <ctype.h>
#include <PCF8583.c>
#include <1wire.c>
#include <ds1820.c>
#byte PORTA = GETENV("SFR:PORTA")
#bit onsaataktif = GETENV("SFR:PORTA").3
#bit down = GETENV("SFR:PORTA").4
#bit up = GETENV("SFR:PORTA").5
#byte PORTB = GETENV("SFR:PORTB")
#bit saataktif = GETENV("SFR:PORTB").0
#bit ondakikaaktif = GETENV("SFR:PORTB").1
#bit dakikaaktif = GETENV("SFR:PORTB").2
#bit bilgi = GETENV("SFR:PORTB").3
#bit goster = GETENV("SFR:PORTB").4
#bit pals = GETENV("SFR:PORTB").5
#define led PIN_A2
#define derece 10
#define cantigrad 11
unsigned char sayi[13]={0x77,0x11,0x6B,0x3B,0x1D,0x3E,0x7E,0x13,0x7F,0x3F,0x0F,0x66,0x08}; //son üç deger derece,santigrad,eksi
unsigned char i=0x00,kesme_sayisi=0x00;
unsigned char display_sirasi=0x00;
unsigned char dakika=0x00,ondakika=0x00,saat=0x00,onsaat=0x00;
unsigned int16 sicaklik;
char templ=0x00, temph=0x00,temp=0x00;
unsigned char islem_basladi=0x00;
void char displaye_gonder(deger)
{
deger=sayi[deger];
disable_interrupts(INT_timer2);
for(i=0;i<8;i++)
{
if( bit_test(deger,i) == 1)
bilgi=1;
else
bilgi=0;
pals=1;
pals=0;
}
goster=1;
goster=0;
enable_interrupts(INT_timer2);
}
#int_timer2
void timer2_kesmesi()
{
kesme_sayisi++;
if(kesme_sayisi==20)
{
output_toggle(led);
kesme_sayisi=0x00;
}
}
#int_timer1
void timer1_kesmesi()
{
display_sirasi++;
if(display_sirasi==4)
display_sirasi=0;
if(display_sirasi==0)
{
dakikaaktif=0;
displaye_gonder(onsaat);
onsaataktif=1;
set_timer1(63035);
break;
}
if(display_sirasi==1)
{
onsaataktif=0;
displaye_gonder(saat);
saataktif=1;
set_timer1(63035);
break;
}
if(display_sirasi==2)
{
saataktif=0;
displaye_gonder(ondakika);
ondakikaaktif=1;
set_timer1(63035);
break;
}
if(display_sirasi==3)
{
ondakikaaktif=0;
displaye_gonder(dakika);
dakikaaktif=1;
set_timer1(63035);
break;
}
clear_interrupt(int_timer1);
}
void main()
{
setup_oscillator( OSC_4MHZ );
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); //display leri tarar.
setup_timer_2(T2_DIV_BY_16,200,16);
enable_interrupts(INT_timer1);
enable_interrupts(INT_timer2); //ortadaki ledleri yakıp söndürür.
enable_interrupts(GLOBAL);
set_tris_a(0x30);
set_tris_b(0x00);
PORTA=0x00;
PORTB=0x00;
for(;;)
{
delay_ms(500);
set_timer1(0x0000);
sicaklik=ds1820_read();
delay_ms(500);
sicaklik=sicaklik>>4; //DS1820 için >>1 defa DS18B20 için ise 4 defa sağa
temp = make8(sicaklik,0);
islem_basladi=1;
if(temp>=128) //Eksi değerler
{
temp=~temp;
temp++;
if(temp<10)
templ=temp;
else
templ=9;
temph=12; //eksi işareti
islem_basladi=0;
}
else //sıfır ve artı değerler için...
{
while(temp>=100) { temph=9; templ=9; temp=0;}
while(temp>=10) { temph++; temp -= 10; }
while(temp>=1) { templ++; temp -= 1; }
islem_basladi=0;
}
if(islem_basladi==0) //sicaklik bilgisi okundu ise
{
onsaat=temph;
saat=templ;
ondakika=10; //derece
dakika=11; //santigrad
temph=0;
templ=0;
islem_basladi=1;
}
}
}
sorununuz cok basit kesmenin icinde sıcaklık ölç olay bukadar basit
fakat DS1820 nin katalogunda max 750ms de okuma yapabildiğini söylüyor. Benim max 2.5ms sürem var.
ya onemli değil kesmenin icinde 750 ms bekler okadar
msn ekledim ama seb kabul etmedin herhalde
ama su durum var dedigin gibi pardon yeni farkettim 750 ms bekledimi
ekran displey cöker
bacak sayısı fazla olan pic kullan can buda amatöre kacar yada lach cıkışlı sürücü kullancan 74hc164 gi bi filan
Alıntı yapılan: "remzi"fakat DS1820 nin katalogunda max 750ms de okuma yapabildiğini söylüyor. Benim max 2.5ms sürem var.
Sadece ekran taraması için kesme kullanıyorsan DS okuma yazma işlemleri sırasında kesmeyi kapatabilirsin.
maalesef sadece okumada kapatıyorum ama çözüm değil...
For döngüsü ile displaylere bilgi göndersen olmazmı.Kesme yapmaya neden ihtiyaç duydun.Rutin olarak belirli işleri yaparsan kesmeye gerek kalmaz.
Görüntünün bozuk olmaması için kesme ile taramayı yaptım. Bir çözüm yolu buldum. DS18B20 yi okuturken ekranı ve kesmeleri kapatıyorum. Okuma bittikten sonra açıyorum. Böylelikle yanlış ölçüm meydan gelmiyor.