EEPROM with 8051(Problem with READ)

Status
Not open for further replies.

arunbharathi.arasu

Full Member level 2
Joined
Feb 28, 2013
Messages
134
Helped
7
Reputation
14
Reaction score
6
Trophy points
1,298
Location
Chennai, Tamil Nadu, India
Visit site
Activity points
2,151
Hi friends,
I am using AT89S52 Controller for interfacing EEPROM(AT24C256).
I am able to write both address and data to memory without any problem,I found this by tracing the ack bit from EEPROM.
But i cant able to read data from EEPROM. i Don't know how to solve this problem.
Can you help me.....
 

controller you mentioned dont have built in i2c protocol.
then do you have written randomely then post your code and circuit for that
 

AT89s52 don't have inbuilt I2c.
Code:
#include"Header.h"
#include"serial.h"
void I2c_delay(unsigned int ms)
{
        unsigned int i;
        for(i=0;i<ms;i++);
}
void I2c_start()
{
        SDA = 1;
        I2c_delay(1);
        SCL = 1;
        I2c_delay(1);
        SDA = 0;
        I2c_delay(1);
        SCL = 0;
        I2c_delay(1);
}
void I2c_stop()
{
        SCL = 0;
        I2c_delay(1);
        SDA = 0;
        I2c_delay(1);
        SCL = 1;
        I2c_delay(1);
        SDA = 1;
        I2c_delay(1);
}

bit I2c_write(unsigned char dat)
{
        unsigned int i;
        SCL = 0;
        for(i=8;i>0;i--)
        {
                if(dat & 0x80)
                {
                        SDA = 1;
                }
                else
                {
                        SDA = 0;
                }
                SCL = 1;
                dat<<=1;
                SCL = 0;
        }
        SDA = 1;
        SCL = 1;
        I2c_delay(1);
        if (SDA)
        {
                sendchar('N');
                return 0;
        }
        else
        {
                sendchar('A');
                return 1;
        }

}

char I2c_read(char ack)
{
        unsigned char dat=0;
        unsigned int i;
        SCL = 0;
        I2c_delay(1);
        SDA = 1;
        for(i=0;i<8;i++)
        {
                dat<<=1;
                do
                {
                        SCL = 1;
                }while(SCL==0);
                I2c_delay(200);
                if(SDA)
                {
                        dat|=1;
                }
                SCL = 0;
        }
        if(ack)
        {
                SDA = 0;
        }
        else
        {
                SDA = 1;
        }
        SCL = 1;
        I2c_delay(1);
        SCL = 0;
        SDA = 1;
        return dat;
}

main()
{
        unsigned char ser_dat=0;
        IE=0x90;
        TMOD=0x20;
        TH1=0xFD;
        SCON=0x50;
        TR1=1;
        TI=0;
        while(1)
        {
                sendchar('H');
                sendchar('A');
                sendchar('I');
                sendchar(ser_dat);

        SDA = 1;
        SCL = 1;
        I2c_start();
        I2c_write(0xA0);
        I2c_write(0x00);
        I2c_write(0x90);
        I2c_stop();
        I2c_delay(200);
        I2c_start();
        I2c_write(0xA0);
        I2c_write(0x00);
        I2c_start();
        I2c_write(0xA1);
        ser_dat= I2c_read(0);
        sendchar(ser_dat);
        I2c_stop();
        I2c_delay(1);
        }
}
 

hi i have correct your code
Code:
#include"Header.h"
#include"serial.h"

void I2c_delay(unsigned int ms)
{
        unsigned int i;
        for(i=0;i<ms;i++);
}

void I2c_start()
{
        SDA = 1;
        I2c_delay(1);
        SCL = 1;
        I2c_delay(1);
        SDA = 0;
        I2c_delay(1);
        SCL = 0;
        I2c_delay(1);
}

void I2c_stop()
{
        SCL = 0;
        I2c_delay(1);
        SDA = 0;
        I2c_delay(1);
        SCL = 1;
        I2c_delay(1);
        SDA = 1;
        I2c_delay(1);
}

