Forum: Mikrocontroller und Digitale Elektronik Ansteuerung EA DOGS 102-64, asm-schleife hängt


von Bernd (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Forum,

nachdem mein LCD Display (EA DOGS 102-64)jetzt mit mir "redet" hab ich 
auch gleich ein neues Problem mit der Routine die mir den Inhalt der 
Anzeige löscht:

Die Anzeige wird zwar vollständig gelöscht, aber am Ende der Routine 
wird nicht zurück in den normalen Ablauf gesprungen, sondern die Anzeige 
aus und wieder eingeschaltet und die Routine läuft erneut ab....und ich 
kann nicht erkennen wieso.
1
Loesche_Anzeige:
2
   
3
   ;Register benennen
4
   .def Zeile         = r21
5
   .def Spalte_LSB    = r19
6
   .def Spalte_MSB    = r22
7
   .def Display_Daten = r18
8
   
9
   ;Startwerte setzen
10
   ldi temp,0b10110000        ;Startwert für Zeile
11
   mov Zeile,temp        ;ins Register Zeile
12
13
   ldi temp,0b00000000        ;Startwert für Spalte_LSB
14
   mov Spalte_LSB,temp        ;ins Register Spalte_LSB
15
16
   ldi temp,0b00010000        ;Startwert für Spalte_MSB
17
   mov Spalte_MSB,temp        ;ins Register für Spalte MSB
18
19
   ldi Display_Daten, 0b00000000     ;Wert für Bildschirm ohne Inhalt
20
21
   
22
Ausfuehrung:
23
   mov SPI_Code,Spalte_LSB
24
   rcall SPI_sende_Kommando
25
26
   mov SPI_Code,Spalte_MSB
27
   rcall SPI_sende_Kommando
28
29
   mov SPI_Code, Zeile
30
   rcall SPI_sende_Kommando
31
32
   mov SPI_Code,Display_Daten
33
   rcall SPI_sende_Daten
34
   
35
   inc Spalte_LSB
36
   cpi Spalte_LSB,0b00010000
37
   breq inc_Spalte_MSB
38
   rcall Ausfuehrung
39
40
inc_Spalte_MSB:
41
   ldi Spalte_LSB,0b00000000
42
   inc Spalte_MSB
43
   cpi Spalte_MSB,0b00011000
44
   breq neue_Zeile
45
   rcall Ausfuehrung
46
47
neue_Zeile:
48
   ldi Spalte_LSB,0b00000000
49
   ldi Spalte_MSB,0b00010000
50
   inc Zeile
51
   cpi Zeile,0b10111000
52
   breq Ende_Ausfuehrung
53
   rcall Ausfuehrung
54
55
Ende_Ausfuehrung:
56
   ret
57
   ;rcall Testtext
58
   ;rcall Schleife

hier die Lösch-Routine, gesamten file im Anhang

Gruß Bernd

von S. Landolt (Gast)


Lesenswert?

Dieses "rcall Ausfuehrung" an drei Stellen - soll da wirklich etwas 
rekursiv ablaufen oder muss das "rjmp " heißen?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

S. Landolt schrieb:
> Dieses "rcall Ausfuehrung" an drei Stellen
Damit ist der Stack aber echt schnell gefüllt. Und auch der Rest des 
RAMs...

von Peter D. (peda)


Lesenswert?

Bernd schrieb:
> Ausfuehrung:
> ...
>    rcall Ausfuehrung

Da läuft der Stack über.
Rekursionen mag ich in C schon nicht, in Assembler erst recht.

von Bernd (Gast)


Lesenswert?

lieben Dank für eure Antworten,

worin unterscheiden sich denn rcall und rjmp?

Und wann muss ich was verwenden?

In der Beschreibung des Tutorials kann ich hier als Anfänger nicht 
wirklich einen Unterschied erkennen.

Gruß Bernd

von Route_66 H. (route_66)


Lesenswert?

Hallo!
Bei RCALL merkt er sich im Stack, woher er kam und kehrt bei RET genau 
dorthin zurück (wenn du den Stack nicht versaust).
Bei RJMP merkt er sich überhaupt nichts.

von Bernd (Gast)


Lesenswert?

vielen Dank für die Erklärung!

habe jetzt an den Stellen, an denen kein Rücksprung notwendig ist rcall 
durch rjmp ersetzt - und damit funktioniert es :-)

muss dann nicht bei den Interrupt-Routinen auch rcall verwendet werden?
in vielen Beispielen liest man an dieser Stell nämlich rjmp.

Gruß Bernd

von Route_66 H. (route_66)


Lesenswert?

Bernd schrieb:
> bei den Interrupt-Routinen

Der Interrupt selbst macht den RCALL - d.h. merkt sich, wo der µC 
gerade gearbeitet hat und bei RETI macht er dann dort weiter.
Die RJMPs in der INT-Sprungtabelle sind nur "Verlängerungen" zur 
eigentlichen INT-Routine.

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.