18B20, 24c512 ve DS1307.

Başlatan Logan, 22 Ekim 2007, 15:46:42

Logan

Merhaba arkadaşlar. Birkaç aydır Hi-Tech C kullanıyorum ve oldukça işlevsel olduğu kanısındayım. Fakat bir kaç konuda takıldım ve yardımınıza ihtiyacım var. Bana 18B20, DS1307 ve 24C512 ile ilgili C ile yazılmış örnek program gerekli. Fakat yabancı kaynaklı olmasını istemiyorum. Mümkün mertebe kendi yazmış olduğunuz programları paylaşırsanız çok sevinirim. Bu şekilde anlama ve idrak etme açısından daha hızlı yol alacağımı düşünüyorum. Hepinize iyi çalışmalar, iyi günler...
İmza.

Cetinal

hitex içinde varmı bilmem ama CCS içerisinde Examples klasörü içerisinde ve MikroC nin examples klasörü içerisinde bu istedikleriniz ve daha fazlası mevcut

bikaç değişiklikle hitex de derleme yapabilirsiniz

Mesela biltek in yayınladığı kayan yazı hitex ben bi kaç tanımlama değişiklikleriyle CCs de rahatlıkla derlemiştim ozamanlar....
Kolay Gelsin

RoMeO

Macera

İşine yararmı bilmem ama deneme amaçlı bir DS18B20 programını 4 Mhz 16F877 de çalıştırdım.Burda benim için önemli olan OneWire ağ protokolünü öğrenmekti.Burdan indirebilirsin.Unutmadan söyliyim derleyici olarak CC5X kullandım.Ama Hitech'e uyarlamak zor olmasa gerek.
"Art without engineering is dreaming; engineering without art is calculating." -- Steven K. Roberts

arslan74

Merhaba,

DS1302 realtime clock için kütüphane yolluyorum.

Kütüphaneyi kullanma şekline örnek;

Yazmak için;

write_DS1302( MINUTE, 0x32 );
	write_DS1302( DATE, 0x26 );
	write_DS1302( HOUR, 1 );
	write_DS1302( MONTH, 8 );
	write_DS1302( YEAR, 7 );


Okumak için;

second = read_DS1302(SECOND);
	minute = read_DS1302(MINUTE);
	hour   = read_DS1302(HOUR);


	date   = read_DS1302(DATE);
	month  = read_DS1302(MONTH);
	year   = read_DS1302(YEAR);




DS1302.c

/*******************************

	DS1302 CHIP SET KODU.

*******************************/

#include <pic.h>
#include "DS1302.h"
#include "delay.h"


void init_DS1302( void ){
	
	unsigned char sec_val;
	
	RST = 0;
	DelayUs(2);
	SCLK = 0;
	DelayUs(2);
	
	write_DS1302( CONTROL, 0 );
	
	write_DS1302( CHARGER, 0b10100110 );
	
	sec_val = read_DS1302(SECOND);
	
	if ( sec_val & 0b10000000 )	// Eper saat kristali kapalı ise ac.
			write_DS1302( SECOND, 0b00000000 );
} //



void write_DS1302(unsigned char reg_val, unsigned char data) {

	unsigned char bits;
		
	TRIS_IO = 0;	// output
	DelayUs(8);
	
	reg_val--;
	
	RST = 1; // Enable
	
	for ( bits=0; bits<8; bits++ ){
	
		if ( reg_val & (1 << bits) )	//
			send_bit_1();
		else
			send_bit_0();
	}
	
	for ( bits=0; bits<8; bits++ ){
	
		if ( data & (1 << bits) )	//
			send_bit_1();
		else
			send_bit_0();
	}

	RST = 0; //Disable
	DelayUs(2);
	TRIS_IO = 0;	// output
	DelayUs(2);
	SCLK = 0;	
	DelayUs(2);
}