bit I2c_write(unsigned char dat)
{
        unsigned int i;
        SCL = 0;
        for(i=8;i>0;i--)
        {
                if(dat & 0x80)
                {
                        SDA = 1;
                }
                else
                {
                        SDA = 0;
                }
                SCL = 1;
                dat<<=1;
                SCL = 0;
        }
        SDA = 1;
        SCL = 1;
        I2c_delay(1);
        if (SDA)
        {
                sendchar('N');
                return 0;
        }
        else
        {
                sendchar('A');
                return 1;
        }

}

char I2c_read(char ack)
{
        unsigned char dat=0;
        unsigned int i;
        SCL = 0;
        I2c_delay(1);
        SDA = 1;
        for(i=0;i<8;i++)
        {
                dat<<=1;
                do
                {
                        SCL = 1;
                }while(SCL==0);
                I2c_delay(200);
                if(SDA)
                {
                        dat|=1;
                }
                SCL = 0;
        }
        if(ack)
        {
                SDA = 0;
        }
        else
        {
                SDA = 1;
        }
        SCL = 1;
        SDA = 1;				// nack should be High
        I2c_delay(1);
        SCL = 0;
        return dat;
}

main()
{
        unsigned char ser_dat=0;
        IE=0x90;
        TMOD=0x20;
        TH1=0xFD;
        SCON=0x50;
        TR1=1;
        TI=0;
        while(1)
        {
                sendchar('H');
                sendchar('A');
                sendchar('I');
                sendchar(ser_dat);

        SDA = 1;
        SCL = 1;
        I2c_start();
        I2c_write(0xA0);
        I2c_write(0x00);
        I2c_write(0x90);
        I2c_stop();
        I2c_delay(200);
        I2c_start();
        I2c_write(0xA0);
        I2c_write(0x00);
        I2c_start();
        I2c_write(0xA1);
        ser_dat= I2c_read(0);
        sendchar(ser_dat);
        I2c_stop();
        I2c_delay(1);
        }
}
 

yes but at time of reading slave you have to provide Not acknowledge to master.
and how much machine cycle required for delay function.
use
Code:
_nop_();
instruction instead of delay and u will get this in intrinsic.h file
for low clock use 5 machine cycle and
for high clock use 5 machine cycle.

Regards
 

Try this code i am using it and work very well
Code:
#include "intrins.h"
/**********************************************************************************/
void start_i2c()
{
	scl=sda=1;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();

	sda=0;
	_nop_();
	_nop_();
	_nop_();
	_nop_();

	scl=0;

}

void stop_i2c()
{	
	scl=0;
	sda=0;
	_nop_();
	_nop_();
	scl=1;
	_nop_();

  
	sda=1;  
}

void data_out(unsigned char sh_val1)
{
	unsigned int temp;
	scl=0;
	temp=0x80;
	k1=0x00;	
	for(i=0;i<=7;i++)
	{	
		k1=temp & sh_val1;
		

		if(k1==0x80)
			{	
			 sda=1;
			}
		else 
			sda=0;
		sh_val1=sh_val1<<1;
	
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();

		scl=1;
		_nop_();
		_nop_();
		_nop_();
		_nop_();

		scl=0;
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();
	}

	sda=scl=1;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	

	scl=0;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
}


unsigned char data_in()
{
	unsigned int temp,k2;
	sda=1;
	scl=0;
	_nop_();
	_nop_();
	_nop_();
	_nop_();

	temp=0x80;
	k2=0x00;

	for(i=0;i<=7;i++)
 	{
	   
	scl=1;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
			if(sda==1)
			{
				k2=k2 | temp;
			}
		
	scl=0;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	temp=temp>>1;									    

	}
	return(k2);
}


void ack()
{	
	sda=0;
	scl=1;


	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();

	scl=0;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	
}

void nack()
{
	scl=1;
	sda=1;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	scl=0;
}

thinks to do as
1. assign controller's pin to SDA and SCL
2. data_out for write i2c and data in for read i2c.
3. In data_out function i have included ACK.
 

hey i have used your code but the problem was not solved. if i use this code i am getting negative acknowledgement even for write operation. Can you send me the main function for this file.
 

ok try this code and give me a result
Code:
void DaDelay (void);
void ExDelay(int);

void I2C_start(void)
{
	SDA = 1;        /* Set SDA */
	SCL = 1;		/* Set SCL */
	DaDelay (); 
	SDA = 0;        /* Clear SDA */
	DaDelay (); 
	SCL = 0;        /* Clear SCL */
}

