Está en la página 1de 6

Ejemplo de programación de una cola de espera (FIFO) (S7-1200, S7-1500)

Ejemplo de programación de una cola de espera


(FIFO)

Ejemplo de programación
En el siguiente ejemplo se programa un búfer en anillo que se compone de un ARRAY y
se escribe y se lee según el principio FIFO. El código de programa contiene un puntero
VARIANT de lectura y otro de escritura. Mediante las instrucciones VARIANT es posible
programar el código de programa de manera robusta y garantizar una copia o borrado se-
guro.
Con el tipo de datos VARIANT es posible influir en partes del programa durante la ejecu-
ción. El puntero VARIANT es un puntero con seguridad de tipos, es decir, se realiza una
comprobación de tipo durante la ejecución. En el caso de bloques que se han creado con
la propiedad de bloque "Optimizado", las funciones parciales que antes se programaban
con un puntero ANY ahora pueden resolverse con un puntero VARIANT. El tipo de datos
VARIANT se utiliza para transferir estructuras a bloques de función del sistema.

Procedimiento
1. Cree un bloque de función SCL y llámelo "FIFOQueue".
2. Declare la interfaz del bloque de la manera siguiente:

Declaración Parámetro Tipo de datos Comentario

La instrucción se eje-
cuta cuando en el
request BOOL parámetro "request"
se registra un flanco
de señal ascendente.
0 = se devuelve la pri-
mera entrada del bú-
Input fer en anillo.
mode BOOL 1 = se escribe una
entrada en la última
posición del búfer en
anillo.
Valor con el que se
initialValue VARIANT inicializa el ARRAY
del búfer en anillo.
Output error INT Información de error
La entrada que se de-
vuelve del búfer en
item VARIANT
anillo o que se es-
InOut cribe en él.
Un ARRAY que se
buffer VARIANT utiliza como búfer en
anillo.
Marca de flancos en
la que se almacena el
Static edgeupm BOOL
RLO de la consulta
anterior.

-1-
Ejemplo de programación de una cola de espera (FIFO) (S7-1200, S7-1500)

Índice de la entrada
firstItemIndex INT más antigua del búfer
en anillo
Índice del siguiente
nextEmptyIte-
INT elemento libre en el
mIndex
búfer en anillo
Resultado de la eval-
edgeup BOOL
uación de flancos
internalError INT Información de error
newFirstItemIn-
INT Índice variable
dex
Temp
newNextEmp-
INT Índice variable
tyItemIndex
Número de elemen-
bufferSize UDINT tos ARRAY en el bú-
fer en anillo
3. En el bloque de función "FIFOQueue", cree el siguiente código de programa:

