DS18B20 bilgisini okurken kesme meydana gelip yanlış ölç

Başlatan remzi, 19 Şubat 2008, 20:53:01

remzi

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;
      }
     
      
      
   }
}

mucitotomasyon

sorununuz cok basit kesmenin icinde sıcaklık ölç  olay bukadar basit

remzi

fakat DS1820 nin katalogunda max 750ms de okuma yapabildiğini söylüyor. Benim max 2.5ms sürem var.

mucitotomasyon

ya onemli değil kesmenin icinde 750 ms bekler okadar
msn   ekledim ama seb kabul etmedin herhalde

mucitotomasyon

ama su durum var dedigin gibi pardon yeni farkettim 750 ms bekledimi
ekran displey cöker

mucitotomasyon

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

elmaalma

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.

remzi

maalesef sadece okumada kapatıyorum ama çözüm değil...

miral

For döngüsü ile displaylere bilgi göndersen olmazmı.Kesme yapmaya neden ihtiyaç duydun.Rutin olarak belirli işleri yaparsan kesmeye gerek kalmaz.
önce selam,sonra kelam...

remzi

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.