Haberler:

Foruma Resim Yükleme ve Boyut Sınırlaması ( ! )  https://bit.ly/2GMFb8H

Ana Menü

DS18B20...

Başlatan Logan, 18 Ocak 2008, 14:55:53

Logan

Merhaba arkadaşlar.Yaklaşık 2 gündür DS18B20'den okuma yapmaya çalışıyorum fakat ekranda sürekli 72.5 görünüyor. Entegreyi protoboarddan söktüğüm halde değer değişmiyor. Bu konu çeşitli sitelerde defalarca kez tartışıldı biliyorum fakat yerel kaynaklı ve açıklayıcı bir program bulmak neredeyse imkansız. XX_CİHAN_XX arkadaşımız sağolsun bana ASM ve CCS ile kendi yazmış olduğu programları yolladı. CCS'den pek anlamıyorum, ASM'yi ise iyi bilmeme rağmen yazan kişinin programda nasıl bir mantık kurduğunu anlamak zor oluyor. En geç yarına kadar sağlık bir şekilde programı çalıştırmam gerekli. Programın tamamı aşağıdadır, yardımlarınızı bekliyorum...

#include <pic18.h>
#include "global.h"
#include "delay.h"

__CONFIG(1,OSCSDIS&XT);
__CONFIG(2,PWRTEN&WDTDIS&WDTPS128&BOREN&BORV27);
__CONFIG(4,STVREN&LVPDIS&DEBUGDIS);

void main()
{
	TRISD=0; PORTD=0;
	TRISC=0; PORTC=0;
	TRISB=1; PORTB=0;
	reset_pin=0; DelayMs(1); reset_pin=1; DelayMs(10);
	disp_init(); clear_text(); clear_graphic();
	while(1){
	CollectData();
	cursor_write(0);
	data_bus=TmpBuffer[1]; send_data();
	data_bus=TmpBuffer[0]; send_data();
	data_bus=0x2e; send_data();
	data_bus=x+0x30; send_data();
	DelayMs(250);DelayMs(250);DelayMs(250);
	}
}


Bu da dallas.h dosyası

#include <pic18.h>
#include "global.h"
#include "delay.h"

#define  DATA_LOW   	(TRISB0 = 0)   			// define macro for data pin output 
#define  DATA_HI    	(TRISB0 = 1)   			// define macro for data pin input
#define  STATE_DATA     RB0				// define macro for state of data pin


#define FOSC	20
void DelayCycles(unsigned char TimeUS)
{
unsigned char i;
i=TimeUS*(FOSC/4);
while(i--);



asm("NOP");
asm("NOP");
asm("NOP");
}

void DS1820_ConvertT(void)
{
	DALLAS_Reset();
	
	DALLAS_Write_Byte(0xCC);	       	// skip ROM command - CCh - 0b11001100
	DALLAS_Write_Byte(0x44);        	// Convert T command - 44h - 0b01000100 
	DALLAS_Reset();        			// new reset, don't bother with presence-pulse 
}


void DS1820_RdTemp(void)
{
	DALLAS_Reset();        			// new reset, don't bother with presence-pulse 
	DALLAS_Write_Byte(0xCC);       		// skip ROM command - CCh - 0b11001100
	DALLAS_Write_Byte(0xBE);      		// read scratchpad command - BEh - 0b10111110 
	Temperature=DALLAS_Read_Byte();		// Read first temperature byte
	TemperatureByte=Temperature;
	DALLAS_Read_Byte();			// Read first temperature byte
	DALLAS_Reset();				// Abort the rest with a reset
}

 void CollectData(void)
{
	
	DS1820_RdTemp();
	DS1820_ConvertT();
  
        x = Temperature % 2;	//decimal .5 ex: 21.5
	if(x==1) { x+=4; }
        Temperature = Temperature / 2;
	TmpBuffer[1] = Temperature % 10 + 48;
        Temperature = Temperature / 10;
        TmpBuffer[0] = Temperature % 10 + 48;
}

