??? 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; } |
Topic | Author | Date |
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 |