void I2C_stop(void)
{
	SDA = 0;			/* Clear SDA */
	DaDelay();
	SCL = 1;			/* Set SCL */
	DaDelay();
	SDA = 1;			/* Set SDA */
}

void I2C_ack()
{
	SDA = 0;		//* Clear SDA 
	DaDelay();
	DaDelay();
	SCL = 1;		//* Start clock 
	DaDelay();    
	SCL = 0;		//* Clear SCL 
	DaDelay();
	SDA = 1;		//* Set SDA
}

bit I2C_write( unsigned char data)
{
	bit getdata_bit;		
	unsigned char i;
	for(i=0;i<8;i++)				/* For loop 8 time(send data 1 byte) */
	{
		getdata_bit = data & 0x80;		/* Filter MSB bit keep to data_bit */
		SDA = getdata_bit;				/* Send data_bit to SDA */
	    DaDelay();
	    SCL = 1;		/* Start clock */
	    DaDelay();    
	    SCL = 0;		/* Clear SCL */
		data = data<<1;  
	}

	SDA = 1;			/* Set SDA */
	DaDelay();		
	SCL = 1;			/* Set SCL */
	DaDelay();	
	data_bit = SDA;   	/* Check acknowledge */	
	SCL = 0;			/* Clear SCL */
	DaDelay();

	return getdata_bit;	/* If send_bit = 0 i2c is valid */		 	
}

unsigned char I2C_read(void)
{
	bit getrd_bit;	
	unsigned char i, data;

	data = 0x00;	

	for(i=0;i<8;i++)		/* For loop read data 1 byte */
	{
		DaDelay();
		SCL = 1;			/* Set SCL */
		DaDelay(); 
		getrd_bit = SDA;		/* Keep for check acknowledge	*/
		data = data<<1;		
		data = data | getrd_bit;	/* Keep bit data in dat */
		SCL = 0;			/* Clear SCL */
	}

	return data;
}

unsigned char ReadEEPROM(unsigned char addr)
{
	unsigned char data;

	I2C_start();            /* Start i2c bus */
	I2C_write(EEPROMS_ID);   /* Connect to EEPROM */ 
	I2C_write(addr);			
	I2C_start();			/* Start i2c bus */
	I2C_write(EEPROMS_ID+1);/* Connect to EEPROM for Read */
	data = I2C_read();		/* Receive data */ 	       				   	
	I2C_stop();				/* Stop i2c bus */ 
   return data;			
}

void WriteEEPROM(unsigned int addr, unsigned char val)
{
	I2C_start();  
	I2C_write(EEPROMS_ID);   /* Connect to EEPROM */
	I2C_write(addr);	 	
	I2C_write(val);			/* Write sec on RAM specified address */
	ExDelay(325);	
	I2C_stop();           	/* Stop i2c bus */
}

DaDelay()
{
     int i;
	 for(i=0;i<2;i++)
	 {
	 	  _nop_();
		  _nop_();
		  _nop_();
	 }

}
ExDelay(int j)					   
{	
	for (;j>0;j--)				   
	{
	_nop_();					
	_nop_();
	_nop_();
	
	}							  
}
 

will you post your actual requirement if i will try to solve and code i am using is working perfectly.
which eeprom u r using?

- - - Updated - - -

and post circuit diagram too.
 

if u want to solve your problem make changes and packed zip and post here..
 

the code i given this is i2c protocol and next code i posted is for basic read and write eeprom.
u can use it

Code:
unsigned char read_array[5]={0};

void write_eeprom()
{
	start_condition();
	data_out(0xA0);		 //device add
	data_out(addh);		//higher byte
	data_out(addl);	   //lower byte 	
	 
	data_out('H');
	data_out('E');
	data_out('L');
	data_out('L');
	data_out('0');
	stop_condition();
	delay(5);
}


void read_eeprom()
{
	start_condition();
	data_out(0xA0);		//write 
	data_out(addh);		//higher byte
	data_out(addl);		//lower byte
	start_condition();
	data_out(0xA1);		 //read	

	read_array[0] = data_in();
	ack();
	read_array[1] = data_in();
	ack();
	read_array[2] = data_in();
	ack();
	read_array[3] = data_in();
	ack();
	read_array[4] = data_in();	 
	nack();
	stop_condition();
}
 
Last edited:

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…