unsigned char CRC_Algoritm(unsigned char * databuffer, unsigned char byte)
{
 unsigned int i,t,x, crc=0;
  
  i=0;
  while(1)
  {	
    byte--;	
    x=(i%8);
    t=databuffer[byte-i/8]>>x;   //t = current bit in databuffer[]
    t&=0x01;
    x=crc&0x01;         //x = bit 0 in crc 	
    crc>>=1;            //rotate crc on to the right
    if(t^x)             //if current bit in databuffer[] XOR bit 0 in crc = 1 	   
      {
      crc^=0x0c;        //XOR crc's bit 2 and 3 with 1   
      crc|=0x80;	//Set crc's bit 7 = 1	 
      }
    else
      {
      crc^=0x00;	//XOR crc's bit 2 and 3 with 0   
      crc&=0x7f;	//Set crc's bit 7 = 0	 
      } 
  byte++;
  if(i==byte*8-1) break;
  i++;			
  }
  return(crc);
}

void DALLAS_Write_Byte(unsigned char data)
{
unsigned char i;
  STATE_DATA=0;		
  for (i=0;i<=7;i++)
  {
	if(data&0x01)
	{				// write 1	
            DATA_LOW;		
	        DelayUs(10);
	    	DATA_HI;
	        DelayUs(60);
	}	
	else
	{				// write 0
    		DATA_LOW;		
	        DelayUs(60);
	        DATA_HI;		
	        DelayUs(10);
	}
	data>>=1;
  }
}

unsigned char DALLAS_Read_Byte(void)
{
unsigned char t,i;

  STATE_DATA=0;				// PORTA low     

t=0;
i=0;
while(1)
  {
    DATA_LOW;		  		// PORTA output
/*
    asm("NOP");				//These NOPS are finetuned to work with
    asm("NOP");				//DS1820, DS1992 and DS1996, and since they
    asm("NOP");				//follow the DALLAS OneWire protocol specification
		        		//(page 36-37 in the Book of DS19xx Touch Memory Standards)
       					//it probably works with all one wire devices
*/
DelayUs(3);
  
    DATA_HI;		  		// PORTA input
/*
    asm("NOP");
    asm("NOP");
    asm("NOP");
    asm("NOP");
    asm("NOP");
    asm("NOP");
*/

DelayUs(8);

    
    t>>=1; 	
    if(STATE_DATA==1)
      {t|=0b10000000;}
    else	
      {t&=0b01111111;}	
  i++;
  DelayUs(40);			    	//This delay ensures that the touch memory
  		           		//returns the I/O line to V-pullup.

  if(i==8) break;
  }
  return(t);	
}

unsigned char DALLAS_Reset(void)
{
unsigned char t;

	STATE_DATA=0;			// State of datalatch

	DATA_LOW;		        // Datapin low (TRISX.0=0)

	DelayUs(200);		// low 600us
	DelayUs(200);
	DelayUs(200);

	DATA_HI;			// PORTA input

	DelayUs(100);		// high 60us
	t=STATE_DATA;   	//Read State of datapin (Presence check)

	DelayUs(200);		// low 600us     Denne er viktig !!
	DelayUs(200);
	DelayUs(200);

	if(t) 
	  {return(0);}			//Returns 0 if no iButton present
	else
	  {return(1);}			//Returns 1 if there is a device present
}
İmza.

Logan

Sanırım aramızda bu konu hakkında Hi-Tech ile ilgili bir çalışma yapan olmadı  :!:
İmza.

james

20 mhz osilator kullanırken
__CONFIG(1,OSCSDIS&XT);  yerine   __CONFIG(1,OSCSDIS&HS);  yaparsan çalışma ihtimali var.
ARAMIYORUM , BULUYORUM

tyilgin

Umarım geç kalmamışımdır.

#define DS18B20_Pin RD7
#define DS18B20_PinYon TRISD7 ile kendi pinlerinizi ve
"unsigned char OrtamSicaklik, OrtamSicaklikOnda" şeklinde 2 değişkeni önceden tanımlamanız gerekiyor.

programınızda sadece SicaklikOku() diyorsunuz ve değerler üstte verdiğim 2 değişkene geliyor...


