Hi-Tech C de i2c eprom okuma sorunum

Başlatan tyilgin, 05 Ocak 2008, 21:56:33

tyilgin

Alıntı YapMerhaba,

öncelikle bizden yardım istiyorsunuz ama bizim dediklerimizi yapmiyorsunuz.

Dediğiniz şekilde denedim ancak hiçbiri çalışmayınca basicte yazdığım, çalıştığını gördüğüm bir kodu emsal almak için bu simülasyon üzerinde çalışmaya başladım.

Alıntı YapBelirmeme rağmen siz CLK ucununa PULLUP direnci koymuşsunuz. Öncelikle bunu cıkartın öyle deneyin.

hiç bir örneği bu şekilde çalıştıramadım.


Alıntı YapProteusun hangi versiyonunu kullandığınız bilmiyorum ama benim kullandığım 7.1 SP4 de örnek 3 tane simulasyon var.
Örneğin, "i2cmem3" simulasyonunu ac biraz incele. Oradan, program neler yapiyor, onu anlamaya çalış. Program önce EEPromun 100 nolu adresinden itibaren sirayla bilgi yazmaya balşiyor. Sonra bu yazdıkları okuyub doğru yazmışmı diye kontrol ediyor.

Proteus 7.2 SP0 kullanıyorum ve içinde sadece i2cmem1 adında bir örnek
mevcut simülasyonda çalıştığına dair en ufak bir iz olmamasına rağmen onunda clk bacağında pullup direnci var.

Alıntı YapSana ben hazır kodu veririm ama niyetim sana balik tutmasını öğretmek olduğu için bu yolu gösteriyorum.

Gerçi size değil, forum yöneticisine bu bölümde yazdığım mesajlarımı silmesin diye yazarken bildirmiştim. Çalıştığım projenin yaklaşık 4000 satırı bulması ve 16F877 ye sığmaması ve PicBasic 'in 18F serisini derlememesi üzerine proje baskısı altında Hi-Tech i öğrenmeye çalışıyorum. Belki lise öğrencileri bu kodlarla oynayarak kendini geliştirebilir ancak 4000 satırları bulan projelerle uğraşan biri artık balığı oltayla değil zıpkınla su altında avlıyor demektir. Zaten amacı birşeyler öğrenmek olan sabahlara kadar uğraşıp bunlarla boğuşmaz. İhtiyacım olan sadece debugger mış. Eğer en azından "i2cmem3" den bahsetmiş olsaydınız emsal kodun bende olmadığını görerek boşu boşuna i2cmem ile boğuşup yıllar önce kullandığım asm yi hatırlamaya çalışarak bir gece sabaha kadar bununla boğuşmazdım.

Ama yinede koca forumda bir siz, birde Macera konu ile ilgilendiği için ayrı ayrı teşekkür etmek boynumun borcu,

Tekrar tekrar teşekkür ederim.....

tyilgin

Ben balık vermekmi tutmayı öğretmekmi konusunda kütüphane olacak şeylerin verilmesi taraftarıyım. Birisi çıkıp "bana şunu şunu yapan bir program lazım" derse ona bunun nasıl yapılacağını anlatarak öğretmeye çalışabilirim. Ancak kütüphane haline gelmiş şeyler o işin yapılması için bir araç haline gelmişse, hedefe ulaşmak için önce araç yapımı ile uğraştırmak benim fikrime göre doğru değil. O zaman oturup herkese kütüphaneleri yazdırmalı hatta asm den başlatıp C'yi kodlattırmamız gerekmezmi ?

Aşağıdaki linkte kendi yazdığım kodu paylaşıyorum. Bu arada nette bulduğum örnek kodlarda da i2c debugger ile incelediğimde hatalar gördüm. eğer i2c üzerinde çalışmalara yeni başlayacaksanız mutlaka debugger elinzin altında olmalı.

http://forum.donanimhaber.com/m_20145662/mpage_1/key_//tm.htm#20201433

Umarım bu konu ile uğraşacak arkadaşlara bundan sonra örnek teşkil eder.

arslan74

Merhaba,

Size kendimin kullandığı 877 ile i2c haberleşme kodunu veriyorum. PIC'in kristali 4Mhz göre yazılmıştır. Kristal değişirse bekleme süreleri yeniden ayarlanmalı. Ben bu kodu 24c512 ile haberleşmede kullaniyorum. O yüzden okuma adresini 16bit olarak geciyorum.

Ayrıca size olmadığını söylediğiniz, proteus simulasyonunu gönderiyorum.

http://rapidshare.com/files/82172645/PIC_Serial_Memory_Example.rar.html



