We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
If a problem with the I2C-Bus. I use a 80C515C and a Philips PCF8582C2T EEPROM. I can write one or two bytes without problems. But when I write more than two bytes (for excample eight bytes) I can do it only one time. When I call the function again I receive an Error (no Acknowledge of the Slave Adress). But in the datasheet of the EEPROM the write for 2 or 8 bytes is equal. Thanks for your help
/*------------------------------------------------------------------------------+ | Function: I2CEEPROM_RWriteSync | +------------------------------------------------------------------------------*/ IO_ErrorType I2CEEPROM_RWriteSync (IO_MemPtrType t_DataAddress_UW, IO_U8 t_Size_UB, IO_U8 t_MemoryPosition_UB) { IO_U8 t_ByteCounter_UB; IO_ErrorType t_Error_UB; t_Error_UB = 0x00u; /* Check size */ if (t_Size_UB < 0x09u) { /* Send start condition */ I2CEEPROM_SendStartCondition(); /* Send slave adress */ t_Error_UB = I2CEEPROM_WriteByte(MS3C_I2C_SLAVE_ADRESS & 0xFEu); if (t_Error_UB != 0x00u) { /* Write error */ t_Error_UB = 0x55;//IO_E_WRITE; } else { /* Send data adress */ t_Error_UB = I2CEEPROM_WriteByte(t_MemoryPosition_UB); if (t_Error_UB != 0x00u) { /* Write error */ t_Error_UB = IO_E_WRITE; } else { /* Send data */ for (t_ByteCounter_UB = 0x00u; t_ByteCounter_UB < t_Size_UB; t_ByteCounter_UB++) { /* Send byte */ t_Error_UB = I2CEEPROM_WriteByte(t_DataAddress_UW[t_ByteCounter_UB]); if (t_Error_UB != 0x00u) { /* Write error */ t_Error_UB = IO_E_WRITE; /* break the for loop */ t_ByteCounter_UB = 0xFFu; } } } } /* Send stop bit */ I2CEEPROM_SendStopCondition(); } else { t_Error_UB = IO_E_INVALID_SIZE; } /* Set Bus not busy */ I2CEEPROM_SetBusNotBusy(); return t_Error_UB; } /*------------------------------------------------------------------------------+ | Function: I2CEEPROM_WriteByte | +------------------------------------------------------------------------------*/ IO_ErrorType I2CEEPROM_WriteByte (IO_U8 t_Data_UB) { IO_U8 t_BitCounter_UB; IO_U8 t_TimeDelay_UB; IO_U8 t_TempData_UB; IO_ErrorType t_ReturnValue_UB = 0x00u; /* Send 8 bit */ for (t_BitCounter_UB = 0x00u; t_BitCounter_UB < 0x08u; t_BitCounter_UB++) { /* Set bit to send */ t_TempData_UB = t_Data_UB & 0x80u; t_TempData_UB = (t_TempData_UB >> 0x07u); I2C_DATA = t_TempData_UB; /* Set serial data */ /* Wait */ for (t_TimeDelay_UB = 0x00u; t_TimeDelay_UB < 0x02u; t_TimeDelay_UB++) { } I2C_CLOCK = IO_HIGH; /* Set serial clock = 1 */ /* Wait */ for (t_TimeDelay_UB = 0x00u; t_TimeDelay_UB < 0x02u; t_TimeDelay_UB++) { } I2C_CLOCK = IO_LOW; /* Set serial clock = 0 */ I2C_DATA = IO_LOW; /* Set serial data = 0 */ /* Bit is written, next bit */ t_Data_UB = (t_Data_UB << 0x01u); } /* Receive acknowledge bit */ I2C_DATA = IO_HIGH; /* Set serial data output = 1 */ for (t_TimeDelay_UB = 0x00u; t_TimeDelay_UB < 0x02u; t_TimeDelay_UB++) { } I2C_CLOCK = IO_HIGH; /* Set serial clock = 1 */ t_TimeDelay_UB = 0x00u; while (t_TimeDelay_UB < 0x20u) { if (I2C_DATA == 0x00) /* Get acknowledge from slave */ { t_ReturnValue_UB = IO_E_OK; t_TimeDelay_UB = 0x20; } else { t_ReturnValue_UB = IO_E_WRITE; t_TimeDelay_UB++; } } I2C_DATA = IO_LOW; /* Set serial data output = 0 */ for (t_TimeDelay_UB = 0x00u; t_TimeDelay_UB < 0x02u; t_TimeDelay_UB++) { } I2C_CLOCK = IO_LOW; /* Set serial clock = 0 */ return(t_ReturnValue_UB); }
Did you check the timing? EEPROMs need a certain time to do the programming. In short, the programming performed after Reception of a page (in this case probable 8 Bytes), the device first has to clear the adressed region (duration of the erase is found in the data sheet) and then it must write the adressed region. This leads to a certain time gap, in which the device is occupied by internal operations. Some EEPROMs for the I2C-Bus have an Output labelled lile "BSY" which gets active during that time (it can be used to poll the end of the write process). Without additional connection simply by means of the I2C-Bus works the so-called "Ack polling". This means, that during write process on the EEPOM memory your chip will not respond to any attempt to reach it on the bus. It seems not to be there, until the internal operation is finished. An "Ack polling" is done by doing a write cycle by the bus master, which writes 0 bytes. So it is just a write of the slave adress, followed by a stop condition. If the slave is present, it will pull the data line low after the adress is scanned, resulting in a valid acknowledge bit. If it is not present or is a EEPROM working internally, the ACK bit will not be low, the access is then terminated. Greetings, Axel