The datasheet for the ATmega328P contains this table, which describes bits 4 and 5 of EECR:

EEPM1 EEPM0 Programming Time Operation
0 0 3.4ms Erase and write in one operation (atomic operation)
0 1 1.8ms Erase only
1 0 1.8ms Write only

I'm currently working on some non-blocking EEPROM-handling code and I'm wondering when and how I should erase the EEPROM.

  • What does erasing do? Does it set one byte to 0x0, or the entire EEPROM?
  • Should I erase it first whenever I want to write a byte?
    • If not, why is there an option to erase and write separately?
  • How do I initiate an erase?

Either the datasheet is rather lacking concerning the EEPROM, or I'm just not finding what I'm looking for. I tried using a search engine, but all results are either about the Arduino EEPROM library or <avr/eeprom.h>, both of which use polling instead of interrupts (and are therefore blocking).

  • 3
    "the datasheet is rather lacking concerning" Hmm, maybe link to the datasheet you're using, because I remember that these things are answered in it, unless you maybe you've wound up with a "summary" and not "complete" datasheet. There are also appnotes about using AVR EEPROM.
    – timemage
    Jul 4, 2022 at 16:05
  • I tried using a search engine, but all results are either about the Arduino EEPROM ... don't be searching for arduino eeprom ... don't search for either of those
    – jsotola
    Jul 4, 2022 at 16:52

2 Answers 2


Your questions are answered in the AVR ATMega328 datasheet.

The procedure for erasing and writing the internal EEPROM is outlined in chapter 7.6 (Register Description).

  • The Erase operation erases 1 byte (erasing an EEPROM cell sets it to all 1s, i.e. 0xff).
  • The EEPROM address to be erased/programmed is pointed to by the EEARL and EEARH registers. The value to be programmed into that address is set by the EEDR. Reading a value from EEPROM returns the value in the same EEDR register.
  • Before writing a new value to the EEPROM, the old value must first be erased. You can do that as two separate actions or one single action. You could also leave the cell deprogrammed (erased) by only erasing it and not programming it again.
  • You initiate an erase of the EEPROM address pointed to by EEARH/EEARL, by setting EEPM1 to 1, EEPM0 to 0 and setting EEPE to 1 to start the erase operation. Setting EEPM1 and EEPM0 both to 0 will erase and program a new byte in a single operation.

As for making EEPROM writes non-blocking, you could set a (non-blocking) timer for the duration of the write, erase or erase/write operation. According to the datasheet these operations respectively take 1.8, 1.8 and 3.4 ms. Just make sure your code does not access the EEPROM while these operations are taking place.

You could also (non-blocking) periodically poll the EEPE bit until it is cleared, signalling the operation is finished.

The most elegant way, i.m.o. is to make use of the EERIE flag by setting it to 1, which will enable the ATmega to generate an interrupt when the EEPROM operation is finished.

  • If the new value sets bits to 0 that are 1 in the old value, no erase is necessary. For example, you can write 0x55 into a cell that contains 0xD7 without the need to erase the cell before. Jul 5, 2022 at 7:24
  • @thebusybee, true, you can generally change an unprogrammed ("1") EEPROM bit to a programmed ("0") bit without erasing the cell. Changing bits from 0 to 1 again does require erasing the cell. This is not unique to the ATmega328 but works for many/most EEPROMs.
    – StarCat
    Jul 5, 2022 at 8:40

I switched to FRAM, 32K x 8 can be gotten for just a few $$$, generally less the imported Arduinos. It is as fast as the Arduino can access it, both read and write. You can use I2C or SPI depending on which unit you buy. There are some very nice libraries for it making it easy to use. It is non volatile, ie does not lost information when power fails. It will support in the range of a trillion memory cycles with no delay when writing or reading it so no blocking. Just a few extra processor cycles because of the SPI or I2C overhead. If you have code already written for the External EEPROM it should work as is but it will have an unneeded delay in it.

  • Interesting though your answer is, it is a bit like answering someone who is having problems with their Ford, telling them that a Cadillac works better.
    – Nick Gammon
    Jul 7, 2022 at 9:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.