simples programm: was mach ich falsch ?

Gast #128583
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
Angehängte Dateien:
Gast #128587
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.
Gast #128588
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
Gast #128590
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.
Gast #128593
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.
Gast #128594
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
Gast #128596
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.
Gast #128597
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren