Funktionsbaustein
Level-1
- Beiträge
- 69
- Reaktionspunkte
- 2
Du schreibst "gibt es in TwinCat3 nicht" ... was ist denn "SHL"? SHift Left, also schiebe nach links?die perfekte loesung waere ein 4 bit Schieberegister mit einem seriellen Dateninput und 4 parallelen ausgaenge.
...
aber in twicat 3 gibt es nicht (so ein baustein), soweit ich weiss.
...
in dem ich 4 baustein SHL mit EN/ENO eingebaut habe.
Du schreibst "gibt es in TwinCat3 nicht" ... was ist denn "SHL"? SHift Left, also schiebe nach links?
Was wäre perfekt am 4 Bit SchiebeRegister? Die 4? Spendiere doch einfach ein Byte oder ein Word oder ein Dword mit 8 oder 16 oder 32 Bit!
Die höherwertigen Bits kannst Du ignorieren oder "platt machen" durch VerUNDen mit der Konstante 15.
Warum hast Du "4 Baustein SHL"? Rufst Du SHL an 4 Stellen auf? Begnüge Dich doch mit 1 Aufruf.
Gruss, Heinileini
Bit0 := (Variable UND 1) = 1- ich benutze 4 SHL um die 4 ausgaenge gleichzeitig aufzurufen.
SHL nicht auf einzelne Bits anwenden!was habe ich falsch gemacht?
mit deiner loesung , ist es möglich nach dem vierten Taktimpuls die 1 zu haben, die wir am ersten Taktimpuls eingeschoben haben?SHL nicht auf einzelne Bits anwenden!
Nimm z.B. eine Word-Variable und wende 1-mal den SHL darauf an.
IF Flanke THEN
CASE Variable OF // ich kenne allerdings die Syntax bei Codesys nicht
1: Variable := Variable * 2; // Variable = 2
2: Variable := Variable * 2; // Variable = 4
4: Variable := Variable * 2; // Variable = 8
else: Variable := 1; // bei "8" oder falschem Wert oder wenn initialisiert werden muss: Variable = 1
END_CASE;
END_IF;
IF Flanke THEN
CASE Variable OF // ich kenne allerdings die Syntax bei Codesys nicht
1,2,4: Variable := Variable * 2; // Variable = 2, 4, 8
else: Variable := 1; // bei "8" oder falschem Wert oder wenn initialisiert werden muss: Variable = 1
END_CASE;
END_IF;
Ja, siehe #5:... ist es möglich ...
Bit0 := (Variable UND 1) = 1
Bit1 := (Variable UND 2) = 2
Bit2 := (Variable UND 4) = 4
Bit3 := (Variable UND 8 ) = 8
wobei Variable diejenige ist, die Du als SchiebeRegister benutzt und Bit0 .. Bit3 die 4 Ausgänge.
FUNCTION_BLOCK SIPO4
VAR_INPUT
CLK : BOOL;
IN : BOOL;
END_VAR
VAR_OUTPUT
OUT1 : BOOL;
OUT2 : BOOL;
OUT3 : BOOL;
OUT4 : BOOL;
END_VAR
VAR
register : BYTE := 0; [COLOR="#008000"]//oder WORD[/COLOR]
m : BOOL := FALSE;
END_VAR
IF CLK AND NOT m THEN [COLOR="#008000"]//steigende Flanke[/COLOR]
register := SHL(register, 1) OR [COLOR="#0000FF"]BOOL_TO_BYTE(IN)[/COLOR]; [COLOR="#008000"]//oder BOOL_TO_INT(IN) ? oder SEL(IN, 0, 1)[/COLOR]
END_IF;
m := CLK; [COLOR="#008000"]//Zustand von CLK merken für Flankenerkennung[/COLOR]
OUT1 := register.0;
OUT2 := register.1;
OUT3 := register.2;
OUT4 := register.3;
R_TRIG_CLK
+--------+ +-------+ +------+
| R_TRIG | | SHL | | OR |
CLK-|CLK Q|--------------|EN ENO|--------------|EN ENO|-
+--------+ register-| |--------------| |-register
1-| | +---------| |
+-------+ | +------+
+-------+ |
| [COLOR="#0000FF"]SEL[/COLOR] | |
IN-|G |----+
0-|IN0 |
1-|IN1 | [COLOR="#008000"]("SEL" oder "BOOL TO INT")[/COLOR]
+-------+
+--------+
| MOVE |
register.0-| |-OUT1
+--------+
+--------+
| MOVE |
register.1-| |-OUT2
+--------+
+--------+
| MOVE |
register.2-| |-OUT3
+--------+
+--------+
| MOVE |
register.3-| |-OUT4
+--------+
Sowas formuliere ich lieber so:Bit0 := (Variable UND 1) = 1
Bit1 := (Variable UND 2) = 2
Bit2 := (Variable UND 4) = 4
Bit3 := (Variable UND 8 ) = 8
Bit0 := (Variable UND 1) <> 0 ;
Bit1 := (Variable UND 2) <> 0 ;
Bit2 := (Variable UND 4) <> 0 ;
Bit3 := (Variable UND 8) <> 0 ;
Du könntest einen FB in ST programmieren und den dann in FBD/FUP aufrufen.
Code:FUNCTION_BLOCK SIPO4 VAR_INPUT CLK : BOOL; IN : BOOL; END_VAR VAR_OUTPUT OUT1 : BOOL; OUT2 : BOOL; OUT3 : BOOL; OUT4 : BOOL; END_VAR VAR register : BYTE := 0; [COLOR=#008000]//oder WORD[/COLOR] m : BOOL := FALSE; END_VAR IF CLK AND NOT m THEN [COLOR=#008000]//steigende Flanke[/COLOR] register := SHL(register, 1) OR [COLOR=#0000FF]BOOL_TO_BYTE(IN)[/COLOR]; [COLOR=#008000]//oder BOOL_TO_INT(IN) ? oder SEL(IN, 0, 1)[/COLOR] END_IF; m := CLK; [COLOR=#008000]//Zustand von CLK merken für Flankenerkennung[/COLOR] OUT1 := register.0; OUT2 := register.1; OUT3 := register.2; OUT4 := register.3;
In FBD/FUP kann man das sicher auch programmieren, doch da habe ich keine Ahnung, wie man in Twincat Anweisungen wie ADD/OR/SEL nur bedingt ausführt. Vielleicht so: ?
Code:R_TRIG_CLK +--------+ +-------+ +------+ | R_TRIG | | SHL | | OR | CLK-|CLK Q|--------------|EN ENO|--------------|EN ENO|- +--------+ register-| |--------------| |-register 1-| | +---------| | +-------+ | +------+ +-------+ | | [COLOR=#0000FF]SEL[/COLOR] | | IN-|G |----+ 0-|IN0 | 1-|IN1 | [COLOR=#008000]("SEL" oder "BOOL TO INT")[/COLOR] +-------+ +--------+ | MOVE | register.0-| |-OUT1 +--------+ +--------+ | MOVE | register.1-| |-OUT2 +--------+ +--------+ | MOVE | register.2-| |-OUT3 +--------+ +--------+ | MOVE | register.3-| |-OUT4 +--------+
Harald
was kann ich in dem ST-code aendern ,um mit einer fallende flanke zu arbeiten?Du könntest einen FB in ST programmieren und den dann in FBD/FUP aufrufen.
Code:FUNCTION_BLOCK SIPO4 VAR_INPUT CLK : BOOL; IN : BOOL; END_VAR VAR_OUTPUT OUT1 : BOOL; OUT2 : BOOL; OUT3 : BOOL; OUT4 : BOOL; END_VAR VAR register : BYTE := 0; [COLOR=#008000]//oder WORD[/COLOR] m : BOOL := FALSE; END_VAR IF CLK AND NOT m THEN [COLOR=#008000]//steigende Flanke[/COLOR] register := SHL(register, 1) OR [COLOR=#0000FF]BOOL_TO_BYTE(IN)[/COLOR]; [COLOR=#008000]//oder BOOL_TO_INT(IN) ? oder SEL(IN, 0, 1)[/COLOR] END_IF; m := CLK; [COLOR=#008000]//Zustand von CLK merken für Flankenerkennung[/COLOR] OUT1 := register.0; OUT2 := register.1; OUT3 := register.2; OUT4 := register.3;
In FBD/FUP kann man das sicher auch programmieren, doch da habe ich keine Ahnung, wie man in Twincat Anweisungen wie ADD/OR/SEL nur bedingt ausführt. Vielleicht so: ?
Code:R_TRIG_CLK +--------+ +-------+ +------+ | R_TRIG | | SHL | | OR | CLK-|CLK Q|--------------|EN ENO|--------------|EN ENO|- +--------+ register-| |--------------| |-register 1-| | +---------| | +-------+ | +------+ +-------+ | | [COLOR=#0000FF]SEL[/COLOR] | | IN-|G |----+ 0-|IN0 | 1-|IN1 | [COLOR=#008000]("SEL" oder "BOOL TO INT")[/COLOR] +-------+ +--------+ | MOVE | register.0-| |-OUT1 +--------+ +--------+ | MOVE | register.1-| |-OUT2 +--------+ +--------+ | MOVE | register.2-| |-OUT3 +--------+ +--------+ | MOVE | register.3-| |-OUT4 +--------+
Harald
IF CLK AND NOT m THEN //Schiebetakt steigende Flankewas kann ich in dem ST-code aendern ,um mit einer fallende flanke zu arbeiten?
Das ist sinnvoll für universellere Verwendbarkeit. Dann hat man bestimmt auch bald den Wunsch, das interne 16 Bit Register direkt manipulieren zu können. Man kann dem FB noch etwas mehr Funktionalität geben, dann kann er ein Standard-Baustein werden.ich habe daraus ein 16bit SIPO schieberegister gemacht.
FUNCTION_BLOCK SIPO16 [COLOR="#008000"]//Schieberegister mit parallelen Ausgängen[/COLOR]
VAR_INPUT
CLK : BOOL; [COLOR="#008000"]//Schiebetakt (bei steigender Flanke)[/COLOR]
IN : BOOL; [COLOR="#008000"]//Serial In Bit[/COLOR]
LD : BOOL; [COLOR="#008000"]//Load[/COLOR]
LV : WORD; [COLOR="#008000"]//Load value[/COLOR]
CLR : BOOL; [COLOR="#008000"]//Clear[/COLOR]
END_VAR
VAR_OUTPUT
OUT1 : BOOL;
OUT2 : BOOL;
OUT3 : BOOL;
...
OUT16 : BOOL;
END_VAR
VAR
register : WORD := 0;
m : BOOL := FALSE;
END_VAR
IF CLR THEN [COLOR="#008000"]//Clear[/COLOR]
register := 0;
ELSIF LD THEN [COLOR="#008000"]//Load[/COLOR]
register := LV;
ELSIF CLK AND NOT m THEN [COLOR="#008000"]//Schiebetakt steigende Flanke[/COLOR]
register := SHL(register, 1) OR BOOL_TO_WORD(IN);
END_IF;
m := CLK; [COLOR="#008000"]//Zustand von CLK merken für Flankenerkennung[/COLOR]
OUT1 := register.0;
OUT2 := register.1;
OUT3 := register.2;
...
OUT16 := register.15;
Du hast absolut Recht, Harald!
Sowas formuliere ich lieber so:
Code:Bit0 := (Variable UND 1) <> 0 ; ... Bit3 := (Variable UND 8) <> 0 ;
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?