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.
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 |
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.
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.
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.
Lies doch mal das Flash wieder aus und schau was drin steht. Am Ende steht da jenseits der ersten 256 Bytes garnichts drin...
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
Und wie sieht es mit "lpm r0,z+" und ohne "adiw zl,1" aus? MfG Andi
@ 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
Zeig doch mal das List-File nach dem Assemblieren. MfG Andi
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.
Ok jetzt hab ichs. Die List-Datei ist im Anhang. Version 1 probiere ich jetzt mal aus.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.