This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problem when implement i2c interface between AT24C04 EEPROM with 8051

Hello!
I have write a program to write and read to/from AT24c04 serial ROM (89C52 interface with AT24C04). I am using Keil C to program.

But i can read any data which i have write to AT24c04.
I don't know exacterly why.

My purpose is very simple. I listent from USART and get data from PC key board. If the character which i get from pc is 'w' or 'W' then i do get data from PC and write to AT24c04 until i get the 0x0D. Now if i get the 'r' or 'R' character from PC i read data which i have just write to AT24c04 and send back to PC.
But i can't read any.

Here is my code

#include <REG52.h>

unsigned char data DEVICEADD;

sbit SDA = P1^0;
sbit SCL = P1^1;

int data c;
char data wrom;
char data rrom;


void outchar(char data chr)
{
while(!TI)
{
}
TI = 0;
SBUF = chr;
}

void outstr(char* str)
{
while(*str != 0)
{
outchar(*str++);
}
}
char i2c_start(void)
{
/*
if(!SDA || !SCL)
return 0; // i2c_start error: bus not free
*/
// Both bus lines are high,
SDA = 0; // so set data line low to generate a start condition.
SCL = 0;
/*
SDA = 1;
SCL = 1;
SDA = 0;
SCL = 0;
*/
return 1;
}

void i2c_stop(void)
{
/*
SDA = 0;
SCL = 1;
SDA = 1;
*/
unsigned char input_var;
SCL = 1;
SDA = 0;
SCL = 1;
SDA = 1;
input_var = SDA;
}

// return ack value: 0 for fale; 1 for success
char i2c_write(char data byte)
{
int data i;
for(i = 0; i < 8 ; i++)
{
SDA = ((byte & 0x80) ? 1 : 0);
SCL = 1; // Ensure that the data is stable during the high period.
byte <<= 1;
SCL = 0;
}
// Get ack
SDA = 1;
SCL = 1;
i = SDA;
//i = 500;
SCL = 0;
/*
while(i-- && SDA)
{
}
*/
return !i; // Get data at end of cycle.
}

char i2c_writebyte(int data address, char data byte)
{
if(!i2c_start())
{
outstr("i2c_start error: bus not free.\n");
return 0;
}
if(!i2c_write(DEVICEADD))
{
i2c_stop();
i2c_start();
if(!i2c_write(DEVICEADD)) // Interface failed to acknowledge device address
{
i2c_stop();
outstr("Interface failed to acknowledge device address.\n");
return 0;
}
}

if(!i2c_write(address >>8)) // Interface failed to acknowledge byteH address
{
i2c_stop();
outstr("Interface failed to acknowledge byteH address.\n");
return 0;
}
if(!i2c_write(address)) // Interface failed to acknowledge byteL address
{
i2c_stop();
outstr("Interface failed to acknowledge byteL address.\n");
return 0;
}
if(!i2c_write(byte)) // Interface failed to acknowledge data
{
i2c_stop();
outstr("Interface failed to acknowledge data.\n");
return 0;
}
i2c_stop();
return 1; // success
}

char i2c_read(char data ACK)
{
char index, byte;
index = SDA; // Put data pin into read mode
byte = 0x00;
for(index = 0; index < 8; index++) // Send 8 bits to the I2C Bus
{
byte <<= 1;
SCL = 1; // Clock the data into the I2C Bus
byte |= SDA; // Input the data from the I2C Bus
SCL = 0;
}

// Write ack bit
SDA = ACK;
SCL = 1; // Ensure that the data is stable during the high period.
SCL = 0;
return byte;
}