//***************************************************************************************
unsigned char DS18B20_init(void) {
	unsigned char sonuc;
	DS18B20_PinYon = 0;
	DS18B20_Pin = 0;
	DelayUs(490);		// > 480us
	DS18B20_PinYon = 1;
	DelayUs(65);		// > 60us
	sonuc = DS18B20_Pin;	// 0 Hazır, 1 Hazır değil
	DelayUs(400);
	return sonuc;
}
unsigned int DS18B20_Oku(void) {
	unsigned char sayac;
	unsigned int veri, bitler;
	veri=0; bitler=1;
	for (sayac=0; sayac<16; sayac++) {
		DS18B20_Pin=0; DS18B20_PinYon=0; DelayUs(1); DS18B20_PinYon=1;
		if ( DS18B20_Pin==1 ) veri|=bitler;
		DelayUs(60); bitler=bitler<<1;
	}
	return veri;
}
void DS18B20_Yaz(unsigned char veri) {
	unsigned char bitler, sayac;
	bitler = 1;
	for (sayac=0;sayac<8;sayac++) {
		if ( veri&bitler) {
			DS18B20_PinYon=0; DS18B20_Pin=0; DelayUs(3); DS18B20_PinYon=1; DelayUs(60);
		} else {
			DS18B20_PinYon=0; DS18B20_Pin=0; DelayUs(60); DS18B20_PinYon=1;
		}
		bitler=bitler<<1;
	}
}

void SicaklikOku(void) {
	unsigned char sayac, bitlertam, bitleronda;
	unsigned int sicaklik, bitler;
	DS18B20_PinYon = 0;
Tekrar:
	if ( DS18B20_init()==1 ) goto Tekrar;
	DS18B20_Yaz(0xCC); DS18B20_Yaz(0x44);
	DelayMs(250); DelayMs(250); DelayMs(250);
	if ( DS18B20_init()==1 ) goto Tekrar;
	DS18B20_Yaz(0xCC); DS18B20_Yaz(0xBE);
	sicaklik=DS18B20_Oku();
	bitler=1; bitlertam=1; bitleronda=1;
	OrtamSicaklik=0; OrtamSicaklikOnda=0;
	for (sayac=0;sayac<12;sayac++) {
		if (sayac<4) {
			if (sicaklik&bitler) OrtamSicaklikOnda=OrtamSicaklikOnda|bitleronda;
			bitleronda=bitleronda<<1;
		} else {
			if (sicaklik&bitler) OrtamSicaklik=OrtamSicaklik|bitlertam;
			bitlertam=bitlertam<<1;
		}
		bitler=bitler<<1;
	}
	OrtamSicaklikOnda = (OrtamSicaklikOnda * 625) / 1000;
}

M_B

Tyilgin hocam;
Vermiş olduğunuz kodu simulasyonda denedim , gayet güzel çalışıyor.
Ben şimdi bir hattan birden fazla  DS18B20  yi baglayıp sıcaklık bilgisini okumak için öğrenmeye çalışıyorum.
AN187 uygulama notunu anlamaya çalışıyorum. Fakat fazla ilerliyemedim. (ing. Zayıf )
Bu konu ile ilgili Hi-Tech C de yapmış olduğunuz uygulama , döküman var mı ?. Paylaşabilirmisiniz ?.

Teşekkürler

M_B



Not: Hocam sizin kod da eksi sicaklıkları okuyamıyoruz.
İmkanın sınırlarını görmek için imkansızı denemek lazım.                                                             Fatih Sultan Mehmet

Erhan YILMAZ

Aynı hatta birden fazla cihaz bağlamak için öncelikle hatta match komutu gönderiyorsun (datashette yazar) sonrasında haberleşmek istediğin cihazın 64bit rom kodunu yolluyorsun rom kod hangi cihaza ait ise o cihaz hatta iletişimi sürdürüyor diğerleride pasif olarak bekliyor taki hatta yeniden reset sinyali gönderene kadar. Tabi önce kullancağın cihazların 64bit rom kodlarını bilmen gerekiyor. Bunun içinde her bir cihazı hatta tek bağlayıp rom kodlarını okuyup kaydetmen lazım ayrıca her cihaz için hatta bir adet 4k7 pullup direnci bağlaman gerekli. Aşağıdaki linkte bu konu ile ilgili ayrıntılı bilgi var ingilizce oalrak pic basic uygulamalarıda var işine yarar

http://www.rentron.com/PicBasic/one-wire2.htm

picman

match kodu ile ilgili bir örmnek uygulama verirmisiniz. amacım sadece nasıl olduğunu öğrenmek. ds1820 ile sıcaklık verisi okumak için kendi yaptığım c kodları var ve sorunsuz çalışıyor. ama match kodu meselesini pek anlamdım. birde ısı sensörlerini nasıl aynı hatta bağlaya biliriz . aynı seri epromlarda olduğu gibi. data uclarını birbirine bi bağlamalıyız bu konu hakkında da bilgi verirseniz sevinirim arkadaşalar . çalışmalarınızda başarılar dilerim ...
Bilgi paylaştıkça artar..

XX_CİHAN_XX

