Forum: Mikrocontroller und Digitale Elektronik ATMega32 Pointer Register


von Michael T. (Gast)


Lesenswert?

Hallo,

da ich glaub ich im moment ein kleines Verständnisfrage zu den 
Pointerregistern habe hier ne kleine Frage:

Ich möchte mir eine Art Ringpuffer bauen, auf das ich mit Z pro Zyklus 
auf eine Stelle schreibe und mit Y eine andere Stelle auslese.
Im Moment stehen in der Tabelle noch konstante Werte, weils eben hier 
hapert:
1
;=============================================================
2
;Datentabelle
3
;=============================================================
4
.org $6000
5
tab1: .db 1,2,3,4,5,6,1,2,3,4,5,6

Wenn ich jetzt versuche mit
1
;--Speicherwerte holen
2
    ldi YH, HIGH(tab1)
3
    ldi YL, LOW(tab1)
4
    
5
    ld r22, Y+

die Konstante in das GPR zu laden, sollte doch '1' draufstehen und der 
Pointer anschließend auf 0x6001 stehen.
Leider steht aber eben auf r22 nicht '1' sondern irgend ein anderer Wert 
(vermutlich '0').

Wo liegt mein Denkfehler?

Vielen Dank schon mal
 Gruß Mich

von albi (Gast)


Lesenswert?

wozu das .org $6000 ?
Damit platzierst du doch den Code auf den Anfang des 24. KiloBytes. Da 
die Tabelle im RAM angelegt wird, sollte das doch egal sein. Falls du 
willst, dass die Tabelle nicht im RAM, sondern im Flash steht, darfst du 
das nicht mit ld r22, Y+ auslesen. Auf den Flash greift man anderweitig 
zu.

>>und der Pointer anschließend auf 0x6001 stehen.

Der Pointer vielleicht (weiß nicht) - aber worauf willst du damit 
zugreifen?. Mit $6000 bist zu wie gesagt beim 24. KiloByte. Insgesamt 
ist es relativ Sinnlos eine Speicheradresse zu verwenden, die mehrfach 
über den tatsächlich vorhandenen Speicher hinauszeigt....


MFG

von Hannes L. (hannes)


Lesenswert?

Ich nehme .db immer, um Konstanten im Flash abzulegen. Wenn ich Platz im 
SRAM reservieren möchte, lege ich mit .dseg fest, dass die folgenden 
Direktiven auf SRAM wirken und reserviere mit .byte den entsprechenden 
Platz.

...

von Michael T. (Gast)


Lesenswert?

das .org war erstmal völlig willkürlich gewählt, dachte mir wohl, damit 
ist die Tabelle aus dem weg. Dass die Adresse im Flash liegt war mit 
zwar klar, aber nicht dass ich darauf anderweitig zugreifen muss.

D.h. wenn ich das .org weglasse steht die Tabelle einfach nach dem 
(Programm-)Code und ich kann mit ld zugreifen!?

Hast du vielleicht nen Tip wo ich nachlesen kann wie man auf den 
Flash-Speicher zugreift?

Vielen Dank,
 Gruß Mich

von Simon K. (simon) Benutzerseite


Lesenswert?

Du kannst auf den Flash nicht per ld zugreifen. Der Flash ist ein 
EEPROM. Das heißt, dass du byteweise lesen kannst (mit lpm) aber nur 
Blockweise schreiben (spm). Außerdem ist der Flash nur begrenzt 
beschreibbar.

Wenn du eine "Variable" anlegen willst, soll diese ja "variabel" sein. 
Dafür muss sie im RAM liegen.

PS: Dein Programm sollte so, wie es da steht aber unabhängig von diesem 
Problem funktionieren. Du solltest nur statt >ld< >lpm< benutzen und die 
Parameter von HIGH() und LOW() jeweils x2 nehmen. (Siehe Tutorial auf 
der Site hier).

von spess53 (Gast)