"877-i2c.h" dosyası
/******************************************************************************************/
// Hardware I2C single master routines for PIC16F877
// for HI-TEC PIC C COMPILER.
//
/******************************************************************************************/



#ifndef	_877_I2C_H
#define	_877_I2C_H


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


#define I2C_EE_WRITE   0b10100010 
#define I2C_EE_READ    0b10100011 


#define INPUT	1
#define OUTPUT	0


#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



unsigned char i2c_write( unsigned int eeadr, unsigned char data);

unsigned char i2c_read(unsigned int address);



void i2c_bit_1(void);
void i2c_bit_0(void);

void i2c_init(void);

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

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

void i2c_start(void);

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

void i2c_repStart(void);


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

void i2c_stop(void);

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


void i2c_error(unsigned char err );

unsigned char i2c_ack( void );

void i2c_nack( void );


void wait_quarter_bit (void);
void wait_half_bit (void);

void wr_reset( void );

void set_clk_low ( void );

void set_clk_high ( void );

void set_sdo_low ( void );

void set_sdo_high ( void );

void i2c_write_byte ( unsigned char byte );

unsigned char i2c_read_byte(void);


#endif


"877-i2c.c" Dosyası

/******************************************************************************************/
// Hardware I2C single master routines for PIC16F877
// for HI-TEC PIC C COMPILER.
//
// i2c_init  - initialize I2C functions
// i2c_start - issue Start condition
// i2c_repStart- issue Repeated Start condition
// i2c_stop  - issue Stop condition
// i2c_read(x) - receive unsigned char - x=0, don't acknowledge - x=1, acknowledge
// i2c_write - write unsigned char - returns ACK
//

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

#include <pic.h>
#include "877-i2c.h"
#include "delay.h"




void wait_half_bit (void){
	
// 212us delay time
	
//DelayUs(250);
//DelayUs(250);

DelayUs(180);
	
	
}


void wait_quarter_bit (void){
	
//DelayUs(250);

DelayUs(90);
	
}



void wr_reset( void ){

	
	wait_half_bit ();
	set_clk_low();
	wait_half_bit ();
	set_sdo_low();
	wait_half_bit();
	set_clk_high();
	
	DelayMs(1);	// 2

	set_sdo_high();

	DelayMs(1);	// 2
	
	set_clk_low();		// bit 0
	wait_half_bit ();
	set_clk_high();
	wait_half_bit();

	set_clk_low();		// bit 1
	wait_half_bit ();
	set_clk_high();
	wait_half_bit();

	set_clk_low();		// bit 2
	wait_half_bit ();
	set_clk_high();
	wait_half_bit();

	set_clk_low();		// bit 3
	wait_half_bit ();
	set_clk_high();
	wait_half_bit();

	set_clk_low();		// bit 4
	wait_half_bit ();
	set_clk_high();
	wait_half_bit();

	set_clk_low();		// bit 5
	wait_half_bit ();
	set_clk_high();
	wait_half_bit();

	set_clk_low();		// bit 6
	wait_half_bit ();
	set_clk_high();
	wait_half_bit();

	set_clk_low();		// bit 7
	wait_half_bit ();
	set_clk_high();
	wait_half_bit();

	set_clk_low();		// bit 8
	wait_half_bit ();
	set_clk_high();
	wait_half_bit();
	
}


void i2c_init(void) {

    RC3 = 1; 
    RC4 = 1; 

	TRISC3=0;           // set SCL and SDA pins as inputs
	TRISC4=0;

	wr_reset();

} //




unsigned char i2c_write( unsigned int address, unsigned char data ) {
	
  	unsigned char reg_val;
  	
  	
    i2c_start();
 //	i2c_Restart();
 
	reg_val = I2C_EE_WRITE;	// Write condition
      
	i2c_write_byte( reg_val);
	
	if (i2c_ack())
		return 1;
	
	reg_val = address/256;	// Write condition
	
	i2c_write_byte( reg_val);
	
	if (i2c_ack())
		return 1;
	
	reg_val = address;	// Write condition
    
	i2c_write_byte( reg_val);
	
	if (i2c_ack())
		return 1;
	
	reg_val = data;	// Write condition
    
	i2c_write_byte( reg_val);
	
	if (i2c_ack())
		return 1;
  
 	i2c_stop();
 
    delay_ms(10);
 	
 	return 0;
 } 


