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