Hi ! ich hab mal ein simples programm geschrieben das eine led an port a zum blinken bringen soll ! (anfang) Aber leider funktioniert es nicht. wenn ich die subroutine rausmache und stadessen des calls einfüge funktioniert es. MfG Simon
Du musst den Stackpointer initialisieren. Sonst kommt dein Code beim ret nicht mehr zurck (weil er die Rücksprungadresse nicht hat). Viele Grüße Steffen
Ganz davon abgesehen hast du beim Label "delay" gleich schon ein ret... so wirst du kaum was vom Blinken mitbekommen, da die Warteschleifen gar nicht abgearbeitet werden.
Ich nahm an, dass das nur zu Testzwecken drin war. Das erste ret muss natürlich auch raus!
Füge mal diese Zeilen am Anfang ein : .CSEG .ORG $0000 ; ; Reset- und Interrupt-Vektoren ; rjmp Start ; Reset-vector ; Start: ldi tmp1, LOW(RAMEND) ; LOW-Byte der obersten RAM-Adresse out SPL, tmp1 ldi tmp1, HIGH(RAMEND); HIGH-Byte der obersten RAM-Adresse out SPH, tmp1 Für "tmp1" kannst du ein Register deiner Wahl einsetzen. Ist der Übliche Beginn eines Programms.
ja des is nur zu testzwecken drin (hab breakpoints gesetzt und so gings halt schneller) Steffen: so ? .def temp = r21 ldi r21, RAMEND ;Stackpointer initialisieren out SPL, r21 dann bringt er immer ne warnung: Immediate byte operand out of range MFG Simon
Wolle: kannst du den code bitte ein bisschen beschreiben ??
RAMEND ist größer als 255, passt also nicht mehr in 8 Bytes. Daher ist der Stackpointer bei AVR's mit mehr als 256Byte Speicher auch in zwei 8-Bit grosse Register aufgespalten: SPH (stack pointer high) und SPL (stack pointer low). Man muss also beide Register nacheinader mit den richtigen Bits laden. low(RAMEND) gibt hierbei die unteren 8 bits zurück und high(RAMEND) entsprechend die oberen 8.
@Simon: nehm den Code von Wolle. Der Mega16 hat einen 16 bit Stackpointer. Da musst du sowohl das High Byte als auch das Lowbyte initialisieren. Viele Grüße Steffen
Jenau, RAMEND ist in der *.def-Datei für jeden Prozessor schon so definiert, mit dem Namen. Deswegen ist es für alle gültig, selbst für die, die keinen Stack (Stapel) mit mehr als 255 Bytes haben. Bei denen wird das high(RAMEND) ignoriert.
Danke für eure antworten Des mit den high und low registern hab ich verstanden (is ja wie beim pc EAX = EAL + EAH (oder so ähnlich wars)) aber was passier überhaupt beim initialisieren der stackpionters ?? und was machen die befehle .CSEG .ORG $0000 sin des so ne art coprozessor befehle ? MfG
Schau mal in die Online-Hilfe-Datei vom AVR Studio. Da gibts unter Inhalt den Punkt "AVR Assembler" und dort den "User's Guide", wo die Instructions und Directives aufgelistet sind.
Das sind Assembler-Anweisungen. .cseg = Codesegment .org $0000 = Beginn bei Adresse 0, also gaaaanz vorne. Damit "weiß" der Assembler, wo sich das Ganze abspielt und wie er dann folgende Adressen für den Code berechnen muß. Soviel "Grundlagen für Einsteiger", läßt sich aber auch irgendwo nachlesen, glaub' ich.
Abgesehen von der Sache mit dem Stackpointer solltest Du auch das über das DDR-Register Port A als Ausgang definieren, also ldi r16, 0xFF out DDRA, r16 an den Anfang. Falls die Ports standardmässig als Ausgaberegister definiert sind dann mag es auch ohne das gehen, aber schon alleine zur Sicherheit solltest Du das einbauen.
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.