??? 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 |