Forum: Mikrocontroller und Digitale Elektronik Flash-Read bei Tiny 4/5/9/10


von Tiny4 (Gast)


Lesenswert?

Hallo,

ich wollte beim Tiny4/5/9/10 aus dem Flash ein Constant-Table auslesen 
(Z-Pointer). Der FLash beginnt bei den kleinen bei 0x4000. In einem 
Forum habe ich gelesen, man soll 0x4000 zum Z-Pointer hinzuaddieren !

LDI ZL,low(WERT*2)
;ADDIW Z,0x4000????????
LD R16,Z

von Falk B. (falk)


Lesenswert?

@ Tiny4 (Gast)

>ich wollte beim Tiny4/5/9/10 aus dem Flash ein Constant-Table auslesen
>(Z-Pointer). Der FLash beginnt bei den kleinen bei 0x4000.

Stimmt, steht auch so im Datenblatt.

> In einem
>Forum habe ich gelesen, man soll 0x4000 zum Z-Pointer hinzuaddieren !

Dann aber richtig addieren. Hier kann man ein wenig sparen.

1
    LDI   ZL,low(WERT*2)    ; Z-Pointer laden
2
    LDI   ZH,HIGH(WERT*2)
3
    LDI   R16, 0x40         ; Offset 0x4000 addieren, LSB kann man weglassen, weil + 0x00 keine Wirkung hat
4
    ADD   ZH, R16    
5
    LD    R16,Z

Klingt komisch, ist aber so.

"The Flash memory has an endurance of at least 10,000 write/erase 
cycles. The ATtiny4/5/9/10 Program Counter (PC) is 9 bits wide, thus 
capable of addressing the 256/512 program memory locations, starting at 
0x000. “Memory Programming” on page 106 contains a detailed description 
on Flash data serial downloading.

Constant tables can be allocated within the entire address space of 
program memory. Since program memory can not be accessed directly, it 
has been mapped to the data memory. The mapped program memory begins at 
byte
address 0x4000 in data memory (see Figure 5-1 on page 15). Although 
programs are executed starting from address 0x000"

D.h. im Compiler werden die Daten/das Programm zwar von Adresse 0x0000 
an aufwärts abgelegt, über die CPU und indirekte Adressierung kommt man 
aber nur ab Adresse 0x4000 ran. Etwas merkwürdig, ist aber halt so. Denn 
die Tinys haben eine geschrumpfte CPU, da wollte jemand krampfhaft ein 
paar Dutzend FlipFlops sparen. Ob sich das gelohnt hat?

von Tiny4 (Gast)


Lesenswert?

Vielen Dank für die Hilfe.

Ihr seid echt ein super Forum !!! Respekt

von Jakob (Gast)


Lesenswert?

Kann man das nicht einfacher haben, wenn man den µC-Typ-
spezifischen .h-File benutzt, um es per symbolischer Adressierung
mit dem lpm-Befehl vom Flash (CSEG) in's RAM (DSEG) zu kopieren?

Ansonsten wären die Tiny < 25 nicht nur leistungsärmer, teuer und
schwerer erhältlich, sondern auch noch schwerer zu programmieren!

Igitt!

von Falk B. (falk)


Lesenswert?

@Jakob (Gast)

>Kann man das nicht einfacher haben, wenn man den µC-Typ-
>spezifischen .h-File benutzt, um es per symbolischer Adressierung
>mit dem lpm-Befehl vom Flash (CSEG) in's RAM (DSEG) zu kopieren?

Das macht er doch!

LDI   ZL,low(WERT*2)

WERT ist das Label einer Variable. Allerdings gibt es bei diesen 
Super-Mini-Tinys kein LPM! Siehe Datenblatt, Abschnitt 19. Instruction 
Set.

>Ansonsten wären die Tiny < 25 nicht nur leistungsärmer, teuer und
>schwerer erhältlich, sondern auch noch schwerer zu programmieren!

Naja, was heißt schwer. Bei den Tinys ist halt alles in einen Adressraum 
eingeblendet, dort kann man nur per indirektem Zugriff über Z ran. 
Einzig der SRAM ist über LDS(STS ansprechbar. Zugegebenermaßen ist die 
Sequenz oben auch nciht gerade speichersparend, den sie braucht 5 
Befehle = 10 Bytes. Für eine Tabelle OK, für Einzelwerte eine 
Katastrophe 8-0.

von Horst M. (horst)


Lesenswert?

Falk B. schrieb:
> Dann aber richtig addieren. Hier kann man ein wenig sparen.
>
>
>
1
>     LDI   ZL,low(WERT*2)    ; Z-Pointer laden
2
>     LDI   ZH,HIGH(WERT*2)
3
>     LDI   R16, 0x40         ; Offset 0x4000 addieren, LSB kann man 
4
> weglassen, weil + 0x00 keine Wirkung hat
5
>     ADD   ZH, R16
6
>     LD    R16,Z
7
>

Oder
1
     LDI   ZL,LOW(WERT*2)
2
     LDI   ZH,HIGH(WERT*2)
3
     SUBI  ZH,-0x40
4
     LD    R16,Z

Oder gleich
1
     LDI   ZL,LOW(WERT*2)
2
     LDI   ZH,HIGH(WERT*2)+0x40
3
     LD    R16,Z

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Horst M. schrieb:
> Oder gleich
1
>      LDI   ZL,LOW(WERT*2)
2
>      LDI   ZH,HIGH(WERT*2)+0x40
3
>      LD    R16,Z
Damit das geht muss WERT doch dem Assembler bekannt sein, oder nicht?

von Falk B. (falk)


Lesenswert?

@ Johann L. (gjlayde) Benutzerseite

>>      LDI   ZL,LOW(WERT*2)
>>      LDI   ZH,HIGH(WERT*2)+0x40
>>      LD    R16,Z

>Damit das geht muss WERT doch dem Assembler bekannt sein, oder nicht?

Ja logisch! Das ist ein Label!
1
Wert:
2
    .db 42

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Falk B. schrieb:
> @ Johann L. (gjlayde) Benutzerseite
>
>>>      LDI   ZL,LOW(WERT*2)
>>>      LDI   ZH,HIGH(WERT*2)+0x40
>>>      LD    R16,Z
>
>>Damit das geht muss WERT doch dem Assembler bekannt sein, oder nicht?
>
> Ja logisch! Das ist ein Label!
1
> Wert:
2
>     .db 42

Ja aber warum schreibt man dann nicht
1
LDI R16, 42

Das ganze Geraffel mit Adressberechnung ist doch nur dann sinnvoll, wenn 
die Adresse nicht bekannt ist, d.h. wenn es sich um einen 
Array-Zugriff mit unbekannten Index handelt.

von Falk B. (falk)


Lesenswert?

@Johann L. (gjlayde) Benutzerseite

>Ja aber warum schreibt man dann nicht

>LDI R16, 42

>Das ganze Geraffel mit Adressberechnung ist doch nur dann sinnvoll, wenn
>die Adresse nicht bekannt ist, d.h. wenn es sich um einen
>Array-Zugriff mit unbekannten Index handelt.

Sicher, das war ja auch ein Beispiel eines Anfängers. Ausserdem könnte 
da noch irgendwann ein ADIW Z,1 folgen . . .

Es geht schon um

"aus dem Flash ein Constant-Table auslesen "

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.