Hello, I have the following code for writing/reading EEPROM of this device.
unsigned char eepromWrite (const unsigned int Address, unsigned char Data) { bit oldEA; unsigned char DataReadBack; if (Address <= 0x07ff) { oldEA = EA; EA = 0; EECON |= 0x02; // Enable EEPROM memory space XBYTE[Address] = Data; EECON &= 0xFD; // Disable EEPROM memory space EA = oldEA; EECON = 0x50; EECON = 0xA0; // Programming... // wait programming... while(EECON & b00000001); // Byte re-read oldEA = EA; EA = 0; EECON |= 0x02; // Enable EEPROM memory space DataReadBack = XBYTE[Address]; EECON &= 0xFD; // Disable EEPROM memory space EA = oldEA; if (DataReadBack != Data) { return(2); } return(0); } else { return(1); } } unsigned char eepromRead (const unsigned int Address, unsigned char* Data) { bit oldEA; if (Address <= 0x07ff) { oldEA = EA; EA = 0; while(EECON & b00000001); //EEbusy EECON |= 0x02; // Enable EEPROM memory space *Data = XBYTE[Address]; EECON &= 0xFD; // Disable EEPROM memory space EA = oldEA; return (0); } else { *Data = 0; return(1); } }
void write_to_EEPROM (unsigned int EEPROM_address, void *buffer, unsigned char buffer_len) { unsigned char *bp; for (bp = buffer; buffer_len; buffer_len--, bp++, EEPROM_address++) { eepromWrite(EEPROM_address, *bp); } Wait20ms(); } void read_from_EEPROM (unsigned int EEPROM_address, void *buffer, unsigned char buffer_len) { unsigned char *bp; for (bp=buffer; buffer_len; buffer_len--, bp++, EEPROM_address++) { eepromRead(EEPROM_address, bp); } }
typedef struct { uchar MotorMin; uchar MotorKnee; uchar MotorMax; } Blower_TYP; ////////// write_to_EEPROM (FAN_ADDR, &BlowerNew, sizeof (Blower_TYP)); void readMotorConf (void) { Blower_TYP temp; read_from_EEPROM(FAN_ADDR, &temp, sizeof(Blower_TYP)); Blower = temp; } }
hi, Only sometime the read function give wrong reading. How do you determine this? Do you find difference between twice reading or between writting and reading? By the way, the datasheet says: Note: The sequence 5xh and Axh must be executed without instructions between then otherwise the programming is aborted. So I think you should keep interrupts disabled during launching programming by writing the control sequence. Regards, Oleg
Hai, thanks for feedback about disabling interrupt. Back to the read function. It is from several reading, I test with this function.
void BlowerTest(void) { Blower_TYP xdata BlowerNew; bit OldET0; BlowerNew = Blower; OldET0 = ET0; ET0 = 0; readMotorConf(); // Read Blower from eeprom ET0 = OldET0; if (Blower.MotorMin != BlowerNew.MotorMin || Blower.MotorKnee != BlowerNew.MotorKnee || Blower.MotorMax != BlowerNew.MotorMax) { DisplayText (2,1, "Diff!"); } }
Can you have a look at the assembly code the compiler generates, especially for the
EECON |= 0x02; // Enable EEPROM memory space DataReadBack = XBYTE[Address]; EECON &= 0xFD; // Disable EEPROM memory space
BlowerNew = Blower;
Also, just as general advice, you might want to review your use of pointers here. On the '51 architecture, the use of pointers is generally fairly inefficient, and most locations are known at compile time. This is quite different from, say, programming in C on a PC.
; SOURCE LINE # 45 0030 43D202 ORL EECON,#02H ; SOURCE LINE # 46 0033 8F82 MOV DPL,R7 0035 8E83 MOV DPH,R6 0037 E0 MOVX A,@DPTR ;---- Variable 'DataReadBack' assigned to Register 'R7' ---- ; SOURCE LINE # 47 0038 53D2FD ANL EECON,#0FDH
Blower = temp;
Blower.MotorMin = temp.MotorMin; Blower.MotorKnee = temp.MotorKnee; Blower.MotorMax = temp.MotorMax;
Hallo all, There were mistakes on my test. It might other bugs. So, that