ATMEL says the cell lifetime of an EEprom cell is about 100 000 write cycle/ cell.
If i do not change the value of a cell, does this stress the lifetime ?
e.g. writing word with values between 0-255,
does this decrease the lifetime of the MSB where always o is written ?
If you do not write / erase it. It is not affected. Period. So the LSB will wear out faster than the MSB.
Wear leveling is not too hard to do if you really need it. Atmel describes this in their application notes.
Cheers, Udo
Thank You Udo,
now remains me to figure out writing a "0" to a
"0" is erase . earase/write or leave it as is.
If you write a '0' to a '0' then it is still writing (deleting the old data and replacing it with the new). It does not take into account what is currrently in that spot.
Mowcius
Ah good point. Actually the datasheet does not state if writing the same value twice counts as two as as one write cycle.
Anyway, the erase would typically write 0xff if I remember this right. In doubt you would have to check before you write.
#include <avr/eeprom.h>
void EEPROM_write_byte(uint8_t *adr, uint8_t val) {
if (val != eeprom_read_byte(adr)) {
eeprom_write_byte(adr, val);
}
}
Ok, thank you, much clearer now.
By the way:
Is there an easy way ( without spliiting and recombining an uint16_t) to write an uint8_t in an area above 255 using the avrlibs ?
This should help...
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1234477290/3#3
(or search for "EEPROM_writeAnything")
An actual EEPROM test...
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=85029&start=all&postdays=0&postorder=asc
Of course there is an easier way. Have a look at the original AVR libs instead of the Arduino EEProm lib:
http://www.nongnu.org/avr-libc/user-manual/group__avr__eeprom.html
Cheers, Udo
Udo,
Of course there is an easier way
I can not find the easy way to write a single byte in address space above 255 without affecting neighbour of this address in the avrlib docs.
Might you point out (copy/paste here) which part of the docs you are referring to, please.
Thank You.
Why is
static __inline__ void eeprom_write_byte (uint8_t *__p, uint8_t __value)
not good enough?
Cheers, Udo
What's the largest value that can be passed in as __p to that function?
Pauls question is exactly my problem.
But maybe i'm missunderstanding something.
__p is a pointer, not a value. The largest "value" is thus definitely >255. Just try to pass (uint8_t *) 0x1FF and see what happens.
I use this function and I can write all 4k of my 644 controller. I still do not get the point.
Cheers, Udo
Ah, seems your comment and mine face a race condition. So the question is due to insufficient knowledge of pointers. This can be fixed easily.
uint8_t *p__ is a pointer pointing to a byte
uint16_t *p__ is a pointer pointing to two bytes
Both pointers will allocate the same amount of memory and can hold addresses in the whole address range. That is they use two bytes. You fill them like
p__ = (unit8_t *) 256
and immediately you see they can address >255 bytes.
Cheers. Udo
So the question is due to insufficient knowledge of pointers.
Seems you are right also in the above quoted point.
Thank you for clearing this. I will go to learn on pointers again now and test the eeprom write function this way.
Hey, you got the point --> do not feel stupid. You should see my mistakes ...
Example of a stupid pointer mistake today:
I coded
const uint8_t c_no_page_adr = (uint8_t *) -1;
instead of
#define c_no_page_adr ((uint8_t *) -1)
Once I included the header file twice the compiler started complaining and I just did not get it.
Btw: any wizard out there who could tell me how to declare such a constant as a constant instead of using a macro?
Cheers, Udo
Is this what you're after...
const uint8_t * c_no_page_adr = (uint8_t *) -1;
arghh, yes, this was really stupid
Just in case i'm not the only remaining stupid guy and for reference i send a nice working example which also shows the neighbours of the byte written in area above 255 (here 511)
#include <avr/eeprom.h>
void setup() {
Serial.begin(9600);
const uint8_t *p__ ;
uint8_t val = 117 ;
p__ = (const uint8_t *) 0x1FF; //511
eeprom_write_byte( (uint8_t*) p__, val );
eeprom_busy_wait();
Serial.println(eeprom_read_byte( (uint8_t*) p__ -1), DEC );
Serial.println(eeprom_read_byte( (uint8_t*) p__ ), DEC );
Serial.println(eeprom_read_byte( (uint8_t*) p__ +1), DEC );
}
void loop() {
;
}