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
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.
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
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
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.
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
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?
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
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
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
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.
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.
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
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.
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.
: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?
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
@ 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
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
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
@ 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
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?
@ 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
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
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...
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
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.
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