Forum: Mikrocontroller und Digitale Elektronik Adressierung eines LUT mit Z-Register


von Dominik L (Gast)


Lesenswert?

Hallo!
Ich versuche einen look up table mit dem Z-Register auszulesen. Dabei
habe ich aus dem Tutorial die Anfangsadressierung

ldi ZL, LOW(tabelle_3*2)
ldi ZH, HIGH(tabelle_3*2)

mit dem *2 übernommen. Die abgelegten Daten werden auch gefunden, bis
zu einer bestimmten Adresse. Was mich stutzig macht ist, dass in der
Simulation die abgelegten Daten auch an der Stelle liegen, wo ich sie
abgelegt habe, das Z_Register, jedoch auf die doppelte Speicheradresse
zeigt, wo nichts abgelegt ist. Die Werte werden trotzdem erfolgreich
ausgelesen.
Sehe ich das also so richtig, dass das Z_Register immer um 2
weitergesetzt werden muss um eine Speicheradresse weiter zu kommen, die
dann jeweils 16 Bit adressiert?

Wenn ich das verstanden habe, dann kommt gleich meine eigentliche
Frage.

MFG Dominik

von A.K. (Gast)


Lesenswert?

Der Program Counter adressiert 16-Bit Worte und der Atmel-Assembler
behandelt ihn auch so, d.h. das erste Wort hat die Adresse 0, das
zweite die Adresse 1. Wird jedoch dieser Speicher mit LPM adressiert,
werden Bytes daraus, d.h. per LPM adressiert steht das zweite Wort an
Adresse 2, das dritte an Adresse 4. Daher *2. Mithin ist die Adresse im
Flash-ROM Interpretationssache. Je nachdem ob sie als Code oder als
Daten interpretiert werden.

NB: GCC/GAS verhalten sich da etwas anders.

von Dominik L (Gast)


Lesenswert?

Ok dann war ich da ja wohl schon auf dem richtigen Weg. Also danke an
A.K.. Jetzt zu meinem eigentlichen Problem:

Ich habe einen LUT, der bei 0x70 im Programmspeicher, bzw 0xE0 für das
Z_Register beginnt und den ich mit

lpm und adiw ZL, 1

auslese. Nun bekomme ich genau an der Stelle Probleme, wo das
Z_Register  von x00FF auf 0x0100 wechselt. Da wird auf einmal nurnoch
0xFF ausgelesen. Ich meine aber gelesen zu haben, dass mit adiw ZL,1
das komplette Registerwort inkrementiert wird, also auch das higher
Byte. Nun weiß ich nicht genau, wo das Z_Register die FFs aufeinmal
herliest.

MFG Dominik

von Dominik L (Gast)


Lesenswert?

Hat da vielleicht jemand eine Idee warum das Z-Register probleme beim
Übergang von 0x00FF auf 0x0100 macht und ich dann nurnoch 0xFFs
eingelesen bekommen? Das heisst doch dass ich irgendwo zu weit unten im
Flash-Speicher bin oder?

Gruß Dominik

von A.K. (Gast)


Lesenswert?

Ohne jede Information (Programm) schwer zu sagen.

von Dominik L (Gast)


Lesenswert?

Ok hier habe ich mal ein Beispielprogramm. Kurz zur Erklärung:
Ich lege eine Liste mit Werten im Codebereich am Adresse 0x7A an. Das
entspricht einer Adresse von 2*0x7A= 0xF4. Also kurz vor dem Wechsel zu
0x100, indem auch das Höherwertige Byte des Z-Registers benötigt wird.
Dann soll das Programm nur immer wieder einen Wert aus der Liste
einlesen und auf PortD (LEDs) ausgeben und das Z-Register
inkrementieren. Bis zu der Zahl 12 in der Liste funktioniert das auch.
Nur ab Zahl 12 werden nurnoch 0xFFs augegeben. Die 12 hat in meiner
definition genau die Z-Registeradresse von 0xFF.
Jetzt weiß ich nur nicht warum das nicht funktioniert.
1
.include "m16def.inc"
2
.def temp1 = r16
3
4
rjmp start
5
6
start:            ldi temp1, LOW(RAMEND)    ;Stack initialisieren
7
      out SPL, temp1
8
      ldi temp1, HIGH(RAMEND)
9
      out SPH, temp1
10
11
      ldi temp1, 0xFF        ;Port D = Ausgang (LED)
12
      out DDRD, temp1
13
14
      ldi ZL, LOW(tabelle_3*2)  ;Z_Register auf Anfang der Liste
15
      ldi ZH, HIGH(tabelle_3*2)