char i2c_readbyte(int data address)
{
char data byte;
if(!i2c_start())
{
outstr("i2c_start error: bus not free.\n");
return 0;
}
if(!i2c_write(DEVICEADD))
{
i2c_stop();
i2c_start();
if(!i2c_write(DEVICEADD)) // Interface failed to acknowledge device address
{
i2c_stop();
outstr("Interface failed to acknowledge device address.\n");
return 0;
}
}

// Transmit address to read from.
if(!i2c_write(address >> 8)) // Interface failed to acknowledge byteH address
{
i2c_stop();
outstr("Interface failed to acknowledge byteH address. \n");
return 0;
}
if(!i2c_write(address)) // Interface failed to acknowledge byteL address
{
i2c_stop();
outstr("Interface failed to acknowledge byteL address. \n");
return 0;
}

// Now terminate write operation and do a read.
if(!i2c_start())
{
outstr("i2c_start error: bus not free.\n");
return 0;
}
// Transmit address to read from.
if(!i2c_write(DEVICEADD | 1)) // Slave failed to ack read access
{
i2c_stop();
outstr("Slave failed to ack read access.\n");
return 0;
}
// Read from address and ack = 1.
byte = i2c_read(1);
i2c_stop();
return byte;
}

char get_char()
{
while(!RI)
{
}
RI = 0;
return SBUF;
}


void WriteData()
{
char data ch;
ch = get_char();
while(ch != 0x0D)
{
i2c_writebyte(c++,ch);
outchar(ch);
ch = get_char();
}
wrom = 0;
ES = 1;
}

void ReadData()
{
char data index;
char data input;
for(index = 0; index < c; index++)
{
input = i2c_readbyte(index);
if(input != 0)
outchar(input);
}
c = 0;
rrom = 0;
ES = 1;
}

void main(void)
{
// Init serial
SCON = 0x52;
// Set timer1 mode and reload value
TMOD &= ~0xF0; // clear timer 1 mode bits
TMOD |= 0x20; // put timer 1 into MODE 2 8 bit auto reload
TH1 = 0xFD;
TR1 = 1; // start timer 1
TI = 0;
ES = 1; // Enable Serial interrupt
EA = 1; // Enable all interrupts

c = 0;
rrom = 0;
wrom = 0;
DEVICEADD = 0xA0; // 10100000B
while(1)
{
if(wrom == 1)
{
outchar('W');
WriteData();
}
if(rrom == 1)
{
outchar('R');
ReadData();
}
/*
count = get_char();
outchar(count);
*/
}
}

void serial (void) interrupt 4 using 3
{
char data inp;
if(RI) // Received data interrupt
{
RI = 0;
inp = (char)SBUF;
if((inp == 'w') || (inp == 'W'))
{
ES = 0;
rrom = 0;
c = 0;
TI = 1;
wrom = 1;
}
else if((inp == 'r') || (inp == 'R'))
{
ES = 0;
wrom = 0;
TI = 1;
rrom = 1;
}
}
else if(TI) // Transmitted data interrupt
{
TI = 0;
}
}

Could you help me ?

