0
votes

I have used the following code for accessing eeprom :

void EEPROM_write(unsigned int uiAddress,unsigned char ucData)
{
   while(EECR & (1<<EEWE))
   {
      //do nothing
   }

   while(SPMCR & (1<<SPMEN));
   EEAR = uiAddress;
   EEDR = ucData;
   EECR |= (1<<EEMWE);
   EECR |= (1<<EEWE);
}

char EEPROM_read(unsigned int uiAddress)
{
   while(EECR & (1<<EEWE))
   {
      //do nothing
   }

   EEAR = uiAddress;
   EECR |=(1<<EERE);
   return EEDR;
}

void EEPROM_write_str(unsigned int uiAddress,unsigned char* string,unsigned int size)
{
   int i;
   for(i=0;i<size;i++)
   {
      EEPROM_write(uiAddress+i,string[i]);
   }
}

void EEPROM_read_str(unsigned int uiAddress,unsigned char* string,unsigned int size)
{
   int i;
   for(i=0;i<size;i++)
   {
      string[i] = EEPROM_read(uiAddress+i);
   }
}

char str[]="hello ";
char str2[20];

int main()
{
   usart_init(12);
   //EEPROM_write_str(0,str,6);
   EEPROM_read_str(0,str2,6);
   usart_puts(str2,6);
}

In the above code, I first commented the EEPROM_read_str and usart_puts,...flashed it then commented the EEPROM_write_str function and removed comments from the other two and flashed again.despite this, the data does not get stored and the output shown in the terminal is yyyyy (hex- FF). What is the problem here?   (Here USART_puts transmits the string taking the second argument as number of characters)

2
There is eeprom at address 0? Where do you erase the eeprom before write?Lundin
@Lundin It is EEPROM at address 0 to 1023 I guessnalostta
@Lundin AVR-s are Hardvare architecture and all memories have separated address spaces. AVR have the option to to it during the write. The cell is erased and written in one go. It called by atmel as an "atomic eeprom write"0___________

2 Answers

0
votes

Working code from my old avr project. I do not use them for years so provide as is, as I do not remember exact meaning of the bits now

void EEPROM_write(uint8_t addr, uint8_t value) {
    while(EECR & (1 << EEPE)) ;             //wait for write enable bit to clear
    EECR &= ~((1 << EEPM1) | (1 << EEPM0)); // (erase & write in one operation)
    EEARL = addr;                           // set the address
    EEDR = value;                           // set value to be written
    EECR |= (1 << EEMPE);                       // set EEPROM Master Write Enable
    EECR |= (1 << EEPE);                        // set EEPROM Master Write Enable
}

uint8_t EEPROM_read(uint8_t addr) {
    while(EECR & (1 << EEPE)) ;             
    EEARL = addr;                           // set the address
    EECR |= (1 << EERE);
    return EEDR;
}
0
votes

This is from the source code companion files for AVR103 AVR EEPROM Application Note, the definitive 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.
}