Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
07/22/04 14:28
Read: times


 
#74699 - I2C EEPROM on 668
Dear friends

Sorry I need to post this long code.

I modify the example code from asacedamy to my 668 program and I want to communicate with i2c EEPROM (AT24C16AN)

The problem is the data that I read are not the same as I write before.

Does this due to coding problem or hardware or the i2c EEPROM?

Can anyone please help me on this.

Thanks in advance
Parif



Data I write:

000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F
404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F
808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF
C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF
E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF

000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F
404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F
808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF
C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF
E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF


and here is the data that I get when I read back:

FF00000000800000000000000000000000000000000000171800000000001E00
000000000000000000002A2B002D002F30000000003500000039000000000000
0041004300000047480000004C004E00000000000000560000005A5B005D005F
6000620064650000006900006C0000000071007300007677780000007C007E00
800082008485860000008A8B008D008F9091920094950097989900009C009E00
00A100A30000A6A7A800AAABACADAEAFB000B200B4B5B60000B9BABB00BD00BF
C0C1C2C3C4C500C7C8C900CBCCCDCE0000D100D30000D6D7D8D9DADBDCDDDEDF
E000E2E3E4E5E60000E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F900FBFCFDFEFF

FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF



this is my calling test code for write data :

void i2cwrite(void)
{
int i;
location = 0;
location2 = 0;
for ( i=0 ; i<=255; i++)
   	{
 	   location = location + i;
	   byte = i;
	   eeprom_write_byte(location, byte);
  	   puyit[0] = byte;
	   sendcomm ( puyit , 1);
       } 

location = 0;
location2 = 0;
for ( i=0 ; i<=255; i++)
   	{
         location2 = location2 + i;
	 byte = i;
	 eeprom_write_byte(location2, byte);
 	 puyit[0] = byte;
	sendcomm ( puyit , 1);
	} 			
}

this is my calling test code for read data :

void i2cread(void)
{
int i;
location = 0;
location2 = 0;
for ( i=0 ; i<=255; i++)
   	{
         location = location + i;
 	 byte = eeprom_read_byte(location);
	 puyit[0] = byte;
	 sendcomm ( puyit , 1);
	} 

location = 0;
location2 = 0;
for ( i=0 ; i<=255; i++)
   	{
         location2 = location2 + i;
  	 byte = eeprom_read_byte(location);
	 puyit[0] = byte;
	 sendcomm ( puyit , 1);
	}
}





and here is my i2c code:

<pre>

#define I2C_ERROR 1 // i2c_state holds I2C_ERROR or I2C_OK after reading
#define I2C_OK 2 // or writing a byte to indicate the result of the operation
#define I2C_BUSY 0 // i2c_state holds I2C_BUSY during a read or write operation

extern void init_i2c(void);
extern void eeprom_write_byte(unsigned int address, unsigned char byte);
extern unsigned char eeprom_read_byte(unsigned int address);
extern unsigned char i2c_status;

///////////////////////////////////////////////

#define EEPROM_ADDRESS 0xA0 // I2C address of EEPROM
#define TIMEOUT 0xAA0F // timer reload value gives 22ms timeout period
// for waiting on SLA + W ack

void init_i2c(void);
void eeprom_write_byte(unsigned int address, unsigned char byte);
unsigned char eeprom_read_byte(unsigned int address);
void i2c_isr(void);
void start_timer(void);
void stop_timer(void);

enum i2c_states { LOWER_ADDRESS, DATA_BYTE, FINISHED, DUMMY_WRITE }; // states during an I2C operation
enum i2c_operations { READ, WRITE }; // possible I2C operations are reading or writing

unsigned char i2c_storage_address; // holds the address to read from or write to
unsigned char i2c_byte; // holds the value read or the value to write
unsigned char i2c_state; // holds the status - LOWER_ADDRESS, DATA BYTE, etc.
unsigned char i2c_status; // holds the state - I2C_ERROR, I2C_OK or I2C_BUSY
unsigned char i2c_operation; // holds the operation - READ or WRITE


unsigned char byte = 0x63 , num, puyit[2]; // value to store in EEPROM

unsigned char location = 0x00;
unsigned char location2 = 0x00; // location to store value

//unsigned int location = 0x102;

// *******************************************************************
// function init_i2c
void init_i2c(void)
{

S1CON = 0x43; //set to become master and speed at Fosc/160
PS1 = 1; //set i2c interupt priority bit
SCL = 1; //set the pin high
SDA = 1;
S1ADR = 0x00; //set adr. register
ES1 = 1; //enable i2c interupt
}

// function eeprom_write_byte
void eeprom_write_byte(unsigned int address, unsigned char byte)
{
i2c_storage_address = address; // copy the address
i2c_byte = byte; // copy the byte to store
i2c_status = I2C_BUSY; // I2C is now busy
i2c_operation = WRITE; // a write operation is being performed
S1CON = 0x40; // enable I2C - no acknowledgements will be generated
STA = 1; // request to transmit a start condition - places I2C peripheral in
// master transmitter mode
while(i2c_status == I2C_BUSY); // wait until I2C is no longer busy
}

// function eeprom_read_byte
unsigned char eeprom_read_byte(unsigned int address)
{
i2c_storage_address = address; // copy the address
i2c_status = I2C_BUSY; // I2C is now busy
i2c_operation = READ; // read operation is being performed
i2c_state = DUMMY_WRITE; // initially a dummy write is to be performed
S1CON = 0x40; // enable I2C - no acknowledgements will be generated
STA = 1; // request to transmit a start condition - this will place the
// I2C peripheral in master transmitter mode
while(i2c_status == I2C_BUSY); // wait until I2C is no longer busy
if (i2c_status == I2C_OK)
return i2c_byte; // if operation was successful then return read value
else
return 0xFF; // return a constant value if there was an error
}

