Haberler:

Forum kuralları güncellendi LÜTFEN  okuyunuz:  https://bit.ly/2IjR3ME

Ana Menü

DS18B20 sorunu

Başlatan sero, 15 Kasım 2007, 13:54:44

sero

Merhaba arkadaşlar.PICC LITE derleyicisini kullanarak,DS18B20 ile sıcaklık ölçmek için bir program yazdım.Fakat Proteusda LCD de 16 adet @ işareti görebiliyorum. Kodların tamamı aşağıda.Eğer yardımcı olursunuz çok sevinirim.
/***********************************************
/*DS 18B20 ile sıcaklık ölçümü
/*
/***********************************************
*/
#include <pic.h>
#include <delay.c>
#include <lcd.c>
#include <stdio.h>
#include <math.h>

#define skip_rom 0xCC
#define w_scratchpad 0x4E
#define convert 0x44
#define r_scratchpad 0xBE

#define DQ RA1

/*************************
/*reset ve precense iŸlemi
/*************************
*/

void reset_presence()
{
   TRISA=0x01;
   DQ=0;            //hat=0
   DelayUs(240);
   DelayUs(240);         //480 us bekle
   DQ=1;            //hat=1;
   DelayUs(60);         //60us bekle
   if(DQ==0)
   {
   DelayUs(240);
   }
}

/*************************
/*bit yazma fonksiyonu
/*************************
*/

void bit_yaz(unsigned char c)
{
   TRISA=0x01;         //DQ ‡kŸ
   if(c==0)
   {
      DQ=0;         //hat=0
      DelayUs(45);      //45 usn bekle
      DQ=1;         //hatt serbest brak
      DelayUs(3);      //3 usn bekle
   }
   else
   {
      DQ=0;         //hat=0
      DelayUs(3);      //3 usn bekle
      DQ=1;         //hat=1
      DelayUs(45);      //45 usn bekle
   }
}

/**************************
/*bilgi yazma fonksiyonu
/**************************
*/

void bilgi_yaz(unsigned char bilgi,unsigned char bit_sayisi)
{
   unsigned char i,simdiki_bit;
   for(i=0;i<bit_sayisi;i++)
   {
      simdiki_bit=bilgi>>i;
      simdiki_bit=simdiki_bit&1;
      bit_yaz(simdiki_bit);
   }
}

/***************************
/*bilgi okuma fonksiyonu
/***************************
*/
float bilgi_oku()
{
   unsigned char tmp[11],j,i=0;
   float sicaklik=0;
   for(j=0;j<12;j++)
   {
      DQ=0;
      DelayUs(2);
      DQ=1;
      DelayUs(15);
      if(DQ==1)
      {
         tmp=1;
         i++;
         DelayUs(30);
      }
      else
      {
         tmp=0;
         i++;
         DelayUs(30);
      }
   }
   sicaklik=tmp[0]*0.065+tmp[1]*0.125+tmp[2]*0.25+tmp[3]*0.5+tmp[4]*1+tmp[5]*2+tmp[6]*4+tmp[7]*8+tmp[8]*16+tmp[9]*32+tmp[10]*64;
   if(tmp==1)
   sicaklik=-128+sicaklik;
   else
   sicaklik=0+sicaklik;
   return(sicaklik);
}
   
/*ANA PROGRAM*/

main(void)
{
   unsigned char goster[]="SICAKLIK: ";
   float sicak;
               ADCON=0x07;
   TRISB=0;
   TRISA=0x03;
   DelayMs(250);
   lcd_init();
   lcd_clear();
   bilgi_yaz(skip_rom,16);
   bilgi_yaz(w_scratchpad,16);
   bilgi_yaz(125,16);
   bilgi_yaz(-55,16);
   bilgi_yaz(0x7F,16);
   reset_presence;
   bilgi_yaz(skip_rom,16);
   bilgi_yaz(convert,16);
   DelayMs(250);
   DelayMs(250);
   DelayMs(250);
   DelayMs(250);
   reset_presence();
   bilgi_yaz(skip_rom,16);
   bilgi_yaz(r_scratchpad,16);
   TRISB=0x03;
   for(;;)
   {
      sicak=bilgi_oku();
      sprintf(goster+16,"%f",sicak);
      lcd_puts(goster);
      DelayMs(250);
      lcd_clear();
   }
}   
Sorunun LCD kısmında olduğundan şüpheleniyorum.Acaba veri tiplerinde(float) bir sorun olabilirmi? Şimdiden teşekkürler.Kolay gelsin...

parda

Merhaba ;

