Forum: Mikrocontroller und Digitale Elektronik ASM Code vereinfachen


von pacer (Gast)


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

von spess53 (Gast)


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

von Guter Rat (Gast)


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!

von Uwe (Gast)


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

von spess53 (Gast)


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

von pacer (Gast)


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.

von Peter D. (peda)


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

von spess53 (Gast)


Lesenswert?

Hi

>Ich habe damals auch nicht schlecht gestaunt, als mein Programm nach dem
>Umschreiben auf C kleiner war, als vorher das Assemblerprogramm.

Lag das am Assembler- oder am C-Programm?

MfG Spess

von Peter D. (peda)


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

von spess53 (Gast)


Lesenswert?

Hi

>Am Assembler, als ich mit dem 8051 anfing.

Und was hat das jetzt mit aktuellen AVR-Assemblern/Compiler zu tun?

MfG Spess

von Peter D. (peda)


Lesenswert?

spess53 schrieb:
> Und was hat das jetzt mit aktuellen AVR-Assemblern/Compiler zu tun?

Hab ich doch oben schon gesagt, Scratchpadregister vereinbaren.
Es erleichtert das Programmieren und verringert den Code.


Peter

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.