When I'm using Proteus to simulate following program, The EEPROM will not change, and Also the EEPE will not set when I add EECR to watch, The whole program is here:
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>
void writeEEPROM(unsigned char address,char data){
while(EECR & (1<<EEPE)); //wait for previus writing;
EECR = ((0<<EEPM1)|(0<<EEPM0));
//EECR=0;
EEAR = address; //set address to eeprom address register
EEDR = data;
cli();
EECR |= (1<<EEMPE);
EECR |= (1<<EEPE);
while(EECR & (1<<EEPE)); //wait for previus writing;
EECR |= (1<<EEMPE);
EECR |= (1<<EEPE);
sei();
}
char readEEPROM(unsigned char address){
while(EECR & (1<<EEPE)); //wait for previous write operation
EEAR=0;
EEAR |= address;
EECR=0;
EECR |= 1; //set bit0
return EEDR;
}
int main()
{
// Write your code here
char ret=0;
writeEEPROM(1,9);
_delay_ms(100);
ret=readEEPROM(1);
if(ret==9){
DDRB=0xff;
PORTB=0xff;
}
while (1)
;
return 0;
}
On calling writeEEPROM data will not store to the eeprom.
This is from the source code companion fileset to AVR103 AVR EEPROM Application Note, authoritative publication from the device manufacturer.
char EEPROM_GetChar( unsigned int addr )
{
do {} while( EECR & (1<<EEPE) ); // Wait for completion of previous write.
EEAR = addr; // Set EEPROM address register.
EECR = (1<<EERE); // Start EEPROM read operation.
return EEDR; // Return the byte read from EEPROM.
}
void EEPROM_PutChar( unsigned int addr, char new_value )
{
char old_value; // Old EEPROM value.
char diff_mask; // Difference mask, i.e. old value XOR new value.
unsigned char old_interrupt; // Stores interrupt flag while programming.
old_interrupt = __save_interrupt(); // Save interrupt flag state.
__disable_interrupt(); // Ensure atomic operation for the write operation.
do {} while( EECR & (1<<EEPE) ); // Wait for completion of previous write.
#ifndef EEPROM_IGNORE_SELFPROG
do {} while( SPMCSR & (1<<SELFPRGEN) ); // Wait for completion of SPM.
#endif
EEAR = addr; // Set EEPROM address register.
EECR = (1<<EERE); // Start EEPROM read operation.
old_value = EEDR; // Get old EEPROM value.
diff_mask = old_value ^ new_value; // Get bit differences.
// Check if any bits are changed to '1' in the new value.
if( diff_mask & new_value ) {
// Now we know that _some_ bits need to be erased to '1'.
// Check if any bits in the new value are '0'.
if( new_value != 0xff ) {
// Now we know that some bits need to be programmed to '0' also.
EEDR = new_value; // Set EEPROM data register.
EECR = (1<<EEMPE) | // Set Master Write Enable bit...
(0<<EEPM1) | (0<<EEPM0); // ...and Erase+Write mode.
EECR |= (1<<EEPE); // Start Erase+Write operation.
} else {
// Now we know that all bits should be erased.
EECR = (1<<EEMPE) | // Set Master Write Enable bit...
(1<<EEPM0); // ...and Erase-only mode.
EECR |= (1<<EEPE); // Start Erase-only operation.
}
} else {
// Now we know that _no_ bits need to be erased to '1'.
// Check if any bits are changed from '1' in the old value.
if( diff_mask ) {
// Now we know that _some_ bits need to the programmed to '0'.
EEDR = new_value; // Set EEPROM data register.
EECR = (1<<EEMPE) | // Set Master Write Enable bit...
(1<<EEPM1); // ...and Write-only mode.
EECR |= (1<<EEPE); // Start Write-only operation.
}
}
__restore_interrupt( old_interrupt ); // Restore interrupt flag state.
}
void main()
{
char t; // Temporary byte.
unsigned int addr = 0x10; // EEPROM address to use.
// Test the EEPROM_GetChar() function.
t = EEPROM_GetChar( addr );
// Try erasing the whole byte.
EEPROM_PutChar( addr, 0xff );
// Try changing a few bits to '0'.
EEPROM_PutChar( addr, 0x0f );
// Try changing bits both ways.
EEPROM_PutChar( addr, 0xf0 );
// Try changing nothing.
EEPROM_PutChar( addr, 0xf0 );
// Restore old value.
EEPROM_PutChar( addr, t );
for(;;); // Loop forever.
}