Şahsen yazdığın kodu okumadım. Okuyup inceleyip cevap verecek birisininde çıkacağını sanmıyorum. Size sadece hatayı bulmada izleyeceğiniz yolda fikir verebilirim.

1. LCD ye sadece sabit "Merhaba" yaz, yazdı mı?
2. LCD ye sadece sabit float sayı yazdır, yazdı mı?

Bu iki sorunun cevabına göre kendini yönlendir yada soruların cevaplarını buraya yaz.

Kolay Gelsin
Bildiğim tek şey, hiç bir şey bilmediğimdir.

sero

İlgilendiğiniz için teşekkür ederim öncelikle. Dediğiniz gibi ilk önce char[] formatında bir veriyi (SICAKLIK) ekrana yazdırdım.Bunda sorun yok. Daha sonra bununla birlikte undigned int tipinde bir değişkene atadağım rastgele bir rakamla birlikte beraber ilk kısmı denedim(SICAKLIK:27). Bu kısımda da sorun yok. Programda sıcaklığı okuyan kısmı altta belirttiğim gibi unsigned int olarak düzenledim. Ama ekrana gönderdiğimde @HL LHH... gelişigüzel karakterler çıkıyor.Yardımlarınızı esirgemeyin lütfen.

Programda ki değişiklik:

/***************************
/*bilgi okuma fonksiyonu
/***************************
*/
unsigned int bilgi_oku()
{
   unsigned char tmp[11],j,i=0;
   unsigned int sicaklik=0;
   for(j=0;j<12;j++)
   {
      DQ=0;
      DelayUs(2);
      DQ=1;
      DelayUs(15);
      if(DQ==1)
      {
         tmp=1;
         i++;
         DelayUs(30);
      }
      else
      {
         tmp=0;
         i++;
         DelayUs(30);
      }
   }
   sicaklik=tmp[4]*1+tmp[5]*2+tmp[6]*4+tmp[7]*8+tmp[8]*16+tmp[9]*32+tmp[10]*64;
   return(sicaklik);
}
   
/*ANA PROGRAM*/

main(void)
{
   unsigned char goster[]="SICAKLIK: ";
   unsigned int sicak=0;
   ADCON1=0x07;
   TRISB=0;
   TRISA=0x03;
   DelayMs(250);
   lcd_init();
   lcd_clear();
   bilgi_yaz(skip_rom,16);
   bilgi_yaz(w_scratchpad,16);
   bilgi_yaz(125,16);
   bilgi_yaz(-55,16);
   bilgi_yaz(0x7F,16);
   reset_presence;
   bilgi_yaz(skip_rom,16);
   bilgi_yaz(convert,16);
   DelayMs(250);
   DelayMs(250);
   DelayMs(250);
   DelayMs(250);
   reset_presence();
   bilgi_yaz(skip_rom,16);
   bilgi_yaz(r_scratchpad,16);
   TRISB=0x03;
   for(;;)
   {
      sicak=bilgi_oku();
      sprintf(goster+9,"%d",sicak);
      lcd_puts(goster);
      DelayMs(250);
      lcd_clear();
   }
}   

Şimdiden teşekkürler.Kolay gelsin...

arslan74

unsigned char goster[]="SICAKLIK: ";


burda hata var. aşağıdaki gibi yaz öyle dene.


unsigned char goster[20]="SICAKLIK: ";


Nedeni ise sprintf fonksiyonun yanlış kullanmışsın. Programda hata mesajı vermez ama uyarı mesajı vermiş olması gerek.

sprintf(goster+9,"%d",sicak);


goster dizinde taşmaya neden oluyorsun. Yanlış yerlere bilgi yaziyorsun.

Selamlar

sero

İlgilendiğiniz için teşekkür ederim öncelikle. Dediğiniz şekilde denedim, fakat aynı sorun yine devam ediyor.

f_machine

void reset_presence()
{
TRISA=0x01;
DQ=0; //hat=0
DelayUs(240);
DelayUs(240); //480 us bekle
DQ=1; //hat=1;
DelayUs(60); //60us bekle
if(DQ==0)
{
DelayUs(240);
}
}


bu fonksiyonda RA1 i çıkış olarak ayarlamışsın, ama if(DQ==0)
satırından önce RA1 in giriş yapılması lazım.Bir de böyle dene bakalım..

arslan74

Merhaba,

Onewire ile ilgili bir yerden bulduğum bir kod var. Kodu test etmedim, ama O kodu kullanmayı deneyebilirsin.