unsigned char read_DS1302 ( unsigned char reg_val ){
	
	unsigned char val, bits;
		
	TRIS_IO = 0;	// output
	DelayUs(2);

	RST = 1; // Enable
	DelayUs(2);
	
	for ( bits=0; bits<8; bits++ ){
	
		if ( reg_val & (1 << bits) )	//
			send_bit_1();
		else
			send_bit_0();
	}
	
	TRIS_IO = 1;	// input
	DelayUs(2);
	
	for ( bits=0; bits<8; bits++ ){
		
		SCLK = 0;
		
		if (IO == 1 )	
			bitset(val,bits);
		else 
			bitclr(val,bits);

		SCLK = 1;
					
	}
	
	RST = 0; //Disable
	DelayUs(2);
	TRIS_IO = 0;	// output
	DelayUs(2);
	SCLK = 0;
	DelayUs(2);

	return val;
	
} //



void send_bit_1(void){
	
	IO = 1;
	DelayUs(2);
	SCLK = 0;
	DelayUs(2);
	SCLK = 1;
	DelayUs(2);
	
}

void send_bit_0(void){
	
	IO = 0;
	DelayUs(2);
	SCLK = 0;
	DelayUs(2);
	SCLK = 1;
	DelayUs(2);
	
}



unsigned char BCD_2_bin (unsigned char data){

	/* Convert a BCD number to a binary character */

	unsigned char temp = 0;

	temp = (((data & 0xF0)>>4)* 0x0A);			// high nibble X 10
	temp = temp + (data & 0x0F);			// add low nibble
	
	return temp;
}


unsigned char bin_2_BCD (unsigned char data){

	/* Convert a binary number to BCD */

	char temp = 0;	
	while (data > 9){
		temp = temp + 0x10;				//  not an efficient routine but acceptable
		data = data - 10;					// since 31 is the largest number
	}
	temp = temp + data;
	
	return temp;
}



DS1302.h

/*******************************

	DS1302 CHiP SET READ KODU.

*******************************/


#ifndef	_DS1302_H
#define	_DS1302_H


#define bitset(var,bitno) ((var) |= 1 << (bitno))
#define bitclr(var,bitno) ((var) &= ~(1 << (bitno)))


#define TRIS_IO TRISE1

#define  SECOND		0x81
#define  MINUTE		0x83
#define  HOUR		0X85
#define  DATE		0X87
#define  MONTH		0X89
#define  DAY		0X8B
#define  YEAR		0X8D
#define  CONTROL	0X8F
#define  CHARGER	0X91



static	bit	SCLK  	@ (unsigned)&PORTE*8+0;	// use this bit to 
static	bit	IO		@ (unsigned)&PORTE*8+1;	// use this bit to 
static	bit	RST  	@ (unsigned)&PORTE*8+2;	// use this bit to 




void init_DS1302(void);

unsigned char read_DS1302 ( unsigned char );

void send_bit_1(void);

void send_bit_0(void);

unsigned char BCD_2_bin (unsigned char data);

unsigned char bin_2_BCD (unsigned char data);


void write_DS1302( unsigned char cmd, unsigned char data );

	
#endif



Kodda herhangi bir sorun yok kod çalışıyor. Kullanmak isteyen arkadaşlara başarılar;

Selamlar

Logan

@Macera, yolladığın kod sanırım işimi görecek. Üzerinde biraz uğraşırsam birkaç saat falan Hi-Tech'e çevirebilirim. @arslan74, DS1302 ile ilgili herhangi bir problemim yok, bildiğimiz SPI protokolü. Eğer elinde DS1307 ve 24C512 ile ilgili kaynak varsa ve paylaşırsan çok iyi olur.  :)
İmza.

M_B

Merhaba Arslan74 hocam;
Yukardaki mesajda ds1302 ile ilgili kutuphanenizi yayınlamıssınız. ( oncelikle teşekkürler )
Hocam sizin kutuphaneyi sanal ortamda pic16f628 ile kullanmak istedim ve aşağıdaki gibi degişiklikler yaptım ama sonuca ulasamadım. Bu konu hakkında yardımcı olabilirmisiniz.

ds1302.h dosyasında yaptıgım degisiklikler.

#define TRIS_IO TRISB1

Not: TRISB yaptım gene aynı.
Yalnız TRISB1 yapınca saat kısmın ilk hanesi cıkıyor

static   bit   SCLK    @ (unsigned)&PORTB*8+4;   // use this bit to 
static   bit   IO      @ (unsigned)&PORTB*8+5;   // use this bit to 
static   bit   RST     @ (unsigned)&PORTB*8+6;   // use this bit to