// function start_timer
void start_timer(void)
{
TL0 = TIMEOUT & 0xFF; // load timer reload value
TH0 = (TIMEOUT >> 8) & 0xFF;
TR0 = 1; // start timer 0
}


// function stop_timer
void stop_timer(void)
{
TR0 = 0; // stop timer 0
TF0 = 0; // clear timer 0 overflow flag
}

// function i2c_isr
void i2c_isr(void) interrupt 5 //using 1
{

switch(S1STA)
{

// START CONDITION TRANSMITTED
case 0x08:
STA = 0; // clear start condition flag so another start condition is not requested
S1DAT = EEPROM_ADDRESS & 0xFE; // transmit EEPROM address + write command (SLA + W)
start_timer(); // start timer 0 to start measuring the timeout period
break;
// REPEATED START CONDITION TRANSMITTED
case 0x10:
STA = 0; // clear start condition flag so another start condition is not requested
if (i2c_operation == READ && i2c_state != DUMMY_WRITE) // if performing a read operation and dummy write is completed then...
{
S1DAT = EEPROM_ADDRESS | 0x01; // transmit EEPROM address + read command (SLA + R)
}
else
{
S1DAT = EEPROM_ADDRESS & 0xFE; // transmit EEPROM address + write command (SLA + W)
// this situation will arise if no resonse was received from the EEPROM
// and another attempt is being made
}
break;
// SLAVE ADDRESS + WRITE TRANSMITTED - ACK RECEIVED
case 0x18:
stop_timer(); // stop timer 0 - a response was received within the timeout period

S1DAT = location;
// S1DAT = (i2c_storage_address >> 8) & 0x0F; // transmit upper 4 bits of address - need to transmit upper 3 bit
i2c_state = LOWER_ADDRESS; // next byte to be transmitted is lower part of address


break;
// SLAVE ADDRESS + WRITE TRANSMITTED - NO ACK RECEIVED
case 0x20:
if (TF0) // if timer 0 overflowed then timeout period reached. no response.
{
STO = 1; // request to transmit a stop condition
stop_timer(); // stop timer 0
i2c_status = I2C_ERROR; // status of operation is ERROR
}
else
{
STA = 1; // request to transmit a repeated start - try again to communicate
}
break;
// DATA BYTE OR UPPER ADDRESS OR LOWER ADDRESS TRANSMITTED - ACK RECEIVED
case 0x28:
switch(i2c_state)
{
case LOWER_ADDRESS: // next byte to transmit is lower part of address
// S1DAT = i2c_storage_address & 0xFF; // transmit lower 8 bits of address
S1DAT = location2;

i2c_state = DATA_BYTE; // next time around transmit the data byte
break;
case DATA_BYTE: // next byte to transmit is the data byte
if (i2c_operation == READ) // if performing a read then the dummy write cycle
// ends here. no data byte is transmitted
{
STA = 1; // request to transmit repeated start
}
else
{
S1DAT = i2c_byte; // transmit the data byte
i2c_state = FINISHED; // next time around the write cycle is finished
}
break;
// finished writing byte
case FINISHED: // data byte was successfully transmitted
STO = 1; // request to transmit a stop condition
i2c_status = I2C_OK; // status of operation is OK

break;
}
break;
// DATA BYTE OR UPPER ADDRESS OR LOWER ADDRESS TRANSMITTED - NO ACK RECEIVED
case 0x30:
STO = 1; // no response. request to transmit a stop condition
i2c_status = I2C_ERROR; // status of operation is ERROR
break;
// SLAVE ADDRESS + READ TRANSMITTED - ACK RECEIVED
case 0x40:
break; // no action is performed. next time an interrupt is
// generated the data byte will have been received from
// the EEPROM
// SLAVE ADDRESS + READ TRANSMITTED - NO ACK RECEIVED
case 0x48:
STO = 1; // request to transmit stop condition
i2c_status = I2C_ERROR; // status of operation is ERROR
break;
// DATA BYTE RECEIVED - NO ACK TRANSMITTED
case 0x58:
i2c_byte = S1DAT; // data byte has been received and no acknowledge was
// transmitted as per the datasheet. read the data byte
i2c_status = I2C_OK; // status of operation is OK
STO = 1; // request to transmit stop condition


break;
// UNKNOWN STATE
default:
STO = 1; // request to transmit stop condition
i2c_status = I2C_ERROR; // status of operation is ERROR
// ES1 = 0; // disable the I2C interrupt
break;
}
SI = 0;

}



List of 9 messages in thread
TopicAuthorDate
I2C EEPROM on 668            01/01/70 00:00      
   RE: I2C EEPROM on 668            01/01/70 00:00      
      RE: I2C EEPROM on 668            01/01/70 00:00      
         RE: I2C EEPROM on 668            01/01/70 00:00      
            RE: I2C EEPROM on 668            01/01/70 00:00      
   RE: I2C EEPROM on 668            01/01/70 00:00      
   RE: I2C EEPROM on 668            01/01/70 00:00      
      RE: I2C EEPROM on 668            01/01/70 00:00      
         RE: I2C EEPROM on 668 - thanks            01/01/70 00:00      

Back to Subject List