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

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.