Hocam yoksa bu ds1302 kutuphanemiz pic16f628 icin uygun değilmi yoksa baska yerde de degısıklık yapmak gereklimi

Benim programın tum kodu:
#include <pic.h>
#include "ds1302.h"
#include "delay.h"
// sigorta ayarları yapılıyor.
__CONFIG(INTIO & WDTDIS & LVPDIS & PWRTEN & BOREN );


#define SH_CP RB0
#define DS RB1
#define ST_CP RB2
#define tus RB3


unsigned char number[10]={0x5F,0b00000110,0x9B,0x8F,0xC6,0xCD,0xDD,0x07,0xDF,0xCF};
unsigned char digit[6]={0,0,0,0,0,0};
unsigned char i;
unsigned char n;
unsigned char counter;
unsigned char x1;
unsigned char x2;
unsigned char x3;
unsigned char x4;
unsigned char x5;
unsigned char x6;

	

static void interrupt
 isr(void)             
{
	if(T0IF)
		{
			if(counter ==5)
				{ DS=0;
				  SH_CP=1;
				  SH_CP=0;
				 // DelayUs(25);
				  counter = 0;
			    }
			 else
				 { DS=1;
		   		   SH_CP=1;
				   SH_CP=0;
				 //  DelayUs(25);
				   counter ++; 
				 }
					ST_CP=1;
				    ST_CP=0;
					PORTA=0;
					PORTA=number[digit[counter]];
		} T0IF =0;
}
				
	
main(void)
{
unsigned char saat,dakika,saniye;
unsigned char saat10,saat1,dakika10,dakika1,saniye10,saniye1;

TRISA=0b00000000;
PORTA=0b00000000;
TRISB=0b00001000;
PORTB=0b00000000;
CMCON=0x07;
OPTION=0b00000001;

counter =0;

    TMR0 = 0;	// TMR0 sayacını sıfırla.
	T0IF = 0;	// interrupt flagini sıfırla
	T0IE = 1;	// RB0 interuprunu devreye sok.
	GIE  = 1;	// Acık olan bütün interupları devreye sok.

DS=0;
SH_CP=0;
ST_CP=0;
init_DS1302();

for(;;)
		{

	    saniye = read_DS1302(SECOND); 
   	    dakika = read_DS1302(MINUTE); 
   		saat   = read_DS1302(HOUR); 


    	// date   = read_DS1302(DATE); 
   		// month  = read_DS1302(MONTH); 
   		// year   = read_DS1302(YEAR); 



		saat10=saat/16;
		saat1=saat%16;
		dakika10=dakika/16; 
		dakika1=dakika%16;
		saniye10=saniye/16;
		saniye1=saniye%16;


			digit[0]=saat10;
			digit[1]=saat1;
			digit[2]=dakika10;
			digit[3]=dakika1;
			digit[4]=saniye10;
			digit[5]=saniye1;
	

		}
}


Not: Bu program 6 Tane 7 segmentlı  displaye 74hc595 entegresi yardımıyla veriler yazdırılıyor.
İmkanın sınırlarını görmek için imkansızı denemek lazım.                                                             Fatih Sultan Mehmet

M_B

Hocam sorunu cozdum.

#define TRIS_IO TRISB5

yapınca calısmaya basladı.

Hocam aklıma soyle bır soru geldı
#define TRIS_IO TRISB5 yapınca RB5 ile alakalı register yonetimini secıyoruz

Nasıl bır makro yazmalıyım ki.  TRIS_IO diyince RB4, RB5 , RB6 ( TRISB4,TRISB5,TRISB6)  secebilmeliyim.

Teşekkürler
İmkanın sınırlarını görmek için imkansızı denemek lazım.                                                             Fatih Sultan Mehmet

arslan74

Alıntı yapılan: "M_B"Hocam sorunu cozdum.

#define TRIS_IO TRISB5

yapınca calısmaya basladı.

Hocam aklıma soyle bır soru geldı
#define TRIS_IO TRISB5 yapınca RB5 ile alakalı register yonetimini secıyoruz

