
// HEADER FILE ...

#include<reg51.h>
#include<stdio.h>
#include<string.h>

#define HIGH 1
#define LOW  0

#define FIRST_LINE	1
#define SECOND_LINE	2

#define LCDPORT P0

#define WRITE_ADD 	0xA0
#define READ_ADD	0xA1

typedef unsigned int 	UINT;
typedef unsigned char 	BYTE;

sbit SCL = P1^6;
sbit SDA = P1^7;

sbit EN = P0^4;					
sbit RS = P0^5;	  

void delay(UINT);



// MAIN FUNCTION FILE ...

void main()
{
	BYTE _buff_[16], dat = 0x00;
	float fl_RETVAL; // variable that will recieve the      
                         // float value after reading the EEPROM
	
	P0 = 0x00; // Make P0 & P1 output ports
	P1 = 0x00;
	
	LCD_INIT();		

	delay(1000);

	MAIN_WRITE_FLOAT(0x02, 0x02, 90.87); // Function for 
        // writing float values at the particular address
	delay(1000);
	fl_RETVAL = MAIN_READ_FLOAT(0x02, 0x02);
         // Function for reading float values ... 																	 
	LCD_ADD(FIRST_LINE, 1); // LCD address selection fn
	sprintf(_buff_, "float = %.2f", fl_RETVAL);
        // store the received value of type float and store it
        // in the array _buff_.
	send_string(_buff_);		

	while(1)
	   ;
}




// =============================================================
// EEPROM FILE ... 

#include<header_file.h>

void MAIN_WRITE_FLOAT(BYTE FIRST_ADD, BYTE SECOND_ADD, float fl_BUFF)
{
	BYTE a, _buff_[16], *ptr = &fl_BUFF;
	
	START(); // start function for I2C protocol
	WRITE_EEPROM(WRITE_ADD);  // 0xA0 sending ... 
	WRITE_EEPROM(FIRST_ADD);  // first add of memory
	WRITE_EEPROM(SECOND_ADD); // second add of memory 

	for(a = 0; a < 4; a++) WRITE_EEPROM(*(ptr++));
              // rountine for sending the float values which
              // is divided in four parts by pointer ptr.
		
	STOP();	  // stop function for I2C protocol
}

float MAIN_READ_FLOAT(BYTE FIRST_ADD, BYTE SECOND_ADD)
{
	BYTE *ptr, a;
	float fl_VAL;

	ptr = &fl_VAL; // fl_VAL variable that will recieve the
                       // float value in four parts and merged
                       // by pointer ptr, ptr has the add of 
                       // this variable.

	START(); // start function for I2C protocol
	WRITE_EEPROM(WRITE_ADD); // 0xA0 sending fn
	WRITE_EEPROM(FIRST_ADD); // first add to be read
	WRITE_EEPROM(SECOND_ADD); // second add to read ... 

	START(); // Agian giving the start condition

	WRITE_EEPROM(READ_ADD); // 0xA1 add send fn

	for(a = 0; a < 4; a++) {
		*(ptr++) = READ_EEPROM(); 
                         // read the data from EEPROM
		if(a != 3) { 
			SDA	= LOW; // send low singnal as an
                                       // ack by the UC to 
                                       // EEPROM.
			I2C_CLOCK_CYCLE(); 
		          // Clock Cycle given after the ack by 
                          // UC ... to EEPROM
		}
	}

	STOP(); // finally STOP condition ...

	return(fl_VAL);
}


void START()
{	
	SCL = HIGH;
	delay(5);
	SDA = HIGH;
	delay(5);
	SDA = LOW;
	delay(5);
	SCL = LOW;
	delay(5);
}

void STOP()
{	
	SCL = HIGH;
	delay(5);
	SDA = LOW;
	delay(5);
	SDA = HIGH;
	delay(5);
	SCL = LOW;						    
	delay(5);
}

// SINGLE BYTE WRITE FUNCTION

void MAIN_WRITE(BYTE FIRST_ADD, BYTE SECOND_ADD, BYTE b_DATA)
{
	START();
	WRITE_EEPROM(WRITE_ADD);
	WRITE_EEPROM(FIRST_ADD);
	WRITE_EEPROM(SECOND_ADD);
	WRITE_EEPROM(b_DATA);
	STOP();
}

// SINGLE BYTE READ FUNCTION

BYTE MAIN_READ(BYTE FIRST_ADD, BYTE SECOND_ADD)
{
	BYTE value = 0x00;

	START();
	WRITE_EEPROM(WRITE_ADD);
	WRITE_EEPROM(FIRST_ADD);
	WRITE_EEPROM(SECOND_ADD);
	START();
	WRITE_EEPROM(READ_ADD);
	value = READ_EEPROM();
	STOP();

	return(value);
}

void I2C_CLOCK_CYCLE()
{
	SCL = HIGH;
	delay(5);
	SCL = LOW;
	delay(5);		
}						

void ACKNOWLEDGE()
{
	BYTE _buff[16];

	SDA = HIGH;

	while(SDA)
		;

	I2C_CLOCK_CYCLE();

	SDA = LOW;	
}

void WRITE_EEPROM(BYTE value)
{
	BYTE count = 8, compare = 0x80;

	while(count--){
		SDA = ((value & compare) ? 1 : 0);
		I2C_CLOCK_CYCLE();
		compare >>= 1;
	}	
									  
	ACKNOWLEDGE();
}

BYTE READ_EEPROM()
{											 
	BYTE count = 8, value = 0x00;
	
	SDA = HIGH;

	while(count--){
		value |= ((SDA) ? 1 : 0);
		I2C_CLOCK_CYCLE();
		if(count) value <<= 1;
	}	
	return(value);
}