(* Esta sección del código del programa solo se ejecu-


ta una vez tras un flanco de señal ascendente. Si el
estado del resultado lógico no cambia, la ejecución
del programa del FB "FIFOQueue" finaliza. *)
#edgeup := #request & NOT #edgeupm;
#edgeupm := #request;
IF NOT (#edgeup) THEN
RETURN;
END_IF;

// ------Validación de si todas las entradas de pará-


metro son válidas.----
(* Esta sección del código del programa comprueba si
el búfer en anillo es un ARRAY. En caso afirmativo, se
lee el número de elementos del ARRAY. Si no se trata
de un ARRAY, la ejecución del programa se interrumpe
en este punto y se devuelve el código de error "-10".
*)
IF NOT (IS_ARRAY(#buffer)) THEN
#error := -10;
RETURN;
ELSE
#bufferSize := CountofElements(#buffer);
END_IF;

(* Esta sección del código del programa comprueba si


el tipo de datos de los elementos ARRAY coincide con

-2-
Ejemplo de programación de una cola de espera (FIFO) (S7-1200, S7-1500)

el tipo de datos de la entrada (variable #item). Si


los tipos de datos no coinciden, la ejecución del pro-
grama se interrumpe en este punto y se devuelve el có-
digo de error "-11". *)
IF NOT (TypeOf(#item) = TypeOfElements(#buffer)) THEN
#error := -11;
RETURN;
END_IF;

(* Esta sección del código del programa comprueba si


el valor inicial del búfer en anillo coincide con la
entrada (variable #item). Si los tipos de datos no co-
inciden, la ejecución del programa se interrumpe en
este punto y se devuelve el código de error "-12". *)
IF NOT (TypeOf(#item) = TypeOf(#initialValue)) THEN
#error := -12;
RETURN;
END_IF;

(* Esta sección del código del programa comprueba si


los índices variables se encuentran dentro de los lím-
ites ARRAY. Si no es así, la ejecución del programa se
interrumpe en este punto y por cada índice se devuelv-
en los códigos de error "-20" o "-21". *)
IF (#nextEmptyItemIndex >= #bufferSize) THEN
#error := -20;
RETURN;
END_IF;
IF (#firstItemIndex >= #bufferSize) THEN
#error := -21;
RETURN;
END_IF;

//-----------Ejecución del código del programa en fun-


ción del parámetro Mode-------------
// La ejecución de las instrucciones depende del esta-
do lógico del parámetro Mode.
IF #mode = 0 THEN

// Si el parámetro Mode presenta el estado lógico "0",


se devuelve la primera entrada del búfer en anillo
transferido.
(* Esta sección del código del programa comprueba si
el búfer en anillo está vacío. En caso afirmativo, la
ejecución del programa se interrumpe en este punto y
se devuelve el código de error "-40". *)
IF (#firstItemIndex = -1) THEN

-3-
Ejemplo de programación de una cola de espera (FIFO) (S7-1200, S7-1500)

#error := -40;
RETURN;
END_IF;

// Esta sección del código del programa devuelve la


primera entrada del búfer en anillo.
#internalError := MOVE_BLK_VARIANT(SRC := #buffer,
COUNT := 1,
SRC_INDEX :=
#firstItemIndex,
DEST_INDEX := 0,
DEST => #item);

IF (#internalError = 0) THEN
(* Esta sección del código del programa comprueba si
el búfer en anillo contiene elementos de ARRAY. En ca-
so afirmativo, se desplaza la primera entrada y el ín-
dice se incrementa en 1. *)
#internalError := MOVE_BLK_VARIANT(SRC := #ini-
tialValue,
COUNT := 1,
SRC_INDEX :=
0,
DEST_INDEX :=
#firstItemIndex,
DEST =>
#buffer);

// Esta sección del código del programa calcula el


nuevo índice de la primera entrada.
#newFirstItemIndex := #firstItemIndex +1;
#newFirstItemIndex := #newFirstItemIndex MOD
UDINT_TO_INT(#bufferSize);

// Esta sección del código del programa comprueba si


el búfer en anillo está vacío.
IF (#nextEmptyItemIndex = #newFirstItemIndex)
THEN
// Si el búfer en anillo está vacío, el índice se pone
a 0.
#firstItemIndex := -1;
#nextEmptyItemIndex := 0;
ELSE
// El índice de la primera entrada se modifica.
#firstItemIndex := #newFirstItemIndex;
END_IF;
END_IF;

-4-
Ejemplo de programación de una cola de espera (FIFO) (S7-1200, S7-1500)

ELSE

// Si el parámetro Mode presenta el estado lógico "1",


la entrada se escribe en el búfer en anillo transferi-
do.
(* Esta sección del código del programa comprueba si
el búfer en anillo está lleno. En caso afirmativo, la
ejecución del programa se interrumpe en este punto y
se devuelve el código de error "-50". *)
IF (#nextEmptyItemIndex = #firstItemIndex) THEN
#error := -50;
RETURN;
END_IF;

// Esta sección del código del programa escribe la en-


trada en el búfer en anillo.
#internalError := MOVE_BLK_VARIANT(SRC := #item,
COUNT := 1,
SRC_INDEX := 0,
DEST_INDEX :=
#nextEmptyItemIndex,
DEST => #buf-
fer);

IF (#internalError = 0) THEN
// Esta sección del código del programa incrementa el
índice en 1 y calcula el nuevo índice de entrada vac-
ío.
#newNextEmptyItemIndex := #nextEmptyItemIndex
+1;
#newNextEmptyItemIndex := #newNextEmptyItemIndex
MOD #bufferSize;
#nextEmptyItemIndex := #newNextEmptyItemIndex;

(* Esta sección del código del programa comprueba qué


índice tiene la variable "#firstItemIndex". Si el nú-
mero = -1, el búfer en anillo se ha inicializado y la
entrada se escribe en el búfer en anillo. Por ello hay
que asignar "0" a la variable. *)
IF (#firstItemIndex = -1) THEN
#firstItemIndex := 0;
END_IF;
END_IF;
END_IF;

//-------------------------Tratamiento local de er-


rores----------------------------

-5-
Ejemplo de programación de una cola de espera (FIFO) (S7-1200, S7-1500)

(* Esta sección del código del programa comprueba si


se ha producido un error local. En caso afirmativo, el
programa se interrumpe en este punto y se devuelve el
código de error "-100". *)
IF (#internalError > 0) THEN
#error := -100;
RETURN;
END_IF;

// Si no se ha producido ningún error durante la eje-


cución del programa, se devuelve el código de error
"0".
#error := 0;

Resultado
Llame al bloque de función SCL en el lugar del programa donde deba ejecutarse la cola de
espera FIFO.

-6-

También podría gustarte