Sida 1 av 1
Läsa från programminnet AVR
Postat: 1 februari 2009, 19:24:45
av övrigt
Tjena
Jag har en lite fråga angående att läsa från programminnet i ATtiny kretsarna. Jag har kod som fungerar, men jag vill veta *varför* den fungerar.
Såhär sen delarna av koden ut
Kod: Markera allt
DATA:
.db 0b11111111
...
ldi ZL, low(DATA*2)
ldi ZH,high(DATA*2)
lpm
mov r16,r0
Efter koden ovan så ligger värdet inlagt vi DATA i programminnet i r16. Det jag inte förstår är varför 2an som multipliceras med DATA ska vara där? Saknas den så hamnar pekaren definitivt på fel plats.
Re: Läsa från programminnet AVR
Postat: 1 februari 2009, 20:06:59
av SvenW
Koden kan fungera tack vare att data adresseras via pekare.
Pekaren är dock förmodligen felaktigt 'castad', därför behövs tvåan.
Språket c tillåter sådant, och givetvis även assembler.
Henry Spencer:
Thou shalt cast all function arguments to the expected type if they are not of that type already, even when thou art convinced that this is unnecessary, lest they take cruel vengeance upon thee when thou least expect it.
http://www.lysator.liu.se/c/ten-commandments.html
Till c finns särskilda funktioner för att nå data i programminnet.
http://www.nongnu.org/avr-libc/user-man ... space.html
Re: Läsa från programminnet AVR
Postat: 1 februari 2009, 20:24:37
av thepirateboy
Det är väl helt enkelt för att programminnet är organiserat "word-wise", alltså 16 bitar.
Från databladet:
Since all AVR instructions are 16 or 32 bits wide, the Flash is organized as 1024/2048/4096 x 16.
Constant tables can be allocated within the entire Program memory address space (see the
LPM – Load Program memory instruction description).
Läs även sid 17 här:
http://www.avr-asm-download.de/beginner_en.pdf
As the program memory is organized word-wise (one instruction on one
address consists of 16 bits or two bytes or one word) the least significant bit selects the lower or upper byte
(0=lower byte, 1= upper byte). Because of this the original address must be multiplied by 2 and access is
limited to 15-bit or 32 kB program memory.
Like this:
LDI ZH,HIGH(2*address)
LDI ZL,LOW(2*address)
LPM
Re: Läsa från programminnet AVR
Postat: 1 februari 2009, 20:36:50
av övrigt
tack!
Re: Läsa från programminnet AVR
Postat: 1 februari 2009, 20:50:04
av Swech
Till skillnad från t.ex. 68000 familjen så har AVR ingen BYTE bit i programräknaren.
Alla instruktioner är därför jämnt delbara med 2 bytes. d.v.s 2,4,6 bytes långa
Så alla minnesrader är adresserade 0.1.2.3.4.5. men innehåller 2 bytes styck.
När man lägger in t.ex. strängar direkt i minnet så är dessa uppbyggda med bytes.
Assemblern vet dock inte skillnad om en label till en adress pekar på
program eller t.ex. en sträng. Den utgår ifrån att det är program.
MEN när man läser från minnet via Z registret så är denna BYTE orienterad.
På detta sätt kan man plocka ut båda bytes som finns på varje word adress.
Så.... för att kompilatorn skall lägga in korrekt adress för Z så måste labeln
multipliceras med 2.
Ett annat fenomen är även att assemblern alltid fyller ut strängar med 0 så att längden
blir ett jämnt antal bytes.
Swech
Re: Läsa från programminnet AVR
Postat: 1 februari 2009, 20:55:43
av sodjan
> Till skillnad från t.ex. 68000 familjen
Eller t.ex PIC...
Och för att komma åt den udda byten i programminnet så får man alltså
(efter multiplikationen med 2) lägga till 1 till adressen. Rätt ? Eller bara
öka pekaren med 1 för varje byte man vill läsa från programminnet om det
gäller en hel "sträng"...
Re: Läsa från programminnet AVR
Postat: 1 februari 2009, 21:12:57
av ie
Det stämmer. Datat hämtas sedan bytevis via pekaren. Det speciella är alltså att allt data alltid börjar på jämna adresser och att labelns adress, som alltså är wordbaserad, initialt måste multipliceras med 2.