Lesenswert?

Hi

Mit deinem Programmkonstrukt legst du den Puffer im Flashspeicher an !!!

Richtig:         .dseg
           tabl: .byte 12

'.db' funktioniert im Ram nicht.

MfG Spess

von Simon K. (simon) Benutzerseite


Lesenswert?

@spess53:
Michael T. wrote:
> Dass die Adresse im Flash liegt war mit
> zwar klar, ...

nicht sofort schreiben, auch mal lesen.. ;)

von Hannes L. (hannes)


Lesenswert?

Simon Küppers wrote:
> @spess53:
> Michael T. wrote:
>> Dass die Adresse im Flash liegt war mit
>> zwar klar, ...
>
> nicht sofort schreiben, auch mal lesen.. ;)

Neenee, denn (Eröffnungsbeitrag):

> Ich möchte mir eine Art Ringpuffer bauen, auf das ich mit Z pro Zyklus
> auf eine Stelle schreibe und mit Y eine andere Stelle auslese.

Also geht es doch um SRAM und nicht um Flash, erst recht nicht um 
EEPROM.

Leider habe ich jetzt kein isoliertes Ringbuffer-Beispiel parat, nur 
eine Anwendung, in der die LCD-Ausgabe über Ringbuffer erfolgt:
http://www.hanneslux.de/avr/stopuhr/index.html

...

von spess53 (Gast)


Lesenswert?

Hi

Wenn du mit dem Flash arbeiten willst , kannst du nur LPM mit Z als 
Pointer benutzen. Dazu musst du allerdings Z mit der Byteadresse von 
tabl, und nicht mit der Wordadresse laden.

         ldi ZL,Low(tabl<<1)
         ldi ZH,High(tabl<<1)
         lpm ...

Ansonsten lege deinen Puffer gleich im Ram an und lade ihn am 
Programmanfang manuell mit Werten.

MfG Spess

von Simon K. (simon) Benutzerseite


Lesenswert?

Hannes Lux wrote:
> Also geht es doch um SRAM und nicht um Flash, erst recht nicht um
> EEPROM.

Wo steht da was von SRAM? Ringpuffer ist doch nur eine Pufferart. Und 
außerdem hat er ja im Nachhinein geschrieben, dass er vom Flash redet.
Klar ist nen Ringpuffer im Flash reichlich sinnlos, aber dass wusste er 
ja eben nicht.

@spess53: Ähm, mal davon abgesehen, dass ich das Programmsnippet 
indirekt schon geposptet habe, wird er ganz sicher "nicht mit den Flash" 
arbeiten wollen.

Meeennsch, leute!

von Hannes L. (hannes)


Lesenswert?

Simon Küppers wrote:
> Hannes Lux wrote:
>> Also geht es doch um SRAM und nicht um Flash, erst recht nicht um
>> EEPROM.
>
> Wo steht da was von SRAM? Ringpuffer ist doch nur eine Pufferart.

Ringbuffer (das Zwischenspeichern von Daten in einem ringförmig 
organisierten Speicherbereich mit dem Zweck, Tempounterschiede 
auszugleichen) ist ein Verfahren, dass eigentlich nur im RAM Sinn macht.

> Und
> außerdem hat er ja im Nachhinein geschrieben, dass er vom Flash redet.

Ich nehme an, dass Michael die Eigenheiten der Harvard-Architektur noch 
nicht verinnerlicht hat und deshalb (wie bei v. Neumann-Architektur) 
Programmspeicher und Datenspeicher noch nicht entsprechend trennt.

> Klar ist nen Ringpuffer im Flash reichlich sinnlos, aber dass wusste er
> ja eben nicht.

Eben, nur soll ich deshalb mit dem Urschleim beginnen und die 
Architekturen gegenüberstellen?

> Meeennsch, leute!

Genau, da haste recht, 150% Ack...  ;-)

...

von Michael T. (Gast)


