| ??? 02/26/09 08:59 Read: times |
#162872 - An explanation Responding to: ???'s previous message |
There are two problems with your code:
The i2c_read(char ack) function needs to force SDA high before the bits are clocked in. So that SDA is an high impedance input.
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;
SDA = HIGH; /* .kbv MAKE LINE AN INPUT */
for ( count = 0; count < 8; count++ ) {
byte <<= 1;
level = clock();
byte |= level;
}
SDA = status; /* status = 1 :- NACK
* status = 0 :- ACK */
clock();
return byte;
}
And the bit that drove me mad: You have *buf++ = read(NACK) followed by buf[1] = read(ACK) You meant to have: buf[0] = read(NACK); ... buf[1] = read(ACK); ... buf[20] = read(NACK); You are mixing a pointer operation *buf++ with an array operation. If you increment buf, a subsequent buf[1] is going to refer to the original buf[2]. I would suggest ONE form of syntax and stick to it. Mixing invites trouble. My personal preference would have been pointers throughout.
/* Sequential read */
unsigned int seq_read( unsigned int size, __idata unsigned char *buf, unsigned int addr) /* .kbv */
{
/* 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[0] = byte_read(addr); /* .kbv THE FIRST BYTE */
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++;
}
Also you use a uint8_t for addr instead of a uint16_t. You won't get far on a 24C512 with a uint8_t ! Your byte_read() function takes a uint16_t addr , but you only pass a uint8_t to seq_read(). Please ask if you do not understand any of this. David. |
| 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 |