/* #include "12F675.h"
// #pragma config |= 0x3194          
#pragma bit  DQ_TRI   @ TRISIO.2
#pragma bit  DQ_PIN   @ GPIO.2
*/
#include "16F877.h"
#pragma bit  DQ_TRI   @ TRISB.5
#pragma bit  DQ_PIN   @ PORTB.5
// Rom commands
#define MATCH_ROM    0x55
#define SKIP_ROM     0xCC
#define SEARCH_ROM   0xF0
#define READ_ROM     0x33
#define ALARM_SEARCH 0xEC


#define SEARCH_FIRST 0xFF        // start new search
#define PRESENCE_ERR 0xFF
#define DATA_ERR     0xFE
#define LAST_DEVICE  0x00        // last device found
//          0x01 ... 0x40: continue searching
#define ROMCODE_SIZE 8
#define OWROMCODE 8
#define OWMAX 16
char buffer[9];     // Used to store 9 bytes read from DS1820

char temperature;
char count;
bit	present;
#pragma origin 4


bit dsReset(void)
{
    DQ_TRI=0;                  // Pull Line Low to start reset pulse
    DQ_PIN=1;
    nop2();
    DQ_PIN=0;
    count=70; 
    do
        nop2();     //480 uS Delay
    while (-- count > 0);
    DQ_TRI=1;                  // Pull 
    count=15;
    do
        nop2();     //100 uS Delay
    while (-- count > 0);
    present=DQ_PIN;
    count=65; 
    do
        nop2();     //380 uS Delay
    while (-- count > 0);
    DQ_TRI=1;       //Lıne is High
    return(present);
}

void dsWrite(char Data)
{
    char count1,n;
    bit  DQdata;
    count1=8;
    for(;count1>0;count1--)  
        {
          DQdata= Data.0;       // Put the bit to be written in the right place
          DQ_PIN=0;
          DQ_TRI=0;         //  Lower the port
          nop2();            // Time slot start time
          if (DQdata == 1)
            DQ_TRI=1;
            else 
            DQ_TRI=0;  
          count=20; 
          do
            nop2();     //60 uS Delay
          while (-- count > 0);
          DQ_TRI=1;                     // Make sure port is released
          nop2();            // Some Delay Between Bits
          Data=Data>>1;     // Shift next bit into place
    }

}

void dsWriteslot(bit temp)
{
          DQ_PIN=0;
          DQ_TRI=0;         //  Lower the port
          nop2();            // Time slot start time
          if (temp == 1)
            DQ_TRI=1;
            else 
            DQ_TRI=0;  
          count=20; 
          do
            nop2();     //60 uS Delay
          while (-- count > 0);
          DQ_TRI=1;                     // Make sure port is released
          nop2();            // Some Delay Between Bits
}



char dsRead(void)
{
 char count1=8,data=0;
 bit  DQdata;
 for(;count1>0;count1--)
    {  
    DQ_TRI=0;                     // Lower port
    nop();           // Timeslot start time
    DQ_TRI=1;         // Set port for reading
    nop2();
    nop2();
    nop2();
    nop2();
    DQdata=DQ_PIN;        // Read the bit on the bus
    count=12;
    do
        nop2();         //50us to finish timeslot
    while (-- count > 0);
    data = data >> 1;             // Shift previous bits (future improvement rr..)
    if(DQdata==1)                 // Add 1 if the data on the bus was 1
    data +=0x80;
    }
    DQ_TRI=1;                     // High port
    return(data);
}

bit dsReadslot(void)
{
    bit temp;
    DQ_TRI=0;                     // Lower port
    nop();           // Timeslot start time
    DQ_TRI=1;         // Set port for reading
    nop2();
    nop2();
    nop2();
    nop2();
    temp=DQ_PIN;        // Read the bit on the bus
    count=12;
    do
        nop2();         //50us to finish timeslot
    while (-- count > 0);
    return(temp);
}


#define CRC8INIT    0x00
#define CRC8POLY    0x18              //0X18 = X^8+X^5+X^4+X^0

uns8 crc8 ( uns8 *data_in, uns8 nobytsread )
{
    uns8   crc , lpcnt , bitcnt , data , fbckbit;
    crc = CRC8INIT;
    for (lpcnt = 0; lpcnt != nobytsread; lpcnt++)
    { data = data_in[lpcnt];
      bitcnt = 8;
      do 
       { fbckbit = (crc ^ data) & 0x01;
         if ( fbckbit == 0x01 ) crc = crc ^ CRC8POLY;
         crc = (crc >> 1) & 0x7F;
         if ( fbckbit == 0x01 ) crc = crc | 0x80;
         data = data >> 1;
         bitcnt--;
       } 
      while (bitcnt > 0);
    }
   return crc;
}


