[Top][All Lists]
[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