unsigned char i2c_read(unsigned int address) 
{ 
    unsigned char	ee_data; 
   	unsigned char	reg_val;
  	
  	
//    i2c_start();
	i2c_repStart();
 
	reg_val = I2C_EE_WRITE;	// Write condition
      
	i2c_write_byte( reg_val);
	
	if (i2c_ack())
		return 1;
	
	reg_val = address/256;	// Write condition
	
	i2c_write_byte( reg_val);
	
	if (i2c_ack())
		return 1;
   
	reg_val = address;	// Write condition
    
	i2c_write_byte( reg_val);
	
	if (i2c_ack())
		return 1;
    
 	i2c_repStart();	// Restart 
   
 	reg_val = I2C_EE_READ;	// Read condition
      
	i2c_write_byte( reg_val);
	
	if (i2c_ack())
		return 1;
   
    ee_data = i2c_read_byte();
    
 	i2c_nack();
    i2c_stop();
    
    return ee_data; 
    
} 


unsigned char i2c_read_byte(void){
	
	unsigned char read_data;
	
	unsigned char bits;

	for ( bits=0 ; bits < 8 ; bits++ ){
		
		set_sdo_high();
		
		set_clk_low();
		wait_half_bit();
		
		set_clk_high();
		wait_quarter_bit();
	
		if (SDA)	
			bitset(read_data,(7-bits));
		else
			bitclr(read_data,(7-bits));

		wait_quarter_bit();
		set_clk_low();
		
	}
	
	return read_data;
	
}

	


void i2c_write_byte ( unsigned char byte ){

	unsigned char bits;

	for ( bits=0 ; bits < 8 ; bits++ ){
	
		if ( byte & (1 << (7-bits)) )	//
			i2c_bit_1();
		else
			i2c_bit_0();
	}

}





void i2c_start(void)
{

	set_clk_high();
	wait_half_bit();

	set_sdo_low();
	wait_half_bit ();

	set_clk_low();
	wait_half_bit ();
	wait_half_bit ();
	wait_half_bit ();


}


/*
 * 	Send (re)start condition
 * 	  - ensure data is high then issue a start condition
 * 	  - see also i2c_Start() macro
 */


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

void i2c_repStart(void)
{	

	set_clk_high();
	wait_half_bit();
	
	set_sdo_low();
	wait_half_bit ();
	
	set_clk_low();
	wait_half_bit ();
	wait_half_bit ();
	wait_half_bit ();
	
}

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

void i2c_stop(void)
{

	wait_half_bit();

	set_clk_low();
	wait_half_bit();

	set_sdo_low();
	wait_half_bit();

	set_clk_high();
	wait_half_bit();

	set_sdo_high();
	wait_half_bit();

}




unsigned char i2c_ack( void ){
	
	unsigned char ack_status;


	wait_quarter_bit();
	
	set_sdo_high();
	
	wait_quarter_bit();
	
	set_clk_high();
	
	wait_quarter_bit();

	if (SDA)	
		ack_status = 1;
	else
		ack_status = 0;

	wait_quarter_bit();
	
	set_clk_low();
	
	wait_quarter_bit();

	return ack_status;
}


void i2c_nack( void ){
	
	set_clk_low();
	wait_half_bit();
	
	set_sdo_high();
	wait_half_bit();
	
	set_clk_high();
	wait_half_bit();
	
	set_clk_low();
	wait_half_bit();
	wait_half_bit();
		
}



void i2c_bit_1(void){	

	wait_quarter_bit();
	set_sdo_high();
	
	wait_quarter_bit();
	set_clk_high();
	
	wait_half_bit();
	set_clk_low();

}

void i2c_bit_0(void){
	
	wait_quarter_bit();
	set_sdo_low();
	
	wait_quarter_bit();
	set_clk_high();
	
	wait_half_bit();
	set_clk_low();

}


void set_clk_low ( void ){
	
	SCL = 0;	
	SCL_TRIS = 0;
	
}

void set_clk_high ( void ){
	
	
	SCL = 1;	
	SCL_TRIS = 0;
		
	
}

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

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

tyilgin

Kodunuzu paylaştığınız için teşekkürler.

yakında DS18B20 ile haberleşme konusunda çalışmalara başlayacağım. Bu konuda elinizde birşeyler varmı ?

arslan74

Alıntı yapılan: "tyilgin"Kodunuzu paylaştığınız için teşekkürler.

yakında DS18B20 ile haberleşme konusunda çalışmalara başlayacağım. Bu konuda elinizde birşeyler varmı ?

Malesef benim DS18B20 serisi ile hiç çalışmam olmadı o yüzden, size yardımcı olamayacağım.

Ancak sizin çalışmalarınız sonucunda yazacağınız kodu buraya yayınlarsanız, Hi-Tech'de bu ürünü kullanmak isteyen arkadaşlara katkıda bulunmuş olursunuz.

Kodlarınızı bekliyoruz.

Selamlar