void putc(uns8 nate)
{
    while(TXIF == 0);
    TXREG = nate;
}

uns8 bin2Hex(char x)
{
   skip(x);
   #pragma return[16] = "0123456789ABCDEF"
}


void Serielinit(void)
{
    SPBRG = 25; //4MHz for 9600 baud rate
        count=12;
    do
        nop2();         //50us to finish timeslot
    while (-- count > 0);

    TXSTA = 0b.0010.0100; //8-bit asych mode, high speed uart enabled
    RCSTA = 0b.1000.0000; //Serial port enable, 8-bit asych continous receive mode

}

uns8 getc(void)
{
    while(RCIF == 0);
    return (RCREG);
}    



void print(const char *nate)
{
    uns8 i,k;
    for (i=0;;i++)
    {
    k=nate[i];
    if (k == 0) break;
    putc(k);
    }
}
void prhex(char u)
{
        putc(':');
        putc(bin2Hex(u >> 4));
        putc(bin2Hex(u & 0b.0000.1111));
        
}  

uns8 dsSearch(uns8 diff, uns8 *id)
{
    uns8 i,j,next_diff;
    bit  b;
    if(dsReset()) return PRESENCE_ERR;
    dsWrite(SEARCH_ROM);
    next_diff = LAST_DEVICE;
    i = ROMCODE_SIZE * 8;
    do 
    {   j = 8;                        // 8 bits
        do 
       { b = dsReadslot();            // read bit
         if( dsReadslot()) 
          { 
            if( b )                 // 11
               return DATA_ERR;  // data error
          }
         else 
          { if( !b ) 
             { // 00 = 2 devices
               if( diff > i || ((*id & 1) && diff != i) ) 
                { b = 1;               // now 1
                  next_diff = i;       // next pass 0
                }
             }
          }
         dsWriteslot(b);               // write bit
         *id >>= 1;
         if( b ) *id |= 0x80;           // store bit
         i--;
       } 
      while( --j );
      id++;                            // next byte
    } 
   while( i );
   return next_diff;                  // to continue search
 }
	
void main(void)
{
uns8 diff,u;
/*    CMCON   = 0;
    ANSEL   = 0;
    GPIO    = 0;
    TRISIO  = 0;
    #asm
    BSF STATUS,RP0
    DW 0x2000+0x03FF
    MOVWF   OSCCAL
    BCF     STATUS,RP0
    #endasm
*/ 
    PORTB = 0xFF;
  //  TRISB = 0;
    PORTC = 0b.0000.0000;
    TRISC = 0b.1000.0000;//SCL
    Serielinit();
    putc(0x0D);
 //   getc();
    print("\n Ben burdayım\n");
/*
    dsReset();
    dsWrite(0xCC);    // Skip Rom
    dsWrite(0x4E);    // Write to scratchpad
    dsWrite(0x02);    // minimum limit T
    dsWrite(0xFE);    // maximum limit T
    dsWrite(0x1F);    // T resolution is 0.5 C  
    
    print("\n DS ye yazıldı\n");
    putc(0x0D);

    dsReset();        // Reset is required before any command is issued
    dsWrite(0xCC);    // Skip Rom
    dsWrite(0x44);    // Convert T  
    nop2();
    DQ_TRI=1;         // Set port for reading
    while (DQ_PIN == 0);
    print("\n T okundu\n");
    putc(0x0D);
    dsReset();
    dsWrite(0x33);    // Read Rom
    for(i=0; i<9 ;i++){ // Read 9 bytes, only the first two bytes
        n=dsRead();   // Are needed.
        buffer[i]=n;
    }

    for(i=0;i<8;i++)
    {
    k=buffer[i];
    prhex(k);
    
    }
    
        putc('\n');
    if (crc8(buffer,8)==0) print("CRC ok!  ");
*/
  

   for( diff = SEARCH_FIRST; diff != LAST_DEVICE; )
    { diff = dsSearch( diff, &buffer[0] );
      if( diff == PRESENCE_ERR ) print( "No Sensor found\r" );
      if( diff == DATA_ERR )     print( "Bus Error\r" );
      putc(0x0D);
        if (diff != PRESENCE_ERR)
        {print("diff = ");prhex(diff);print("  ");
      for (u=0;u<8;u++)
        {  prhex(buffer[u]);print(" ");}
        if (crc8(buffer,8)==0) print("CRC ok!  ");
        putc(0x0D);
        }
    }
}


Selamlar