Lesenswert?

So, erstmal nochmals Danke für die schnellen Antworten!
Da hab ich wohl einiges durcheinandergebracht mit dem AVR-Speicher....
Hab mich aber jetzt mal tiefer in das Tutorial eingelesen (Echt gut 
gemacht, aber ich hätte wohl ohne Hinweis oben anhand der Überschriften 
erstmal nicht draufgeklickt) und würde jetzt nochmal gern meinen 
Lernerfolgt bestätigt haben. Ich fass mal kurz zusammen:

1. Im Flash des AVR landet erstmal der Programmcode. Kann auch als 
Datenspeicher genutzt werden, zb für Strings etc. Sollte bzw. kann zur 
Laufzeit nicht (oder nur umständlich) beschrieben werden. Nötige 
Befehle: lpm bzw spm in Verbindung mit den Pointer-Registern. 
Reservierung von Speicher mit  .dseg und .db/.dw

2. Das EEPROM kann ebenfalls als Datenspeicher genutzt werden. Kann zur 
Laufzeit (mehr oder weniger umständlich über EEAR... ) 
gelesen/beschrieben werden. Reservierung über .eseg und .db/.dw

3. Ins RAM werden zum einen die GP- und IO Register gemappt. Zum anderen 
liegt hier das SRAM, das erstmal den Stack enthält, der von hohen zu 
niedrigen Adressen wandert. Daher ist bei den niedrigen Adressen auch 
Platz für Variablen (oder meinen Ringpuffer) die sich zur Laufzeit 
ändern (können/sollen). Reservierung über .dseg und .byte. Zugriff zb. 
über Labels.

Ich werde also meinen 12 Byte Ringpuffer im .dseg platzieren und jedes 
Byte über ein Label ansprechen.

So, jetzt wärs schön wenn mir das Ganze jemand bestätigt ;)

von Michael T. (Gast)


Lesenswert?

> Ich nehme an, dass Michael die Eigenheiten der Harvard-Architektur noch
> nicht verinnerlicht hat und deshalb (wie bei v. Neumann-Architektur)
> Programmspeicher und Datenspeicher noch nicht entsprechend trennt.

Ich glaub genau hier liegt das Problem! Ich hab bisher C167 programmiert 
und der hat eben ne von-Neumann Architektur....


Leute das Forum hier gefällt mir, ich glaub ihr habt jetzt gleich ein 
neues Mitglied ;)

von spess53 (Gast)


Lesenswert?

Hi

Nur als Tip: Puffer in Grössen von 2er-Potenzen, z.B.16, lassen sich 
wesentlich besser handeln als solche (binär) ungeraden Zahlen wie 12.

MfG Spess

von Hannes L. (hannes)


Lesenswert?

@Michael:

Deine Einteilung der Speicherarten stimmt soweit. Allerdings solltest Du 
auch auf die Einschränkungen gewisser (gemappter) Adressbereiche achten. 
So kann nur die (obere) Hälfte der Register mit Konstanten (ldi, cpi, 
..)operieren, es lässt sich nur die (untere) Hälfte des I/O-Bereiches 
bitorientiert (sbi, cbi, sbis, sbic) ansprechen, bei einigen AVRs 
beginnt SRAM nicht bei 96, sondern bei 256, davor gibt es 
"extendet-I/O", der allerdings nicht wie I/O (in, out), sondern wie SRAM 
angesprochen werden muss.

Noch'n Tip: AVR-Studio hat eine kontextsensitive F1-Taste. Funktioniert 
bei allen ASM-Befehlen, aber leider nicht bei den Direktiven, zu denen 
muss man sich per Help-Menü durchhangeln.

Konnte denn wenigstens der Link zur Stoppuhr etwas Klarheit schaffen?

...

von Michael T. (Gast)


Lesenswert?

hat mich auf jeden Fall nen großen Schritt weiter gebracht!

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.