16
17
laden:    lpm              ;Wert laden
18
      out PORTD, r0        ;Wert ausgeben
19
      adiw ZL, 1          ;nächsten Wert adressieren  
20
                    
21
wart_1:    sbic PINA, 7        ;warten auf Taster
22
      rjmp wart_1
23
wart_2:    sbic PINA, 6        ;warten auf Taster
24
      rjmp wart_2
25
26
      rjmp laden          ;neuer Durchlauf
27
28
.org 0x7A                ;Z-Register Adresse: 0x00F4
29
tabelle_3:
30
.db  1, 2,3,4,5,6,7,8
31
.db  9,10,11,12,13,14,15,16        ;Bis Zahl (Z-Register Adresse 0x00FF)
32
.db 17,18,19,20,21,22,23,24        ;Ausgabe normal,danach nurnoch 0xFF

von A.K. (Gast)


Lesenswert?

Ich kann kein Problem erkennen.

von Dominik L (Gast)


Lesenswert?

Hm is ja mist. Hast du es mal ablaufen lassen oder nur den Code
überprüft? Das Problem fängt immer genau bei dem Übergang von 0x00FF zu
0x0100 an. Wenn ich die Liste etwas weiter oben in den Speicher
schreibe, dann kann ich auch ein paar Bytes mehr einlesen. Eben wieder
genau bis zu dem Übergang. Hat da vielleicht jemand anderes schonmal
eine ähnliche Erfahrung gemacht oder ne Idee?

Gruß Dominik

von D. W. (dave) Benutzerseite


Lesenswert?

Ist das jetzt das ganze Programm?
Bis zu 0xFF musst du ja was mit 130x drücken, vielleicht rutscht du
einfach wegen zu langem drücken (beide gleichzeitig) rüber?

Hab ich das bis jetzt immer falsch gedacht?
.ORG ist doch in Byte?

von Andi K. (Gast)


Lesenswert?

Für Einzelschritt mußt Du natürlich auch prüfen, ob die beiden Taster
losgelassen worden sind.
Anssnten bist Du binnen Sekundenbruchteilen über der Tabelle drüber und
es wird nur noch das vom Erase erzeugte FF ausgelesen was vor jedem
Flash gemacht wird.

laden:    lpm              ;Wert laden
          out PORTD, r0    ;Wert ausgeben
          adiw ZL, 1       ;nächsten Wert adressieren

wart_01:  sbis PINA, 7     ;warten auf Taster
          rjmp wart_01
wart_02:  sbis PINA, 6     ;warten auf Taster
          rjmp wart_02

wart_1:   sbic PINA, 7     ;warten auf Taster
          rjmp wart_1
wart_2:   sbic PINA, 6     ;warten auf Taster
          rjmp wart_2

          rjmp laden       ;neuer Durchlauf

Ansonsten gibt es in der Codesammlung eine wesentlich effektivere
Methode 8 Tasten auf gedrückt, losgelassen oder gehalten zu prüfen.
Author ist Peter Dannegger.

MfG
Andi

von Andi K. (Gast)


Lesenswert?

Hmmm... ich glaube, so wäre es besser:

wart_01:  sbis PINA, 7     ;warten auf Taster
          rjmp wart_01
          sbis PINA, 6     ;warten auf Taster
          rjmp wart_01

Mußt Du halt probieren.

MfG
Andi

von Dominik L (Gast)


Lesenswert?

Ja das sit das gnze Programm. Macht so zwar noch keinen Sinn, aber
verdeutlicht mein Problem denke ich ganz gut. Ob .org jetzt Byte ist
weiß ich nicht. Die Liste ist auf jedenfall an der richtigen Stelle im
Flash abgelegt, also bei 0x7A, wenn man es als Code interpretiert.

Also in der Simulation is das bei mir so:
Das Z-Register wird auf tabelle_3 gesetzt und steht dann auf 0xF4. Dann
sind es noch 12 Schritte bis 0xFF. Und genausoweit kommt das Programm
auch. Also zwölf mal drücken, dann wird 12 ausgegeben, dann als
nächstes kommen nurnoch 0xFFs.
Beide Tasten gleichzeitig drücken glaube ich nicht. Komme auch jedesmal
genau wieder bis 12.

MFG Dominik

von A.K. (Gast)


Lesenswert?

Wenn die Taster sauber nacheinander gedrückt und losgelassen werden,
sehe ich darin kein Problem, da wart_2 erst fertig wird wenn Taste A7
wieder losgelassen ist. Für diesen Test ist das ausreichend.