Parents
  • #include <REG52.h>
    #include <intrins.h>

    unsigned char data DEVICEADD;

    sbit SDA = P1^0;
    sbit SCL = P1^1;

    // Delay for one miliseconnd

    void time1ms(void)
    {
    	unsigned char c;
    
    	for(c = 0;c < 200;c++)
    	{
    		_nop_();
    	}
    }
    

    // Delay function, delay time in millisecond
    void delay(int data i)
    {
    	data int time;
    
    	for(time = 0;time < i;time++)
    	{
    		time1ms();
    	}
    }
    

    // Send a character to PC
    void outchar(char data chr)
    {
    	while(!TI)
    	{
    	}
    	TI = 0;
    	SBUF = chr;
    }
    


    // Send a string to PC
    void outstr(char* str)
    {
    	while(*str != 0)
    	{
    		outchar(*str++);
    	}
    }
    
    char i2c_start(void)
    {
    	SDA = 1;
    	SCL = 1;
    	SDA = 0;
    	SCL = 0;
    	return 1;
    }
    
    void i2c_stop(void)
    {
    	unsigned char input_var;
    	SCL = 1;
    	SDA = 0;
    	SCL = 1;
    	SDA = 1;
    	input_var = SDA;
    }
    

    // return ack value: 0 for fale; 1 for success
    char i2c_write(char data byte)
    {
    	int data i;
    	for(i = 0; i < 8 ; i++)
     	{
    		SDA = ((byte & 0x80) ? 1 : 0);
    		SCL = 1;               // Ensure that the data is stable during the high period.
    		byte  <<= 1;
      		SCL = 0;
    	}
    	// Get ack
    	SDA = 1;
    	SCL = 1;
    	i = SDA;
    	SCL = 0;
    	return !i;  // Get data at end of cycle.
    }
    

    // Write a byte to @4C04 at address
    char i2c_writebyte(int data address, char data byte)
    {
    	if(!i2c_start())
    	{
    		outstr("i2c_start error: bus not free.\n");
    			return 0;
    	}
    	if(!i2c_write(DEVICEADD))
    	{
    		i2c_stop();
    		i2c_start();
    		if(!i2c_write(DEVICEADD))	// Interface failed to acknowledge device address
    		{
    			i2c_stop();
    			outstr("Interface failed to acknowledge device address.\n");
    			return 0;
    		}
    	}
    
    	if(!i2c_write(address >>8)) // Interface failed to acknowledge byteH address
    	{
    		i2c_stop();
    		outstr("Interface failed to acknowledge byteH address.\n");
    		return 0;
    	}
    	if(!i2c_write(address))	// Interface failed to acknowledge byteL address
    	{
    		i2c_stop();
    		outstr("Interface failed to acknowledge byteL address.\n");
    		return 0;
    	}
      	if(!i2c_write(byte))	// Interface failed to acknowledge data
    	{
    		i2c_stop();
    		outstr("Interface failed to acknowledge data.\n");
    		return 0;
    	}
    	i2c_stop();
    	return 1;	// success
    }
    
    char i2c_read(char data ACK)
    {
    	char index, byte;
       	index = SDA;							// Put data pin into read mode
    	byte = 0x00;
    	for(index = 0; index < 8; index++)  	// Send 8 bits to the I2C Bus
    	{
    		byte <<= 1;
    		SCL = 1;           				// Clock the data into the I2C Bus
          	byte |= SDA; 		   		// Input the data from the I2C Bus
    		SCL = 0;
    	}
    
    	// Write ack bit
    	SDA = ACK;
      	SCL = 1;               // Ensure that the data is stable during the high period.
    	SCL = 0;
    	return byte;
    }
    
    // Red a byte from 24c04 at address
    char i2c_readbyte(int data address)
    {
    	char data byte;
    	if(!i2c_start())
    	{
    		outstr("i2c_start error: bus not free.\n");
    			return 0;
    	}
    	if(!i2c_write(DEVICEADD))
    	{
    		i2c_stop();
    		i2c_start();
    		if(!i2c_write(DEVICEADD))	// Interface failed to acknowledge device address
    		{
    			i2c_stop();
    			outstr("Interface failed to acknowledge device address.\n");
    			return 0;
    		}
    	}
    
    	// Transmit address to read from.
      	if(!i2c_write(address >> 8)) // Interface failed to acknowledge byteH address
    	{
    		i2c_stop();
    		outstr("Interface failed to acknowledge byteH address. \n");
    		return 0;
    	}
    	if(!i2c_write(address))	// Interface failed to acknowledge byteL address
    	{
    		i2c_stop();
    		outstr("Interface failed to acknowledge byteL address. \n");
    		return 0;
    	}
    
      	// Now terminate write operation and do a read.
    	if(!i2c_start())
    	{
    		outstr("i2c_start error: bus not free.\n");
    			return 0;
    	}
    	// Transmit address to read from.
    	if(!i2c_write(DEVICEADD | 1))	// Slave failed to ack read access
    	{
    		i2c_stop();
    		outstr("Slave failed to ack read access.\n");
    		return 0;
    	}
        // Read from address and ack = 1.
      	byte = i2c_read(1);
      	i2c_stop();
    	return byte;
    }
    
    // Write a string to 24c04
    void WriteToROM(char* str)
    {
    	char data index = 0;
    	while(*str != 0)
    	{
    		i2c_writebyte(index++,*str++);
    	}
    }
    

    // My purpose is very simple, i send Hello string to ROM and delay for 200 milisecond and read back from rom and send to PC and loop forever

    void main(void)
    {
    	char data index;
    	char data byte;
    	// Init serial 9600 baud, 8 bit, enable receive...
    	SCON  = 0x52;
    	// Set timer1 mode and reload value
    	TMOD &= ~0xF0; // clear timer 1 mode bits
    	TMOD |= 0x20;  // put timer 1 into MODE 2 8 bit auto reload
    	TH1 = 0xFD;
    	TR1 = 1; // start timer 1
    	DEVICEADD = 0xA0;	// 10100000B
    	while(1)
    	{
    			// Write Hello to ROM
    		WriteToROM("Hello");
    		delay(200); // delay for 200 milisecond
    		// Read data back from rom
    		for(index = 0; index < 4; index++)
    		{
    			byte = i2c_readbyte(index);
    	  		outchar(byte);
    		}
    		delay(200); // delay for 200 milisecond
    	}
    }
    
    

