Step 7 Schieberegister mit 8bit

spezi

Level-1
Beiträge
37
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
'Nabend

Wiedereinmal habe ich ein kleines Problem.
Es geht darum, für eine Förderanlage ein neues Programm zu schreiben.
Hierzu will ich mittels Schieberegister 8 Stellen (jeweils eine einzelne) ansprechen.


Nachfolgend eine Möglichkeit, die ich mir überlegt habe mittels ROL-DW:
Ein vordefinierter Wert wird in das MD16 geschrieben;

Mittels Flankenmerker wird das MD16 gelesen, um eine Stelle weiterrotiert und wiederum ins MD16 geschrieben;

Nun wird 1/4 des MD's, nämlich nur ein MB abgefragt, und ins MB 1 verschoben;

Anschließend wird noch der Sperrmerker gesetzt, damit nicht weitere Bits in das MD16 geschrieben werden;

So weit, so schlecht.
Ich habe nun zwar ein schönes Register, dass durchläuft, jedoch werden durch ROL-DW nicht nur meine 8 benötigten Bits durchrotiert, sondern 32. D.h. 3/4 der Durchlaufzeit vergeht umsonst.

Das ist jetzt zwar kein Problem, weil es sich hier eh um keine kritische Maschine handelt, schön isses aber trotzdem nicht.
Gibt es hier also die Möglichkeit, nur ein einzelnes Byte zu rotieren?

Es ist zwar möglich, nach 8 Schritten bzw. bei erreichen eines bestimmten Merkers das gesamte Register wieder um 8 Stellen oder so zurück (nach rechts) zu schieben, ist aber auch wieder nur mehr Code-Schreiberei.
Andere Möglichkeit: Einen Zähler nochzählen lassen, und den ZW jeweils mit CMP ==I zu vergleichen und danach das entsprechende Bit zu setzen. Nach erreichen von ZW=8 mittels MOVE den Wert "0" ins ZW zu schreiben, bzw. über ein weitere CMP und einem Merker den Zähler rücksetzen.

Das ist alles möglich, jedoch zu aufwändig, daher nochmals zurück zur eigentlichen Frage: Gibt es ein 8bit-Schiebereigster?

Danke und lg
 
Du könntest den Anfangswert des Merkerbytes in alle vier Bytes des Doppelwortes duplizieren.
Das könntest du entweder mit Schieben und mehreren Oder-Verknüpfungen zusammenbauen, oder mit einer 32-Bit Multiplikation mit einer "geeigneten" Konstanten:

Code:
L #Byte_Startmuster
L DW#16#01010101
*D
T MD16
 
Zuviel Werbung?
-> Hier kostenlos registrieren
RotiereLinksByte um 1 Bit

Code:
//-- (A) --
L #ByteVar
PUSH
TAD
OD
RLD 1
T #ByteVar

//-- (B) --
L #ByteVar
PUSH
SRD 8
TAK
RLDA
T #ByteVar

//-- (C) --
L #ByteVar
L B#16#80
UD
TAK
RLDA
T #ByteVar

//-- (D) -- Thomas_v2.1
L #ByteVar
L DW#16#1010101
*D    
RLD 1
T #ByteVar

Harald
 
guten morgen rundherum,

erstmals vielen dank für die brauchbaren antworten ;-)

um der bitte des admin markus nachzukommen, gibts hier ein kleines feedback:

die verwendung des codebeispiels von Thomas v2.1 wurde von mir weiterverwendet weil es sehr kurz gehalten aber trotzdem effizient ist.
das beispiel von PN/DP wird wahrscheinlich auch funktionieren, ist mir aber etwas zu lange.

trotzdem nochmals danke an euch beide für die zeit, die von euch aufgewendet wurde und wird, um den verschiedensten leuten hier im forum zu helfen

DANKE :D
 
Zuviel Werbung?
-> Hier kostenlos registrieren
das beispiel von PN/DP wird wahrscheinlich auch funktionieren, ist mir aber etwas zu lange.
Du hast aber schon registriert, dass das von PN/DP 4 mögliche Lösungsvarianten sind und nicht ein Gesamtcode (die 4. ist die von Thomas)?
Die sind einzeln auch nicht länger!
;)
 
Zuletzt bearbeitet:
zurück zur eigentlichen Frage: Gibt es ein 8bit-Schiebereigster?
Code:
//SchiebeLinksByte um 1 Bit

L #ByteVar
SLD 1
T #ByteVar


Gibt es hier also die Möglichkeit, nur ein einzelnes Byte zu rotieren?

Es ist zwar möglich, nach 8 Schritten bzw. bei erreichen eines bestimmten Merkers das gesamte Register wieder um 8 Stellen oder so zurück (nach rechts) zu schieben, ist aber auch wieder nur mehr Code-Schreiberei.
Du meinst also tatsächlich Rotieren wenn Du Schieben schreibst... oder doch Schieben, aber mit Merken der herausgeschobenen Bits? :confused:


