www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik simples programm: was mach ich falsch ?


Autor: Simon (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Steffen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Christof Krüger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Steffen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich nahm an, dass das nur zu Testzwecken drin war.

Das erste ret muss natürlich auch raus!

Autor: Wolle (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wolle: kannst du den code bitte ein bisschen beschreiben ??

Autor: Christof Krüger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Steffen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: Christof Krüger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
korrektur, 1.Satz:

...passt also nicht mehr in 8 BITS.

Autor: Wolle (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Christof Krüger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Wolle (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Joachim Schäfer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.