Reply
  • #include <REG52.h>
    #include <intrins.h>

    unsigned char data DEVICEADD;

    sbit SDA = P1^0;
    sbit SCL = P1^1;

    // Delay for one miliseconnd

    void time1ms(void)
    {
    	unsigned char c;
    
    	for(c = 0;c < 200;c++)
    	{
    		_nop_();
    	}
    }
    

    // Delay function, delay time in millisecond
    void delay(int data i)
    {
    	data int time;
    
    	for(time = 0;time < i;time++)
    	{
    		time1ms();
    	}
    }
    

    // Send a character to PC
    void outchar(char data chr)
    {
    	while(!TI)
    	{
    	}
    	TI = 0;
    	SBUF = chr;
    }
    


    // Send a string to PC
    void outstr(char* str)
    {
    	while(*str != 0)
    	{
    		outchar(*str++);
    	}
    }
    
    char i2c_start(void)
    {
    	SDA = 1;
    	SCL = 1;
    	SDA = 0;
    	SCL = 0;
    	return 1;
    }
    
    void i2c_stop(void)
    {
    	unsigned char input_var;
    	SCL = 1;
    	SDA = 0;
    	SCL = 1;
    	SDA = 1;
    	input_var = SDA;
    }
    

    // return ack value: 0 for fale; 1 for success
    char i2c_write(char data byte)
    {
    	int data i;
    	for(i = 0; i < 8 ; i++)
     	{
    		SDA = ((byte & 0x80) ? 1 : 0);
    		SCL = 1;               // Ensure that the data is stable during the high period.
    		byte  <<= 1;
      		SCL = 0;
    	}
    	// Get ack
    	SDA = 1;
    	SCL = 1;
    	i = SDA;
    	SCL = 0;
    	return !i;  // Get data at end of cycle.
    }
    

    // Write a byte to @4C04 at address
    char i2c_writebyte(int data address, char data byte)
    {
    	if(!i2c_start())
    	{
    		outstr("i2c_start error: bus not free.\n");
    			return 0;
    	}
    	if(!i2c_write(DEVICEADD))
    	{
    		i2c_stop();
    		i2c_start();
    		if(!i2c_write(DEVICEADD))	// Interface failed to acknowledge device address
    		{
    			i2c_stop();
    			outstr("Interface failed to acknowledge device address.\n");
    			return 0;
    		}
    	}
    
    	if(!i2c_write(address >>8)) // Interface failed to acknowledge byteH address
    	{
    		i2c_stop();
    		outstr("Interface failed to acknowledge byteH address.\n");
    		return 0;
    	}
    	if(!i2c_write(address))	// Interface failed to acknowledge byteL address
    	{
    		i2c_stop();
    		outstr("Interface failed to acknowledge byteL address.\n");
    		return 0;
    	}
      	if(!i2c_write(byte))	// Interface failed to acknowledge data
    	{
    		i2c_stop();
    		outstr("Interface failed to acknowledge data.\n");
    		return 0;
    	}
    	i2c_stop();
    	return 1;	// success
    }
    
    char i2c_read(char data ACK)
    {
    	char index, byte;
       	index = SDA;							// Put data pin into read mode
    	byte = 0x00;
    	for(index = 0; index < 8; index++)  	// Send 8 bits to the I2C Bus
    	{
    		byte <<= 1;
    		SCL = 1;           				// Clock the data into the I2C Bus
          	byte |= SDA; 		   		// Input the data from the I2C Bus
    		SCL = 0;
    	}
    
    	// Write ack bit
    	SDA = ACK;
      	SCL = 1;               // Ensure that the data is stable during the high period.
    	SCL = 0;
    	return byte;
    }
    
    // Red a byte from 24c04 at address
    char i2c_readbyte(int data address)
    {
    	char data byte;
    	if(!i2c_start())
    	{
    		outstr("i2c_start error: bus not free.\n");
    			return 0;
    	}
    	if(!i2c_write(DEVICEADD))
    	{
    		i2c_stop();
    		i2c_start();
    		if(!i2c_write(DEVICEADD))	// Interface failed to acknowledge device address
    		{
    			i2c_stop();
    			outstr("Interface failed to acknowledge device address.\n");
    			return 0;
    		}
    	}
    
    	// Transmit address to read from.
      	if(!i2c_write(address >> 8)) // Interface failed to acknowledge byteH address
    	{
    		i2c_stop();
    		outstr("Interface failed to acknowledge byteH address. \n");
    		return 0;
    	}
    	if(!i2c_write(address))	// Interface failed to acknowledge byteL address
    	{
    		i2c_stop();
    		outstr("Interface failed to acknowledge byteL address. \n");
    		return 0;
    	}
    
      	// Now terminate write operation and do a read.
    	if(!i2c_start())
    	{
    		outstr("i2c_start error: bus not free.\n");
    			return 0;
    	}
    	// Transmit address to read from.
    	if(!i2c_write(DEVICEADD | 1))	// Slave failed to ack read access
    	{
    		i2c_stop();
    		outstr("Slave failed to ack read access.\n");
    		return 0;
    	}
        // Read from address and ack = 1.
      	byte = i2c_read(1);
      	i2c_stop();
    	return byte;
    }
    
    // Write a string to 24c04
    void WriteToROM(char* str)
    {
    	char data index = 0;
    	while(*str != 0)
    	{
    		i2c_writebyte(index++,*str++);
    	}
    }
    

    // My purpose is very simple, i send Hello string to ROM and delay for 200 milisecond and read back from rom and send to PC and loop forever

    void main(void)
    {
    	char data index;
    	char data byte;
    	// Init serial 9600 baud, 8 bit, enable receive...
    	SCON  = 0x52;
    	// Set timer1 mode and reload value
    	TMOD &= ~0xF0; // clear timer 1 mode bits
    	TMOD |= 0x20;  // put timer 1 into MODE 2 8 bit auto reload
    	TH1 = 0xFD;
    	TR1 = 1; // start timer 1
    	DEVICEADD = 0xA0;	// 10100000B
    	while(1)
    	{
    			// Write Hello to ROM
    		WriteToROM("Hello");
    		delay(200); // delay for 200 milisecond
    		// Read data back from rom
    		for(index = 0; index < 4; index++)
    		{
    			byte = i2c_readbyte(index);
    	  		outchar(byte);
    		}
    		delay(200); // delay for 200 milisecond
    	}
    }
    
    

Children
No data