| ??? 11/04/08 06:41 Read: times |
#159612 - Try this, Responding to: ???'s previous message |
I had also faced a similiar problem. But with AT24c08. Then i had fiddled around it a little and found out that increasing the delay made the piece of code work properly. I was using AT89C51 running at 12MHz. Am including the following code for your guidance. The code was written to compile in Keil. This is for a reference only... You may just try alter the delay routine ( make it run slower and see if write occurs or not.
...
// Header :
// File Name : i2c_eeprom.c
// Author : shibin das
// Date : Thursday, November 16th 2006.
#define __ON__ 1
#define __OFF__ 0
#define __DEBUG__ __OFF__
#include <REG51F.H>
#include <stdio.h>
sbit SCL = P1^0;
sbit SDA = P1^1;
extern bit ramOK; // this bit could be used to see if proper write or read has occured or not.
void delay(unsigned int count);
void delay_ms( unsigned int count);
void RAM_Stop();
void PrintError(char uPE_no);
void RAM_Start();
unsigned char RAM_SendByte(unsigned char uByte);
void RAM_BWrite(unsigned int iRW_Addr, unsigned char uByte);
unsigned char RAM_BRead(unsigned int iRR_Addr);
void RAM_WWrite(unsigned int m_iAddr, unsigned int m_iWord);
void RAM_ULWrite(unsigned int m_ulAddr, unsigned long int m_ulWord);
unsigned int RAM_WRead(unsigned int m_iAddr);
unsigned long int RAM_ULRead(unsigned int m_ulAddr);
void delay(unsigned int count){
if(count > 4 ) count /=4;
for( 1 ; count ; count--);
}
void delay_ms( unsigned int count){
for( 1; count ; count--) delay(1000);
}
//////////////////////////////////////////////////////////////
// Function Name : RAM_Stop
// Parameters : none
// Return Values : none
// Description : Pulls SCL and SDA high.
//////////////////////////////////////////////////////////////
void RAM_Stop()
{
SDA = 0;
delay(20);
SCL = 1;
delay(20);
SDA = 1;
}
//////////////////////////////////////////////////////////////
// Function Name : PrintError
// Parameters : char
// Return Values : none
// Description : Helps identify the error that occured in eeprom communication.
// Also clears "ramOK" variable to inform the main program that an error has
// occured.
//////////////////////////////////////////////////////////////
void PrintError(char uPE_no)
{
RAM_Stop();
uPE_no = 0;
/**********************************\
ERR0; No ack in WR from Ctrl Word
ERR1; No ack in WR from Addr
ERR2: No ack in WR from Data
ERR3: No ack in RD from Ctrl Word1
ERR4: No ack in RD from Addr
ERR5: No ack in RD from Ctrl Word2
ERR6:
\**********************************/
//printf("\nERR%d",uPE_no);
/*
sprintf(LCDBuf,"ERR%d",uPE_no);
LCDPrint(LCDBuf,0x8B);
delay(20);
sprintf(LCDBuf," ");
LCDPrint(LCDBuf,0x8B);
*/
ramOK = 0;
}
//////////////////////////////////////////////////////////////
// Function Name : RAM_Start
// Parameters : none
// Return Values : none
// Description :
//////////////////////////////////////////////////////////////
void RAM_Start()
{
SDA = 1;
SCL = 1;
if( !SDA || !SCL )
{
PrintError(6);
//printf("\n SDA and SCL loaded");
return;
}
SDA = 0;
delay(20);
SCL = 0;
}
//////////////////////////////////////////////////////////////
// Function Name : RAM_SendByte
// Parameters : unsigned char
// Return Values : unsigned char
// Description :
//////////////////////////////////////////////////////////////
unsigned char RAM_SendByte(unsigned char uByte)
{
char cnt;
for(cnt=0; cnt<8; cnt++)
{
if( uByte & 0x80 )
SDA = 1;
else
SDA = 0;
delay(20);
SCL = 1;
delay(20);
SCL = 0;
delay(20);
uByte <<= 1;
}
SDA = 1;
delay(20);
SCL = 1;
delay(20);
if( SDA )
{
SCL = 0;
return(1);
}
else
{
SCL = 0;
return(0);
}
}
//////////////////////////////////////////////////////////////
// Function Name : RAM_BWrite
// Parameters : unsigned int, unsigned char
// Return Values : none
// Description :
//////////////////////////////////////////////////////////////
void RAM_BWrite(unsigned int iRW_Addr, unsigned char uByte)
{
unsigned int uiTemp;
RAM_Start();
iRW_Addr %= 1024; // Calculate <Page:uAddress>
uiTemp = iRW_Addr/256;
uiTemp <<=1;
uiTemp |= 0xA0;
if( RAM_SendByte(uiTemp) ) // Ctrl Wd
{
PrintError(0);
//printf("\n No ack in WR from Cntrl Word");
return;
}
uiTemp = iRW_Addr%256;
if( RAM_SendByte(uiTemp) ) // Low ADDR
{
PrintError(1);
//printf("\n No ack in Wr from addr");
return;
}
if( RAM_SendByte(uByte) )
{
PrintError(2);
//printf("\n No ack in WR from data");
return;
}
RAM_Stop();
delay(2000);
}
//////////////////////////////////////////////////////////////
// Function Name : RAM_BRead
// Parameters : unsigned int
// Return Values : unsigned char
// Description :
//////////////////////////////////////////////////////////////
unsigned char RAM_BRead(unsigned int iRR_Addr)
{
unsigned char uByte;
unsigned int uiTemp;
char cnt;
RAM_Start();
iRR_Addr %= 1024; // Calculate <Page:uAddress>
uiTemp = iRR_Addr/256;
uiTemp<<=1;
uiTemp |= 0xA0;
if( RAM_SendByte(uiTemp) )
{
PrintError(3);
//printf("\n No ack in RD Cntrl 1");
return (0);
}
uiTemp = iRR_Addr%256;
if( RAM_SendByte(uiTemp) ) // ADDR
{
PrintError(4);
//printf("\n No ack in RD add");
return (0);
}
RAM_Start();
uiTemp = iRR_Addr/256;
uiTemp<<=1;
uiTemp |= 0xA1;
if( RAM_SendByte(uiTemp) ) // Read Ctrl Wd2
{
PrintError(5);
#if (__DEBUG__ == __ON__)
printf("\n No ack in RD Cntrl 2");
#endif
return (0);
}
SDA = 1;
delay(20);
uByte = 0;
for(cnt=0; cnt<8; cnt++)
{
SCL = 1;
delay(20);
uByte <<= 1;
if(SDA)
uByte |= 0x01;
else
uByte &= 0xFE;
SCL = 0;
delay(20);
}
SDA = 1;
delay(20);
SCL = 1;
delay(20);
SCL = 0;
RAM_Stop();
delay(2000);
return(uByte);
}
//////////////////////////////////////////////////////////////
// Function Name : RAM_WWrite
// Parameters : unsigned int, unsignged int
// Return Values : none
// Description :
//////////////////////////////////////////////////////////////
void RAM_WWrite(unsigned int m_iAddr, unsigned int m_iWord)
{
unsigned char m_uTemp;
m_uTemp = m_iWord&0xFF; // LOW BYTE on iAddr
RAM_BWrite(m_iAddr, m_uTemp);
m_iWord >>= 8; // HIGH BYTE on iAddr+1
m_uTemp = m_iWord&0xFF;
RAM_BWrite(m_iAddr+1, m_uTemp);
}
//////////////////////////////////////////////////////////////
// Function Name : RAM_ULWrite
// Parameters : unsigned int, unsigned long int
// Return Values : none
// Description :
//////////////////////////////////////////////////////////////
void RAM_ULWrite(unsigned int m_ulAddr, unsigned long int m_ulWord)
{
unsigned char m_uTemp;
m_uTemp = m_ulWord&0xFF; // LOWEST BYTE on iAddr
RAM_BWrite(m_ulAddr, m_uTemp);
m_ulWord >>= 8;
m_uTemp = m_ulWord&0xFF;
RAM_BWrite(m_ulAddr+1, m_uTemp);
m_uTemp = m_ulWord&0xFF;
RAM_BWrite(m_ulAddr+2, m_uTemp);
m_uTemp = m_ulWord&0xFF;
RAM_BWrite(m_ulAddr+3, m_uTemp); // HIGH BYTE on iAddr+3
}
//////////////////////////////////////////////////////////////
// Function Name : RAM_WRead
// Parameters : unsigned int
// Return Values : unsigned int
// Description :
//////////////////////////////////////////////////////////////
unsigned int RAM_WRead(unsigned int m_iAddr)
{
unsigned int iRetVal;
iRetVal = RAM_BRead(m_iAddr+1); // HIGH BYTE on iAddr+1
iRetVal <<= 8;
iRetVal |= RAM_BRead(m_iAddr); // LOW BYTE on iAddr
return(iRetVal);
}
//////////////////////////////////////////////////////////////
// Function Name : RAM_ULRead
// Parameters : unsigned int
// Return Values : unsigned long int
// Description :
//////////////////////////////////////////////////////////////
unsigned long int RAM_ULRead(unsigned int m_ulAddr)
{
unsigned long int ulRetVal = 0;
ulRetVal = RAM_BRead(m_ulAddr+3); // HIGHEST BYTE on iAddr+3
ulRetVal <<= 8;
ulRetVal = RAM_BRead(m_ulAddr+2);
ulRetVal <<= 8;
ulRetVal = RAM_BRead(m_ulAddr+1);
ulRetVal <<= 8;
ulRetVal |= RAM_BRead(m_ulAddr); // LOWEST BYTE on iAddr
return(ulRetVal);
}
... |
| Topic | Author | Date |
| 24C04 differences | 01/01/70 00:00 | |
| I've got the very same problem! | 01/01/70 00:00 | |
| Why only 04; why not higher | 01/01/70 00:00 | |
| 24cxx are not TRULY generic parts | 01/01/70 00:00 | |
| can only find the "P" | 01/01/70 00:00 | |
| not sure if a larger part would work | 01/01/70 00:00 | |
| Try this, | 01/01/70 00:00 | |
| Source changes seldom an option when repairing | 01/01/70 00:00 | |
| Ramtron seems to be one that ... | 01/01/70 00:00 | |
I may explore that option | 01/01/70 00:00 |