asm, ccs vermişiz bide hi tech versiyonunu verelim hocam buyur :)
#include	<pic.h>
	#include 	"delay.h"
 #define DQ_TRIS	TRISA2
 #define DQ_PIN		RA2
 unsigned char ow_reset(void){
 unsigned char onay;
 DQ_TRIS=1;
 DQ_PIN=0;
 DQ_TRIS=0;
 DelayUs(250);
 DelayUs(250);
 DQ_TRIS=1;
 DelayUs(65);
 onay = DQ_PIN;
 DelayUs(250);
 DelayUs(250);
 return(onay);
}	//"0" değeri dönmelidir!!!

unsigned char ow_read(void){
 unsigned char i;
 unsigned char value;
 for (i=8;i>0;i--){
 DQ_PIN=0;
 DQ_TRIS=0;
 DelayUs(5);
 DQ_TRIS=1; 
 DelayUs(3);
 value = value >> 1;
 if(DQ_PIN)value |= 0x80;
 DelayUs(55);
}
 return(value);
}

void ow_write(unsigned char data){
 unsigned char i;
 for (i=8; i>0; i--){
 DQ_PIN=0;
 DQ_TRIS=0;
 DelayUs(3);
 data = data >> 1;
 DQ_TRIS=CARRY;
 DelayUs(55);
 DQ_TRIS=1;
 DelayUs(5);
}
}
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

M_B

@XX_CİHAN_XX hocam;
Elinizde :ID Rom Match  okuma ile ilgili kodda mevcut mu. An187 Nolu uygulama notunu ve rentron.com dahi bilgileri baktım ama bir turlu elle tutulur bir şey elde edemedim. Halen üzerinde çalışmaktayım. ( Tek hat üzerinde Birden fazla DS18B20 ısı sensorun degerlerini okumak istiyorum )
Kolay gelsin
Mehmet

@FixDev hocam sizinle ilgili kısım:
__CONFIG(WDTDIS&PWRTEN&LVPDIS&INTIO&MCLRDIS);

ornek config ayarı.

Kristal ayarının nasıl yapıldığını  arslan74 hocamız acıklamıs:
#ifndef XTAL_FREQ 
#define XTAL_FREQ 4MHZ /* Crystal frequency in MHz */ 
 


Kısmında 4 yazan yere 20 yap başka bir şey yapmana gerek yok. 

Yani şöyle: 

Kod: 

#ifndef XTAL_FREQ 
#define XTAL_FREQ 20MHZ /* Crystal frequency in MHz */
İmkanın sınırlarını görmek için imkansızı denemek lazım.                                                             Fatih Sultan Mehmet

Erhan YILMAZ

Sitede gayet güzel açıklamış birde kendi denediğim kodları ekliyorum devrede 2 tane ds1820 kullanılmıştır ikisininde seri noları önceden bilinmektedir.Ana programda ilk önce 55h karşılaştırma komutu gönderilir ondan sonraki 8 byte ise ds1820nin 64 bit laser rom nosudur ensonda 44h dönüşümü başlat komutu ile sıcaklık dönüşümü başlatılır. alt saıtrda yine 55h karşılaştırma komutu ve cihazın seri nosu ardından beh kodu gönderilip sıcaklık bilgisi okunur anlattıklarım diğer sensör içinde aynı şekildedir devrede iç ve dış sensör olmak üzere iki sensör vardır. ikiside aynı hat üzerinden haberleşiyor tabi bunların seri nolarını daha önceden okuyupta yaptırdım bu işlemleri sonrasında cihaz bilgisayar haberleşmeli oldugundan sıcaklık değeri bilgisayara gönderilir.