Nasıl bır makro yazmalıyım ki.  TRIS_IO diyince RB4, RB5 , RB6 ( TRISB4,TRISB5,TRISB6)  secebilmeliyim.

Teşekkürler

Merhaba,

En başta define ile yazılanı bir makro olarak görmeyin bu kod sadece derleyicinin derleme yapmadan önce TRIS_IO gördüğü yeri TRISB5 değiştirib, ondan sonra derleme yapar. Yani Sen kendinde TRIS_IO yazmak yerine doğrudan TRISB5 de yazsan aynı şeyi yazmış olursun. Ancak TRISB5 ne amacla kullanıldığını ilk bakışta anlamak kolay değil o yüzden kodun okunaklığı zor, bu yüzden daha okunaklı olması için böyle yapıldı.

TRISB5 ise ne anlama geldiğini kullandığın registerin include dizinin içinde kullandığın PIC'in header dosyası "pic16f62xa.h" incele, orada hepsi var.

Selamlar

M_B

Merhaba Hocam
Devamlı kafama takılan bir soru var onuda sizlere sormak istiyorum.
ornegin aşağıdaki kısımda  once tanımlamalar yapılmış
#define SCL RC3
#define SDA RC4
Bu kısımda sorun yok.

#define SDA_TRIS TRISC4
#define SCL_TRIS TRISC3
aslında burda da sorunum yok burdakı tanımla RC3 veya RC4  giriş veya cıkış ayarlamak ıcın kullanıyoruz.


#define   SCL      RC3  		 //-- The SCL output pin 
#define   SDA      RC4  	 	 //-- The SDA output pin 

#define   SDA_TRIS   TRISC4   	//-- The SDA output pin 
#define   SCL_TRIS   TRISC3  	//-- The SCL output pin


void set_sdo_low ( void )
{ 
   SDA = 0;    
   SDA_TRIS = 0; 
} 

void set_sdo_high ( void )
{ 
   SDA = 0;    
   SDA_TRIS = 1; 
}

kafama takılan kısım
void set_sdo_high ( void )
{ 
   SDA = 0;    
   SDA_TRIS = 1; 
}  


burda neden SDA_TIRS =1 yaptık.  Birden giriş icin ayarladık.

void set_scl_low ( void )
{ 
   SDA = 0;    
   SDA_TRIS = 0; 
}


kısımda ıse tekrar neden cıkıs ayarlandı.

hocam ust ksımdakı program parçası sizin 877 icin hazırlamış oldugunuz i2c  ksımdan alıntıdır.
Program ıcınde bu sekılde kullanılmasına ( giriş çıkış olarak konum degiştirmesi ) duyduguma gore tristate surum mu ne denıyormuş
tam olarak bilmiyorum ve bu tur kullanımın bize ne tur avantajları vardır.
nasıl bır fayda saglıyor.

ornegin bu bahsettığim olay jalın i2c kutuphanesinde de mevcut.

i2c ile ilgili bir takım dokumanlar da okudum ama bu bahsettigim olay i2c protokolu ıcın değil başka uygulamalarda da kullanılıyor.

Hocam sorum biraz karısık ve uzun oldu kusuruma bakmayın.  
Herturlu aydınlatıcı bilgi icin size teşekkür ediyorum sayenizde bir seyler ogreniyorum

_____________________________________________________________
Not: i2c icin  bilgi:

START ve STOP durumu:
Haberleşmenin başlaması için master tarafından yola Bir START ın gönderilmesi gerekir.  Haberleşme yoksa pull-up dirençler den dolayı her iki yolda HIGH dır. Yazılım ile SDA yükseğe çekilir peşinden SCL yükseğe çekilir. Bu iki işlem sadece yol güvenliği için .SCL yüksekken SDA düşüğe çekilirseyol bir START komutu gönderilmiş olur.

Haberleşmenin sonlandırılması ve yolun serbest bırakılması için ise SDA düşüğe çekilir SCL yükseğe çekilir ve bu anda tekrar SDA yükseğe çekilirse bir STOP komutu gönderilmiş olur.
İmkanın sınırlarını görmek için imkansızı denemek lazım.                                                             Fatih Sultan Mehmet