Ich habe nun zwar ein schönes Register, dass durchläuft, jedoch werden durch ROL-DW nicht nur meine 8 benötigten Bits durchrotiert, sondern 32. D.h. 3/4 der Durchlaufzeit vergeht umsonst.
Das ist dem ROL-DW egal, ob er 8 Bit oder 32 Bit um 1, 8 oder 31 Bit rotiert - die Befehlsausführungszeit ist gleich lang.

Harald
 
die verwendung des codebeispiels von Thomas v2.1 wurde von mir weiterverwendet weil es sehr kurz gehalten aber trotzdem effizient ist.
das beispiel von PN/DP wird wahrscheinlich auch funktionieren, ist mir aber etwas zu lange.
Die 3 verschiedenen Beispiele von mir sind jeweils gerade 1 Codezeile länger als das Beispiel von Thomas_v2.1
Was meinst Du mit "effizient"?

Ich glaube eher, Du hast einfach nur das erste Beispiel genommen, weil es zu dem Zeitpunkt noch das Einzige war, als Du die Lösung abgegriffen und Thomas_v2.1 das Danke gegeben hast. Dabei Rotiert oder Schiebt der Code gar nicht..
Ich hatte meine Beispiele erst ca. 10 Minuten danach hier eingestellt. Über diese Beispiele hast Du gar nicht nachgedacht.


Um auf Effizienz zurückzukommen: die macht man wohl weniger an der Länge des Quelltextes fest als an der Programmgröße und Ausführungszeit und Datenspeicherbedarf des compilierten Codes. Und das ist abhängig von der CPU für die der Code compiliert wird.
Was hast Du denn für eine CPU (genaue Bestellnummer)?

Für eine S7-300 compiliert benötigen meine 3 Beispiele jeweils nur 80% des Programmspeicherplatzes den die Multiplikationsvariante benötigt.

Was die Programmausführungszeit auf einer CPU der aktuellen S7-300-Generation betrifft, da gibt es für "alte Hasen" allerdings eine Überraschung! Wie ineffizient ist denn diese Firmware programmiert, wenn ein simples TAK oder OD deutlich länger dauert als eine Festpunkt-Multiplikation *D? Oder ein Schieben/Rotieren nur des AKKUs (SLD/RLD) länger dauert als ein Rotieren durch A1 (RLDA)?

Programmgröße und Ausführungszeit der 4 Varianten auf einer 315-2PN/DP der vorletzten und der aktuellen Generation
Code:
                                     Programmgröße   Ausführungszeit in µs
                                 Codezeilen / Byte   315-1EH13   315-1EH14

Variante A: Rotieren nur AKKU             4 / 8        2.9         0.56
Variante B: Rotieren durch A1             4 / 8        2.5         0.51
Variante C: Rotieren durch A1             4 / 8        2.3         0.46
Variante D: Multiplikation/Thomas_v2.1    3 / 10       5.4         0.37
Die Angaben sind jeweils für den reinen Rotiercode ohne das Laden und Zurückschreiben der #ByteVar.
Die Varianten B und C kann man noch 0.2µs bzw. 0.03µs schneller machen, wenn man TAK durch POP ersetzt.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten morgen in die Runde

da hab ich wieder ein Diskussion losgetreten ;-)

@PN/DP:
Ich will da keinen Streit vom Zaun brechen, natürlich gilt ein großes DANKE auch DIR für deine Beiträge (die mir auch in anderen Forumsbeiträgen schon oft weitergeholfen haben).
Anscheinend hab ich schlampig über deinen Beitrag drübergelesen, nochmals 'tschudligung dafür.

Das ist dem ROL-DW egal, ob er 8 Bit oder 32 Bit um 1, 8 oder 31 Bit rotiert - die Befehlsausführungszeit ist gleich lang.

Hiermit ist nicht die Code-Ausführungszeit in der CPU gemeint sondern folgendes:
Ich habe 8 Stationen, denen ich nacheinander die Freigabe erteile. Das geschieht im Sekundentakt. Mit den Bits 0-7 werden die auch angesprochen, dauert also, nach init, 7 Sekunden. Die Bits 8-31 werden in 24 Sekunden durchlaufen. Das meine ich mit
3/4 der Durchlaufzeit vergeht umsonst
Diese Zeit vergeht also mehr oder weniger sinnlos, da keine der Stationen die Freigabe bekommt. Die Zykluszeit der Steuerung ist mir hier eigentlich komplett wurscht.

@hucki
Du hast aber schon registriert, dass das von PN/DP 4 mögliche Lösungsvarianten sind und nicht ein Gesamtcode (die 4. ist die von Thomas)? Die sind einzeln auch nicht länger!

Jetzt,nachdem ich es nochmals durchgelesen habe, seh ich es auch ;-)



Wie dem auch sei, ich möchte hier niemanden anpissen, ich bin froh, dass es ein Forum wie dieses gibt und dass es so viele Leute gibt, die einen weiterhelfen, sollte es nicht mehr gehen.


Nichts für ungut und danke nochmals für eure Unterstützung und Feedback

Bernd
 
Zurück
Oben