proteus 中的 AVR EEPROM 问题

AVR EEPROM issue in proteus

当我用Proteus模拟下面的程序时,EEPROM不会改变,而且加EECR看时EEPE也不会设置,整个程序在这里:

#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;
}

调用 writeEEPROM 数据不会存储到 eeprom。

这是从源代码配套文件集到 AVR103 AVR EEPROM Application Note,来自设备制造商的权威出版物。

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.
}