ASM Code vereinfachen

Gast #1615381
Lesenswert?

Hallo,
ich benötige für ein GLCD zwei verschiedene Statusabfragen.
Diese sind ziemlich gleich aufgebaut.
1
 StatusCheck:
2
  clr temp1
3
  out DDRD, temp1      ; Datenport als Eingang für Statusantwort des Displays  
4
  cbi PortB, CE        ; Display enable
5
  
6
    _status_check_0:
7
    cbi  PortB, RD          ; Leseanforderung 
8
    in   temp1, PinD          ; Daten vom Display kommend einlesen
9
    sbi  PortB, RD          ; Leseanforderung beenden
10
    andi temp1,(1<<STA0)+(1<<STA1)    ; Statusbyte maskieren
11
    cpi  temp1,(1<<STA0)+(1<<STA1)    ; Püfen ob Bits Bits STA0 und STA1 gesetzt sind
12
  brne _status_check_0        ; warte auf sta0 und sta1 =1
13

14
   sbi  PortB, CE      ; Display disable
15
   ser temp1        ; Datenport als Ausgang  
16
   out DDRD, temp1        
17
 ret
1
AutoStatusCheck:
2
  clr temp1
3
  out DDRD, temp1      ; Datenport als Eingang für Statusantwort des Displays  
4
  cbi PortB, CE        ; Display enable
5
  
6
    _status_check_1:
7
    cbi  PortB, RD          ; Leseanforderung 
8
    in   temp1, PinD          ; Daten vom Display kommend einlesen
9
    sbi  PortB, RD          ; Leseanforderung beenden
10
    andi temp1,(1<<STA3)    ; Statusbyte maskieren
11
    cpi  temp1,(1<<STA3)    ; Püfen ob Bits Bits STA0 und STA1 gesetzt sind
12
  brne _status_check_1        ; warte auf sta0 und sta1 =1
13
  
14
   sbi  PortB, CE      ; Display disable
15
   ser temp1        ; Datenport als Ausgang  
16
   out DDRD, temp1        
17
ret

kann man irgendetwas vereinfachen, ohne die Unterprogramme ineinander zu 
verschachteln oder dort neue Unterprogramme einzubauen?
Ich möchte wenn es geht nur ein Unterprogramm für beide Fälle 
verwenden,dafür aber mit Parameterübergabe. Es muss halt übersichtlich 
bleiben.
Was mir dazu einfällt wären Macros, aber da weiß ich nicht genau wie.

Hat jemand eine Idee?

vielen Dank
Gast #1615392
Lesenswert?

Hi

Übergib doch einfach die Maske in einem Register.

->    and temp1,Register    ; Statusbyte maskieren
->    cp  temp1,Register    ; Püfen ob Bits Bits STA0 und STA1 gesetzt 
sind

Aufruf:

   ldi Register,(1<<STA0)+(1<<STA1) oder (1<<STA3)
   rcall StatusCheck

MfG Spess
Gast #1615396
Lesenswert?

Ich würde so vorgehen:

1. Die Variable (einmal (1<<STA0)+(1<<STA1) und einmal STA3
in ein eigenes Register vor dem UP-Call laden und dann
mit diesem Register statt temp1 arbeiten.

2. Temp1 VOR dem UP-Aufruf entsprechend laden.

  push temp1           ; damit temp1 sichern

  clr temp1
  out DDRD, temp1      ; Datenport als Eingang für Statusantwort des 
Displays
  cbi PortB, CE        ; Display enable

  pop temp1            ; und wieder zurückholen

Vorschlag 2 braucht nur ein zusätzliches Push-pop, nicht mal ein 
Register!

Einen schönen Sonntag!
Gast #1615720
Lesenswert?

Hi!
> brne _status_check_0        ; warte auf sta0 und sta1 =1
Da ist hoffentlich irgendwo ein Timeout verbaut, nicht das du dich mal 
wunderst wenn nichts losgeht(unmögliches ist immer möglich)
Ansonsten würde ich es wie "spess53" machen.

Viel Erfolg, Uwe
Gast #1615820
Lesenswert?

Hi

>Da ist hoffentlich irgendwo ein Timeout verbaut, nicht das du dich mal
>wunderst wenn nichts losgeht(unmögliches ist immer möglich)

Läuft bei mir seit über 10 Jahren und mehr als 500 Displays in dieser 
Art problemlos.

MfG Spess
Gast #1615995
Lesenswert?

Vorschlag 2 wird wohl nicht funktionieren, da ich ja den Portinhalt für 
den Vergleich in ein Register laden muss. Somit bräuchte ich auf jeden 
Fall zwei Register.
Eigentlich wollte ich durch Verwendung eines Macros um ein zweites 
Register herum kommen.
#1616043
Lesenswert?

pacer schrieb:
> Eigentlich wollte ich durch Verwendung eines Macros um ein zweites
> Register herum kommen.

Für ungenutzte Register gibts von Atmel kein Geld zurück.

Definiere Dir 4..8 zerstörbare Arbeitsregister, d.h. die müssen nicht 
per push/pop gesichert werden und jede Funktion darf sie nutzen.
Vorzugsweise sind das auch die Register, die als Funktionsargumente und 
Returnwerte definiert sind.

Man kann sich ne Menge Programmiertricks vom C-Compiler abgucken.
Ich habe damals auch nicht schlecht gestaunt, als mein Programm nach dem 
Umschreiben auf C kleiner war, als vorher das Assemblerprogramm.


Peter
#1616093
Lesenswert?

spess53 schrieb:
> Lag das am Assembler- oder am C-Programm?

Am Assembler, als ich mit dem 8051 anfing.
Wenn man die Technik der Scratchpad-Register nicht kennt, pusht/popt man 
wie blöde, das ja alle Register erhalten bleiben.
Und es war auch Spaghetticode (wenig Unterfunktionen, riesige 
Umherspringerei).


Peter

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