Cannot Write to AVR Internal EEPROM from within Code

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've looked to this forum many times while learning the ways of the AVR and finally I need to post my own question:

I'm trying to write a byte to some location in my ATMEGA48's EEPROM. First I wrote my own read/write functions based on the register descriptions and then compared them to the samples to find them identical (I also finally tried copying verbatim). My program simply tells the AVR to blink an LED the number of times found in EEPROM location 0x00. When the LED kept on blinking, I assumed the value to always be 0xFF. Sure enough on reading the EEPROM out via avrdude, I get a file full of 0xFFs. However, on writing the file back to the EEPROM with the first byte changed to 0x05, I get 5 blinks confirming the read works...

I've tried adding arbitrary delays between commands and even putting the AVR to sleep during the write and waking it with the interrupt to no avail. I've tried idiot-checking and swapping the chip out. See code below. Any ideas?

Sorry for the long post but I don't wanna leave out any details for debugging. Thanks for the help, -Mike-

#include "atmega48.h"

int main()
{
	uint8_t data = 0;
	DDRB = 1; //PB0 output

	EE_write(0x00,0x05);
	delay(100);
	for(;;)
	{
		data = EE_read(0x00);
		delay(20000);
		for(uint8_t i=0;i

Included Functions:

void EE_write(uint16_t addr, uint8_t data)
{
	//cli();
	while(EECR & _BV(EEPE)); //wait for EEPE to be 0
	while(SPMCSR & _BV(SELFPRGEN)); //wait in case Flash is programming
	EEAR = addr;
	EEDR = data;
	EECR = _BV(EEMPE);  //set EEMPE to 1 (and EEPE to 0)
	EECR |= _BV(EEPE);  //set EEPE to 1 also(within 4clks) to initiate write
	return;
}

uint8_t EE_read(uint16_t addr)
{
	while(EECR & _BV(EEPE)); //wait for EEPE to be 0
	EEAR = addr;
	EECR |= _BV(EERE);
	return EEDR;
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You do not say which compiler you are using, and there are clues in your code to suggest avr-gcc.

When you read the data sheet, you saw that there are timing restrictions on the eeprom write.

So you must examine the generated ASM to see the exact instructions and check the critical cycle count.

Compile with optimisation and it should work.

Alternatively use , steal the code and re-write it as your own work.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, I had the same problem. I was working with the AVR-GCC (WinAVR) and compiling without optimisation.
When I changed the optimisation level to 's' it worked.

Try it! : )

Javi

My writing routine is quite similar:

void EEPROM_write_char(unsigned int location, unsigned char * EEPROM_data, unsigned char n)
{

        unsigned char savedSREG,i;
        
        savedSREG = SREG;    // keep setting so it can be restored
		
        cli();               // disable interrupts

        for(i = 0; i < n; i++, location++, EEPROM_data++){
             while ( EECR & (1<<EEPE)); 
	          EEAR = location;
             EEDR = *EEPROM_data;  // set data  
             EECR |= (1<<EEMPE);  // set "write enable" bit
             EECR |= (1<<EEPE);   // set "write" bit 
        }


         SREG = savedSREG;       // restore SREG
	 sei();
		
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Which is why you have which makes sure that you have the correct critical code sequences.

The compiler is free to translate your source code as it chooses, just as long as it conforms to the rules of the language.

It just happens that many compilers (with optimisation) may produce code that satisfies the "critical timing".
With a PIC, you actually have to use specific opcode sequences for some critical operations. The AVR does give a timing "window".

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A recent thread on time critical operations in C/avr-gcc: https://www.avrfreaks.net/index.p...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for all the responses! Wow, optimization changed to 's' and EEPROM Write works now just like that.

And yes, avr-gcc 4.3.0 on Ubuntu 8.10. My IDE is KontrollerLab. Normally I use AVR Studio but my windows machine passed on recently so I've been relearning how to do everything with Linux on my Asus eeePC.

Glad I joined, thanks again,
-Mike-