Nur wenn beide gleichzeitig gedrückt sind, rauscht das durch.

von Dominik L (Gast)


Lesenswert?

Hallo Andi!
Ich möchte nicht, dass beide Taster gleichzeitig gedrückt werden, hab
das einfach so gemacht, damit das Programm eben nicht sofort
durchläuft. Ich drücke die erste Taste, und dann die zweite, das
Programm läuft dann weiter und wartet wieder auf Drücken der ersten
Taste. Das funktioniert auch super. Nur darum geht es mir ja garnicht.
Also dass das Programm unbeabsichtigt so durchläuft ist ausgeschlossen.
Bis zur 12 werden mir ja alle Zahlen einwandfrei ausgegeben.

von A.K. (Gast)


Lesenswert?

Ich habe das ebenfalls simuliert und es hat noch bei 14 funktioniert.

.ORG ist in Worten. Im Code jedenfalls. Ist ja auch so richtig
angegeben.

von A.K. (Gast)


Lesenswert?

Apropos Simulation: Ist die Version vom AVR-Studio aktuell?

von Dominik L (Gast)


Lesenswert?

Ja das ist ja das Verwunderliche. In der Simulation funktioniert das bei
mir auch super bis zum, Ende der Liste. Nur im Controller (mega32 oder
mega16) selbst nicht.

MFG Dominik

von Dominik L (Gast)


Lesenswert?

Die Version ist 4.11.
Nur in meinem STK500 ist eine etwas ältere Software, weil ich mit dem
updaten schon schlechte Erfahrung gemacht habe. Hat mir zwei mal meinen
ISP Programmer lahmgelegt.

von A.K. (Gast)


Lesenswert?

Lies doch mal das Flash wieder aus und schau was drin steht. Am Ende
steht da jenseits der ersten 256 Bytes garnichts drin...

von A.K. (Gast)


Lesenswert?

Nachtrag: Schrott rein Schrott raus - geht natürlich nicht mit dem
gleichen Programmer. Wenn der beim Programmieren die oberen Adressen
verzwiebelt, tut er das beim Auslesen evtl. auch.

von Dominik L (Gast)


Lesenswert?

:1000000000C00FE50DBF08E00EBF0FEF01BBE4EF2E
:10001000F0E0C89502BA3196CF99FECFCE99FECFC7
:10002000F8CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
:10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
:10004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
:10005000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
:10006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
:10007000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
:10008000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
:10009000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
:1000A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
:1000B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
:1000C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
:1000D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
:1000E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
:1000F000FFFFFFFF0102030405060708090A0B0CB6
:100100000D0E0F101112131415161718FFFFFFFF15
:10011000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
:10012000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF

So das is das ausgelesene hex File. Die Zahlen von 1 bis 24 sind alle
da. Nur was bedeutet das B6 in der letzten Spalte? Is das ne
Adressangabe?

von Andi K. (Gast)


Lesenswert?

Wie wärs mit Checksumme für die Datenzeile?

MfG
Andi

von Dominik L (Gast)


Lesenswert?

Hier mal ein paar neue Informationen. Wenn ich den Codebereich einfach
weiter hinten in den Speicher schiebe und meine Tabelle dann bei 0x0001
anfangen lasse, dann kann ich alle Zahlen auslesen. Also muss es
wirklich an dem Übergang des Z-Registers von 0x00FF nach 0x0100 liegen.
Den Codebereich habe ich auch mal auf den Übergang von 0x00FF auf 0x0100
und auf 0x007F zu 0x0080 gelegt und beides funktioniert. Aber wirklich
schlau werde ich daraus auch nicht.

Gruß Dominik

von Andi K. (Gast)


Lesenswert?

Und wie sieht es mit "lpm r0,z+" und ohne "adiw zl,1" aus?

MfG
Andi

von Dominik L (Gast)


Lesenswert?

@ Andi: Habe ich gerade ausprobiert und es läuft auch nicht. Wieder an
der gleichen Stelle. Ich lasse mir das Z-Register mal ausgeben und
schaue mir mal an, ob da beim Übergang dann Unsinn drinsteht.

MFG Dominik

von Andi K. (Gast)


Lesenswert?

Andere Möglichkeit wäre noch, Dein Code wie gehabt und statt mit "adiw
zl,1" mit
 subi zl,low(-1)
 sbci zh,high(-1)

Oder mit nen anderen Mega16 probieren.

MfG
Andi

von Hartmut Gröger (Gast)


Lesenswert?

Hi

Ich glaube zwar nicht daß das die Lösung ist,aber versuche mal
folgrnden Code:

laden:    lpm r16,Z+       ;Wert laden un Z incrementieren
          out PORTD, r16   ;Wert ausgeben

MfG HG

von Dominik L (Gast)


Lesenswert?

@ Hartmut: Leider nein. Wieder die gleiche Stelle nach der Zahl 12.

Ich habe mir jetzt gerade mal das Z-Register mit ausgeben lassen und
seltsamer Weise ist das in ordnung. Zählt wie es soll nach 0x00FF bei
0x0100 weiter. Nur dass nurnoch 0xFF eingelesen wird anstelle der
Zahlen, die eigentlich dort stehen sollten.
Das würde ja darauf hindeuten, dass mein Programmer die Speicherplätze
nicht ordentlich beschreibt. Wenn ich allerdings Programmcode darüber
schreibe, tauchen diese Probleme ja nicht auf, was wiederum bedeuten
würde, dass die Speicherplätze ja doch ordentlich beschrieben
werden...

MFG Dominik

von A.K. (Gast)


Lesenswert?

Was passiert, wenn die kompletten Daten jenseits von 0xFF liegen? Also
beispielsweise mit ".ORG 0x80".

Du deutest oben an, das dies bei zwei verschiedenen Prozessoren
passiert?

von Dominik L (Gast)


Lesenswert?

@ A.K.:
Die Liste muss in dem Bereich zwischen 0x01 und 0x7F beginnen.
Andernfalls bekomme ich sofort 0xFF als ersten Wert ausgegeben. Der
Programmcode kann irgendwo im Speicher liegen. Das ändert nichts,
solange die Liste nur im richtigen Bereicht liegt. Also genau der
Bereich, wo nur das lower Byte des Z-Registers benötigt wird.

Ich hatte das Problem mit dem mega16 und abe dann zur Kontrolle mal den
mega32 genommen, den ich jetzt immernoch drin habe.

Gruß Dominik

von Andi K. (Gast)


Lesenswert?

Zeig doch mal das List-File nach dem Assemblieren.

MfG
Andi

von Dominik L (Gast)


Lesenswert?

Wo finde ich das List-File denn? Ich hätte die Map- oder die Objektdatei
anzubieten. Das List-File hat doch die Endung .lst oder? Die finde ich
bei mir im Projektordner nämlich nicht. Muss ich dem Compiler sagen,
dass er mir die ausgibt oder nicht wieder löscht?

MFG Dominik

von A.K. (Gast)


Lesenswert?

Kontrolliere mal alle Fuse- und Lockbits. Wirklich alle, auch
diejenigen, die es offiziell garnicht gibt.

Bei welcher Taktfrequenz, intern/extern? Mal andere Taktversorgung
probieren.

Wenn das auch mit der aktuellen Version der STK500 Firmware passiert
(wirst Du wohl oder übel mal probieren müssen), dann bleibt nur Atmel
als Ansprechpartner.

Versuch mal parallele Programmierung. Wird wohl nichts ändern, aber wer
weiss...

von Andi K. (Gast)


Lesenswert?

Im Memü -> Projekt -> Assembler Options "Create Listfile" aktivieren.
Bei der Gelegenheit kannst Du auch den AVR-ASM auf Version 1 oder 2
umstellen (zum Probieren).

MfG
Andi

von Dominik L (Gast)


Lesenswert?

Seltsam. Ich stelle das um, aber jedesmal wenn ich compiliere, werden
die Einstellungen wieder zurückgestellt. Demnach wird auch kein
List-File ausgegeben. bei den Versionen hab ich nur die Auswahl
zwischen 1 und 2. Stellt sich allerdings auch immer wieder auf
2(default) zurück.

von Dominik L (Gast)


Angehängte Dateien:

Lesenswert?

Ok jetzt hab ichs. Die List-Datei ist im Anhang. Version 1 probiere ich
jetzt mal aus.

von Dominik L (Gast)


Lesenswert?

Für alle, die es noch interessiert!
Habe das Problem jetzt gelöst. Ich habe mir mal das alte Studio 3.56
von Atmel besorgt und damit mal mein Hex-File ausgelesen. Und siehe da,
das neue Studio 4.11 hat ab der Adresse 0x7F in Worten den Flash nicht
mehr beschrieben. Wenn ich den AVR jetzt mit dem alten Studio
beschreibe habe ich keine Probleme auch in höhere Speicherbereiche zu
schreiben.
Ich vermute mal, dass das daran liegt, dass ich mein STK500 nicht
upgedatet habe, weil ich damit schon zweimal meinen ISP Programmer
lahmgelegt habe.

MFG Dominik

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.