@ DEVICE PIC16F628A
@ DEVICE PIC16F628A,XT_OSC
@ DEVICE PIC16F628A, WDT_OFF
@ DEVICE PIC16F628A, PWRT_ON
@ DEVICE PIC16F628A, PROTECT_OFF
@ DEVICE PIC16F628A, MCLR_OFF
define  OSC 4
ds_test_ic  var     byte           
ic_isi     var     byte
kusurat_ic  var     byte 
ds_test_dis  var     byte           
dis_isi    var     byte
kusurat_dis  var     byte      
DQ       var     PORTB.4                         
CMCON=7                            
basla:
OWOut DQ, 1, [$55,$10,$2D,$3B,$87,$00,$08,$00,$DA,$44]
OWOut DQ, 1, [$55,$10,$2D,$3B,$87,$00,$08,$00,$DA,$BE]
OWIn DQ, 0, [ic_isi,skip 5, DS_Test_ic]
OWOut DQ, 1, [$55,$10,$AD,$F2,$6C,$01,$08,$00,$97,$44]
OWOut DQ, 1, [$55,$10,$AD,$F2,$6C,$01,$08,$00,$97,$BE]
OWIn DQ, 0, [dis_isi,skip 5, DS_Test_dis]
if ic_isi.0=0 then
kusurat_ic=0
else
kusurat_ic=5
endif
if dis_isi.0=0 then
kusurat_dis=0
else
kusurat_dis=5
endif
serout PORTB.2,2,["ET",ic_isi,kusurat_ic,ds_test_ic,dis_isi,kusurat_dis,ds_test_dis] 
Goto basla                                             
End

XX_CİHAN_XX

@M_B, @tamirci_erhan arkadaşım detaylı bir şekilde anlatmış.
DS18b20 nin pdf inide iyice incelemeni tavsiye ederim. Yabancı dilin olmasa bile sinyal diyagramlarından birçok şeyi kapabilirsin.
Bende bu konu ile ilgili örnek kod olsa bir tanede ben koyardım. :)

Herkese iyi çalışmalar,
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

M_B

@tamirci_erhan hocam aciklmanız için teşekkürler
Seri nosunu bilmediğimiz DS olunca önce onun seri nosunu öğrenmemiz gerekiyor. Benim Sorunum öğrenme kısmında.  ( Yani ID okumada )
Biraz daha datasheet ve forumdaki basic orneklere bakayım. Hi-Tech C ye uyarladığımda burda kodu yayınlayacam.

Saygılarımla
Mehmet
İmkanın sınırlarını görmek için imkansızı denemek lazım.                                                             Fatih Sultan Mehmet

M_B

@FixDev
Ben MPLAB da denedim herhangi bir hata mesajı vermedi.

Benim yaptığım işlem:

- Öncelikle delay.h dosyasını actım  
icine  4 MHz olan yere 20 yazdım.

sonrada aşağıdaki kodu derleedim ve çalıştı
#include <pic.h> 
#include "delay.h"

__CONFIG(WDTDIS&PWRTEN&LVPDIS&INTIO&MCLRDIS); 




void main(void) 
{ 
   TRISA=0x00; 
   TRISB=0x01; 
    
   PORTA=0x00; 
   PORTB=0x00; 
    
   CMCON=0x07; 
   while (1) 
   { 
      PORTA=RB0; 
   } 
}


Not: Ben Hi-Tech ide sini kullanmıyorum. Hep MPLAB altın da  yapıyorum.

Kolay gelsin.
Mehmet
İmkanın sınırlarını görmek için imkansızı denemek lazım.                                                             Fatih Sultan Mehmet

MURSEL

Alıntı YapSeri nosunu bilmediğimiz DS olunca önce onun seri nosunu öğrenmemiz gerekiyor. Benim Sorunum öğrenme kısmında. ( Yani ID okumada )
onewire_reset();
onewire_write(0x33);
data_rom[i++][t]=onewire_read();  aile kodu
data_rom[i++][t]=onewire_read();
data_rom[i++][t]=onewire_read();
data_rom[i++][t]=onewire_read();   ortadaki 6 bayt seri no
data_rom[i++][t]=onewire_read();
data_rom[i++][t]=onewire_read();
data_rom[i++][t]=onewire_read();
data_rom[i++][t]=onewire_read(); crc


bu  sekilde rom kodlarını alınıyor  bir butonla teker teker birden fazla ds18s20 nin rom kodlarını kaydedip  sonra hepsini hatta baglayıp degerleri okuyabiliyorum  fakat asıl sıkıntı  teker teker kaydetdetmektense  hatta baglı tüm cihazlrın rom kodlarını nasıl ögrenicez
SEARCH ROM [F0h]  böyle bir komut var ama daha çözemedim

cdurakbasi

Geç oldu ama yeni görüp cvp yazayım dedim.Bildiğim kadarıyla Microchip in bu konuda bir datasheet i var. Çoklu ROM öğrenme algoritmasından bahsediliyordu şimdi hatırımda değil araştırılırsa bulunabilir. Ama ben zamanında çok karışık bulmuştum. Bilmiyorum eğer sistemde 100lerce sensor var ise o algoritma nasıl ne hızda çalışır artık?