Forum: Mikrocontroller und Digitale Elektronik Assembler INC


von Pierre G. (bqube)


Lesenswert?

Servus ihr,

Und zwar hab ich schon ein paar Programme mit Assembler geschrieben, die 
auch so Funktionierten aber es scheitert grad an der eigenen Include 
datei.

Ich hab einfach ein kleines Programm zum Testen geschrieben.

.include "m8def.inc"
.include "D:\AVR_Programme\Text\wait.asm"

         ldi r16, 0xFF
         out DDRB, r16
         A:
         ldi r16, 0xFF
         out PORTB, r16
         RJMP Warte0

         ldi r16, 0x00
         out PORTB, r16
   RJMP Warte0
   RJMP A

ende:    rjmp ende

Meine wait.asm datei sieht so aus

Warte0:
LDI     R16,2
Warte1:
DEC     R16
BRNE   Warte1

Nun meine Frage wenn ich das ganze teste bleibt der Kontroller in der 
Warteschleife hängen und kommt da nicht mehr so wirklich raus warum?
muss ich noch was bedenken.

Die idee war das ich nicht immer den ganzen text hab der schleife 
sondern so meine Programme kürzer bekomme dur eigenen Include datein.

Danke schonmal

Mfg Bqube

von Spess53 (Gast)


Lesenswert?

Hi

>BRNE   Warte1

Und wie geht es danach weiter?

MfG Spess

von hmmmmmmm (Gast)


Lesenswert?

Spess53 schrieb:
> Und wie geht es danach weiter?

         ldi r16, 0xFF
         out DDRB, r16
...

aber dafür ist ein include eigentlich nicht da.

von Pierre G. (bqube)


Lesenswert?

Ich hatte mir das so gedacht oder eher gesagt so verstanden das er ab 
dem Punkt Warten0 die Warteschleife anfängt und dann einfach das 
Programm Weiter seinen weg geht.

Also

ldi r16, 0xFF
out DDRB, r16
A:
ldi r16, 0xFF
out PORTB, r16
RJMP Warte0
ldi r16, 0x00        <----- Hier
out PORTB, r16
RJMP Warte0
RJMP A

Wenn RJMP Warte0 kommt dachte ich das er dann einfach seine schleife 
wartet und dann bei LDI R16, 0x00 weiter macht?

Bqube

von Spess53 (Gast)


Lesenswert?

Hi

>         ldi r16, 0xFF
>         out DDRB, r16
>...

>aber dafür ist ein include eigentlich nicht da.

Da bist du auf dem Holzweg. Mit 'include' hat das überhaupt nichts zu 
tun. Ich vermute du meinst 'rcall' oder 'call', also einen 
Unterprogrammaufruf.

Der benutzt aber, wie gesagt, 'call' oder 'rcall' zum Aufruf. Und das 
Unterprogramm muss mit 'ret' beendet werden. Also:
1
         out PORTB, r16
2
         RCALL Warte0
3
         ldi r16, 0x00
4
...
5
6
Warte0: LDI     R16,2
7
Warte1: DEC     R16
8
        BRNE   Warte1
9
        ret

MfG Spess

von Pierre G. (bqube)


Lesenswert?

Danke Spess

Darann hab ich garnicht gedacht, es geht darum ich hab eine Routine 
geschrieben (wenn man das so richtig nennt) die 8Bit Seriell an ein 
anderes Modul schickt. Z.b ich hab eine 4*8 Tastatur (mit einem Atmega8) 
die ihre Daten dann Seriell an die CPU (atmega32) schicken soll.

Da es schon eine gewisse menge an Assembler Code ist will ich sie net 
immer komplett in mein Hauptprogramm reinpacken.

DAmit ich das richtig verstanden habe ich kann den Code zum schieben in 
einer include datei haben und dann mit dem rcall befehl anwenden oder 
muss der code an einer bestimmten stelle stehen ?

Mfg Bqube

von hmmmmmmm (Gast)


Lesenswert?

Spess53 schrieb:
> Da bist du auf dem Holzweg. Mit 'include' hat das überhaupt nichts zu
> tun. Ich vermute du meinst 'rcall' oder 'call', also einen
> Unterprogrammaufruf.

Welchen Beitrag meinst du? Ich habe hier keinen call finden können.
Der OT wollte den Text einfach reinkopieren, das macht include ja auch. 
Aber der Sinn eines include ist natürlich ein anderer, schrieb ich ja 
schon.

von Spess53 (Gast)


Lesenswert?

Hi

Eine '.include'-Directive ist eine einfache Textersetzung. Wenn du also

     .include "xyz.inc"

an eine Stelle in dein Programm schreibst, assembliert der Assembler an 
dieser Stelle das, was in xyz.inc steht. Danach macht er mit deinem 
Programm weiter.

MfG Spess

von hmmmmmmm (Gast)


Lesenswert?

Spess53 schrieb:
> Eine '.include'-Directive ist eine einfache Textersetzung. Wenn du also
>
>      .include "xyz.inc"
>
> an eine Stelle in dein Programm schreibst, assembliert der Assembler an
> dieser Stelle das, was in xyz.inc steht. Danach macht er mit deinem
> Programm weiter.

Schön erkannt Spess, dass schreib ich doch hier die ganze Zeit! Bist 
'nen Schnellmerker, gelle ;-)

von Pierre G. (bqube)


Lesenswert?

Hab das so geschrieben .include "m8def.inc"
.DEF REG1 = R16
.DEF REG2 = R17

;Main

A:
ldi R18, HIGH(RAMEND)
out SPH, R18
ldi R18, LOW(RAMEND)
out SPL, R18

LDI REG1, 0xFF
OUT DDRB, REG1

LDI REG2, 0xFF
OUT PORTB,REG2
RCALL UPRO1

LDI REG2, 0x00
OUT PORTB,REG2
RCALL UPRO1

RJMP A


;Unteprogramme

UPRO1:
LDI     R16,20
Warte1:
DEC     R16
BRNE   Warte1
RET

Muss man für die Unterprogramme immer der Stackpointer initialisiert 
werden.

Mfg Bqube

von hmmmmmmm (Gast)


Lesenswert?

Pierre Gnauck schrieb:
> Muss man für die Unterprogramme immer der Stackpointer initialisiert
> werden.

Woher kommt die Rücksprungadresse nach dem RET?

Schau mal unter 
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Stack

von Steffen (Gast)


Lesenswert?

Den Stackpointer brauchst du nur am Beginn deines Programms zu laden 
(initialisieren). Nicht immer vor jedem Unterprogrammaufruf.

Also das reicht:

.include "m8def.inc"
.DEF REG1 = R16
.DEF REG2 = R17

;Main

Init:  ; Stackpointer initialisieren
ldi R18, HIGH(RAMEND)
out SPH, R18
ldi R18, LOW(RAMEND)
out SPL, R18

A:
LDI REG1, 0xFF
OUT DDRB, REG1

LDI REG2, 0xFF
OUT PORTB,REG2
RCALL UPRO1

LDI REG2, 0x00
OUT PORTB,REG2
RCALL UPRO1

RJMP A


;Unteprogramme

UPRO1:
LDI     R16,20
Warte1:
DEC     R16
BRNE   Warte1
RET

von Spess53 (Gast)


Lesenswert?

Hi

>Muss man für die Unterprogramme immer den Stackpointer initialisiert
>werden.

Ja.

MfG Spess

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
Noch kein Account? Hier anmelden.