| ??? 02/23/09 07:42 Read: times |
#162682 - AT24C512 Sequential Read failed!! |
Hi all,
I am working with AT24C512 I2C EEPROM interfaced to P89C664HBA controller on SDCC. The following is a program written by me to write and read to/from the EEPROM - byte-wise and page-wise. Well all seems to be working fine except the sequential read operation. Can anyone tell me how can I sort this out? Regards, Sarma #define SCL P1_6
#define SDA P1_7
#define EEPROM_READ_ADDR 0XA1
#define EEPROM_WRITE_ADDR 0XA0
#define HIGH 1
#define LOW 0
#define ACK LOW
#define NACK HIGH
#define SUCCESS HIGH
#define ERROR LOW
#define TEST_NUM 0x81
__sbit __at (0x96) P1_6 ;
__sbit __at (0x97) P1_7 ;
/* I2C functions */
void start()
{
/* I2C START condition */
SCL = SDA = HIGH;
NOP;
SDA = LOW;
NOP;
SCL = LOW;
}
void stop()
{
/* I2C STOP condition */
SDA = LOW;
SCL = HIGH;
NOP;
SDA = HIGH;
NOP;
SCL = LOW;
}
unsigned char clock()
{
/* A subroutine to generate a clock pulse and return the
* status of the data bus during the clock period */
unsigned char status = 0;
SCL = HIGH;
NOP;
while(!SCL); /* eliminate ripples */
status = SDA;
SCL = LOW;
return (status);
}
unsigned char write(unsigned char byte)
{
/* I2C WRITE operation, Write a byte on SDA and return the
* acknowledgement */
unsigned char mask = 0x80;
unsigned char status= ACK;
for ( ; mask > 0 ; ) {
SDA = (byte & mask) ? ( SET ):( CLEAR ) ;
mask >>= 1;
clock();
}
return (clock()); /* return the status of SDA line on
* the 9th pulse */
}
unsigned char read(unsigned char status)
{
/* I2C READ operation, read one byte from the transmitter and
* give ack/nack to it */
unsigned char byte = 0;
unsigned char count, level = 0;
/* if (status == NACK) */
/* print_on_lcd("NACK!!"); */
for ( count = 0; count < 8; count++ ) {
byte <<= 1;
level = clock();
byte |= level;
}
SDA = status; /* status = 1 :- NACK
* status = 0 :- ACK */
clock();
return byte;
}
/* EEPROM functions */
unsigned char byte_write( unsigned int addr, unsigned char val )
{
/* A write operation requires two 8-bit data word addresses
* following the device address word and acknowledgment. Upon
* receipt of this address, the EEPROM will again respond
* with and then clock in the first 8-bit data
* word. Following receipt of the 8-bit data word, the EEPROM
* will output . The addressing device, such as a
* microcontroller, then must terminate the write sequence
* with a stop condition. At this time the EEPROM enters an
* internally-timed write cycle, tWR, to the nonvolatile
* memory. All inputs are disabled during this write cycle
* and the EEPROM will not respond until the write is
* complete */
unsigned char status = ERROR;
start();
if ( write(EEPROM_WRITE_ADDR) == ACK ) {
if ( write( (addr & 0xFF00) >> 8 ) == ACK ) {
if ( write( (addr & 0x00FF) ) == ACK ) {
if ( write(val) == ACK ) {
status = SUCCESS;
}
else
print_on_lcd("write val failed!!");
}
else
print_on_lcd("write low byte failed!!");
}
else
print_on_lcd("write high byte failed!!");
}
else
print_on_lcd("write device id failed!!");
stop();
delay_millisec(10); /* Twr = 10ms max */
return status;
}
unsigned char byte_read( unsigned int addr )
{
/* A random read requires byte write sequence to load in the
* data word address. Once the device address word and data
* word address are clocked in and acknowledged by the EEPROM,
* the microcontroller must generate another start
* condition. The microcontroller now initiates a current
* address read by sending a device address with the
* Read/Write select bit high. The EEPROM acknowledges the
* device address and serially clocks out the data word. The
* microcontroller does not respond with but does generate a
* following stop condition */
unsigned char val = ERROR;
start();
if ( write(EEPROM_WRITE_ADDR) == ACK ) {
if ( write( (addr & 0xFF00) >> 8 ) == ACK ) {
if ( write( (addr & 0x00FF) ) == ACK ) {
/* Dummy write successful */
start();
if ( write(EEPROM_READ_ADDR) == ACK) {
val = read(NACK);
}
else
print_on_lcd("write device Read id failed!!!");
}
else
print_on_lcd("write addr low byte failed!!!");
}
else
print_on_lcd("write addr high byte failed!!!");
}
else
print_on_lcd("write device_write id failed!!!");
stop();
return val;
}
/* Current address Read */
unsigned char current_read()
{
/* read a byte from the last address read/written + 1 */
unsigned char byte = ERROR;
start();
if ( write(EEPROM_READ_ADDR) == ACK )
byte = read(NACK);
else
print_on_lcd("write(read id) failed!! ");
stop();
return byte;
}
/* Sequential read */
unsigned int seq_read( unsigned int size, __idata unsigned char *buf, unsigned char addr)
{
/* read sequentially 'size' bytes to buffer 'buf' starting
* from address 'addr' */
unsigned int num = 1; /* count the number of bytes read */
unsigned char byte = 0;
*buf++ = byte_read(addr);
start();
if ( write(EEPROM_READ_ADDR) == ACK ) {
for ( ; size -1 ; size-- ) {
buf[num] = read(ACK);
num++;
}
buf[num] = read(NACK); /* transmit NACK with last byte
* followed by a STOP */
num++;
}
else
print_on_lcd("Device not selected!");
stop();
return (num);
}
/* main program */
main()
{
unsigned char addr = 0;
unsigned char *ptr = "testing page read operation";
unsigned int i = 0;
__idata unsigned char buf[128] = ""; /* A null string */
init_lcd();
print_on_lcd("EEPROM test");
for ( i = 0; ptr[i]; i++ ) {
if ( byte_write( i, ptr[i] ) != SUCCESS )
print_on_lcd("byte_write() failed!!!");
}
byte_write( i, ptr[i] ); /* for last cahracter */
print_on_lcd("seq_read()!!");
seq_read( 20, buf, 0x00 );
print_on_lcd(buf);
for ( i = 0; i < 20; i++ ) {
buf[i] = byte_read(i);
}
print_on_lcd("otherwise!!");
print_on_lcd(buf);
while (1);
}
|
| Topic | Author | Date |
| AT24C512 Sequential Read failed!! | 01/01/70 00:00 | |
| the IIC engine is identical ... | 01/01/70 00:00 | |
| Sample code | 01/01/70 00:00 | |
| what are the symptoms? | 01/01/70 00:00 | |
| symptoms | 01/01/70 00:00 | |
| A common mistake... | 01/01/70 00:00 | |
| Your code looks fine | 01/01/70 00:00 | |
| It took me ages ! | 01/01/70 00:00 | |
| uint8_t range | 01/01/70 00:00 | |
| confusion | 01/01/70 00:00 | |
| you use uint8_t in your read_seq () | 01/01/70 00:00 | |
| Do you want the full corrected source code ? | 01/01/70 00:00 | |
| my own code | 01/01/70 00:00 | |
| An explanation | 01/01/70 00:00 | |
| code update | 01/01/70 00:00 | |
| diff is your friend | 01/01/70 00:00 | |
| size -1 | 01/01/70 00:00 | |
| write program, rather than code... | 01/01/70 00:00 | |
It's Working | 01/01/70 00:00 |



