avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] using EEPROM


From: Theodore A. Roth
Subject: Re: [avr-gcc-list] using EEPROM
Date: Wed, 1 Oct 2003 22:49:26 -0700 (PDT)

On Thu, 2 Oct 2003, Jack Valmadre wrote:

>I've done a bit more searching.  Here's my understanding of how to use it,
>please tell me if I'm right or wrong.
>
>#include <avr/io.h>
>#include <avr/eeprom.h>
>
>static unsigned char EEaddr __attribute__((section (".eeprom"))) = 0;
>
>...
>
>EEaddr = 0x25;
>eeprom_write_byte(&EEaddr, 0x3A);    //write 0x3A to EEPROM address 0x25
>EEaddr = 0x9D;
>eeprom_write_byte(&EEaddr, 0xA3);    //write 0xA3 to EEPROM address 0x9D

I really don't think you have a grasp of C pointers. This is all you need to 
do (you don't even need the .eeprom section to do this):

  eeprom_write_byte ((uint8_t *)0x25, 0x3a);
  eeprom_write_byte ((uint8_t *)0x9d, 0xa3);

I hinted at this in this message:

  http://www.avr1.org/pipermail/avr-gcc-list/2003-September/005400.html

In that example, I use the ee_map variable simply as a means to have the 
compiler calculate the eeprom address, thus avoiding manual calculation. If 
you look closely, you'll see that I never actually set ee_map to anything. 
As far as I'm concerned, the ee_map variable doesn't even exist in the sense 
that it uses no flash or sram. It's just a "map" of the data I'm storing in 
eeprom. Putting the ee_map into the .eeprom section is what facilitates 
this.

Now, look again at what you did:

>EEaddr = 0x25;
>eeprom_write_byte(&EEaddr, 0x3A);    //write 0x3A to EEPROM address 0x25

I compiled this and here's the disassembly,

void
foo (void)
{
    EEaddr = 0x25;
  52:   85 e2           ldi     r24, 0x25       ; 37
  54:   80 93 00 00     sts     0x0000, r24
    eeprom_write_byte(&EEaddr, 0x3A);    //write 0x3A to EEPROM address 0x25
  58:   6a e3           ldi     r22, 0x3A       ; 58
  5a:   80 e0           ldi     r24, 0x00       ; 0
  5c:   90 e0           ldi     r25, 0x00       ; 0
  5e:   2e d0           rcall   .+92            ; 0xbc
}
  60:   08 95           ret


Notice that 0x00 is being loaded into r25:r24 at lines 5a and 5c. That is
the address of EEaddr, which means that you've passed the wrong address to
eeprom_write_byte().

The more insidious bug is what happened when you tried to set EEaddr = 0x25.
At line 52, you've loaded 0x25 into r24. Next, on line 54, the contents of 
r24 are stored in sram address 0x0000. Oops, you just wrote 0x25 to r00.

I recommend that you invest some time learning about pointers in C. Until 
you do that, you are going to have a very difficult time programming the 
AVR's. I wish I could say pointers are easy, but that would be a lie. It 
took me years to get a grip on them and I still probably don't know squat 
compared to some of the real masters out there.

Don't give up though, if even you get some harsh replies from this list
(which isn't the proper place for basic C questions).

Ted Roth



reply via email to

[Prev in Thread] Current Thread [Next in Thread]