Académique Documents
Professionnel Documents
Culture Documents
OB 1 FB1 FB5
Motor 1 Regulador en
Motor 1 Regulador
lazo cerradoen
lazo cerrado . . .
FB1 FC10
Valor_medido ARRAY[1..20]
REAL
Motor 2 Suma REAL
Motor 2 Valor_medioREAL . . .
L P##Valor_medido
LAR1
FB2 L W [AR1,P#0.0]
T #Num_DB
OPN DB[Num_DB]
L D [AR1,P#2.0]
LAR1
Isla de válvulas .
Isla de válvulas . . . .
.
.
Contenido Página
Llamada a Función con Tipos de Datos Compuestos ……………..................................................... 2
Paso de Parámetros para Tipos de Datos Compuestos ………........................................................ 3
Acceso Indirecto a Tipos de Datos Compuestos ……………............................................................ 4
Paso de Parámetros para Punteros …............................................................................................... 5
Paso de Parámetros para los Tipos de Parámetros ........................................................................... 6
Características Especiales para Parámetros Actuales Elementales en DBs y Constantes .............. 7
Ejercicio A7.1: Evaluar el Parámetro Date-and-Time en una FC ....................................................... 8
Llamada a FB con Tipos de Datos Compuestos ……………............................................................. 9
Acceso Indirecto a Parámetros de Entrada/Salida ............................................................................ 10
Acceso Indirecto a Parámetros In/Out ……….................................................................................. 11
”Pasando" Parámetros …….....…..................................................................................................... 12
Ejercicio A7.2: Evaluar el Parámetro Date-and-Time en un FB .................................................... 13
Ejercicio A7.3: Evaluar Parámetros In/Out en un FB ……............................................................ 14
Solución al Ejercicio A7.1: Acceso a Parámetros DT en una FC ........................................................ 15
Solución al Ejercicio A7.2: Acceso a Parámetros DT en un FB ...................................................... 16
Solución al Ejercicio A7.3: Acceso a Parámetros In/Out en un FB (Parte 1) .................................. 17
Solución al Ejercicio A7.3: Acceso a Parámetros In/Out en un FB (Parte 2) .................................. 18
DB5 "Temperatura"
CALL FC 21
Valores_medidos:="Temperatura".secuencia
Visión General Los parámetros del tipo de datos compuestos (ARRAY y STRUCT) ofrecen un
modo claro y eficiente para transferir grandes cantidades de datos relacionales
entre el bloque llamante y el llamado y así acomodar el concepto de
“Programación Estructurada”.
Se puede pasar una matriz o una estructura a una función llamada como una
variable completa.
Asignar los Para el paso, se debe declarar en la función llamada un parámetro del mismo
Parámetros tipo de datos que el parámetro actual que se debe pasar. Un parámetro como
este (tipo de dato: ARRAY, STRUCT, DATE_AND_TIME y STRING) sólo puede
ser asignado simbólicamente.
Ya que las variables del tipo de datos compuesto sólo pueden crearse en
bloques de datos o en pilas de datos locales, el parámetro actual debe estar
situado en un bloque de datos (global o DB de instancia) o en la pila de datos
locales del bloque llamante.
Después de que el Editor KOP/AWL/FUP ha comprobado la compatibilidad de
los tipos de datos del parámetro actual y el parámetro de bloque en el paso de
parámetros a una FC, sólo se pasa a la FC llamada un puntero POINTER con
el número de DB y un puntero interárea al parámetro actual.
Este puntero POINTER se crea en la Pila L Stack del bloque llamante (área V)
mediante la macro CALL. Este puntero POINTER es entonces de gran
importancia para el programador, en particular cuando se debe acceder al
parámetro pasado indirectamente (ver apéndice).
...
Paso de Parámetros Con los tipos de datos compuestos (DT, STRING, ARRAY, STRUCT y UDT) los
parámetros actuales residen en un bloque de datos o en la pila L Stack del
bloque llamante (área V).
Ya que un puntero interárea de 32-bit no puede alcanzar un parámetro actual
en un DB, el Editor KOP/FUP/AWL guarda un "POINTER” de 48-bit que apunta
al parámetro actual en la pila L Stack del bloque llamado.
Durante una llamada, se pasa un puntero interárea de 32-bit a este "POINTER".
Dentro de la FC tiene entonces lugar un acceso al parámetro de los parámetros
actuales por medio de una ramificación doble.
La creación del puntero "POINTER" en la pila L Stack del bloque llamante tiene
lugar antes de la conexión actual con la FC llamada.
Consecuencias Los parámetros del tipo de datos compuesto son “más fáciles de llevar” que los
tipos de parámetros elementales. Los parámetros de entrada del tipo de datos
compuesto pueden ser escritos en la FC llamada sin pensarlo dos veces.
De la misma forma, los parámetros de salida pueden ser leídos sin pensarlo
dos veces.
Acceso Indirecto Cuando se pasan tipos de datos compuestos tales como ARRAYs y STRUCTs,
sólo puede explotarse toda la potencia si el paso de parámetros se combina con
del acceso indirecto en el bloque llamado.
Un acceso indirecto a los parámetros actuales pasados del tipo de datos
compuestos se realiza en dos pasos:
1. Primero, se determina un puntero interárea al puntero POINTER que ha sido
pasado en la pila de datos locales del llamante por medio de la operación:
L P##Valores_medidos.
2. Para el acceso actual a los parámetros actuales, es necesario entonces
evaluar la información del puntero POINTER, que hace referencia a los
actuales operandos actuales, como:
L P##Valores_medidos // devuelve un puntero interárea a POINTER
LAR1 // carga el puntero interárea en el registro de direcciones
L W[AR1,P#0.0] // devuelve el número de DB del parámetro actual, si está
// guardado en un DB, en caso contrario 0
L D[AR1,P#2.0] // devuelve punteros interárea al parámetro actual
El resultado se calcula entonces de la forma habitual.
Paso de Parámetros Si se pasa un parámetro del tipo de datos "POINTER" o "ANY" a una FC,
entonces el Editor KOP/AWL/FUP crea la estructura de datos correspondiente
en la pila de datos L-Stack del bloque llamante.
Con la llamada a la FC, se pasa entonces a la FC llamada un puntero interárea
de 32-bit que apunta a esta estructura de datos ("POINTER" o "ANY").
Dentro de la FC llamada no es posible acceder a los parámetros directamente
debido a la falta de información del tipo referenciado a través este puntero
"POINTER" o "ANY".
La evaluación del contenido del "POINTER"- o - "ANY" debe llevarse a cabo por
el usuario dentro de la FC llamada.
La creación del la estructura "POINTER" o "ANY" en la pila L-Stack del bloque
llamante tiene lugar antes de la conexión actual con la FC llamada.
Parámetro de bloque:
TIMER, COUNTER
OB1
BLOCK_xx
Paso de Parámetros El paso de parámetros del tipo: TIMER, COUNTER y BLOCK_x es el más
sencillo. En este caso, en lugar de un puntero interárea de 32-bit, simplemente
se pasa a la FC llamada el número del TIMER, o COUNTER o BLOCK_xx
actual.
Consecuencias Este mecanismo muestra que dentro de una FC llamada sólo se pueden leer
los parámetros de entrada y sólo se puede escribir en los parámetros de salida.
Si se escribe en un parámetro de entrada, el valor correspondiente se guarda
en la pila L-Stack. Sin embargo, no se copia en los parámetros actuales
después de la ejecución de la FC.
Del mismo modo, sólo se puede escribir y no leer en los parámetros de salida.
En la lectura de un parámetro de salida se lee un valor indefinido de la pila L-
Stack debido a una falta de inicialización.
Los parámetros de entrada/salida causan los menores problemas. Se les
asignan los valores de los parámetros actuales antes de la llamada a la FC así
como se le retiran después de la llamada.
FC51
EN ENO
Min AB12
Hora AB8
Visión General El siguiente ejercicio debería mostrarle como puede acceder indirectamente a
parámetros de entrada, salida y entrada/salida del tipo de datos compuestos
dentro de una función.
Debe usar la misma técnica si tiene que acceder indirectamente a otros tipos de
datos compuestos, como ARRAYs, STRUCTs o STRINGs.
FB17
DB2 "Temperature"
CALL FB 17, DB 30
Medida_1 :="Temperatura".Cilindro
Suma_1 :=MD20
Suma_2 :=MD30
Medida_2 :="Temperatura".Eje
Tipos de Datos Como en las funciones, los operandos del tipo de datos compuestos (ARRAY,
Compuestos STRUCT, DATE_AND_TIME, y STRING) se puede pasar completamente a un
bloque de función llamado.
Para el paso, debe declararse en el bloque de función llamado un parámetro del
mismo tipo de datos que el parámetro actual que se le va a pasar.
La asignación de un parámetro de este tipo sólo es posible simbólicamente.
Parámetros de Para los parámetros de entrada y salida del tipo de datos compuestos se crean
Entrada y Salida áreas correspondientes a los valores de los parámetros individuales en el DB
de instancia. Cuando se llama al FB, los parámetros actuales del parámetro de
entrada se copian en el DB de instancia usando la SFC 20 (BLKMOV) (”paso
por valor "), antes de la conexión actual con la zona de instrucciones del FB.
De la misma manera, los valores del parámetro de salida se copian del DB de
instancia en el parámetro actual después de que el FB se haya ejecutado.
Como resultado, puede ocurrir una significante cantidad de copias (tiempo de
ejecución) en la asignación de parámetros de entrada y salida. Esta cantidad de
copias se soslaya con parámetros de entrada/salida.
Parámetros de Con los parámetros de entrada/salida del tipo de datos compuestos no ocurre
Entrada/Salida “paso por valor”. Simplemente se reservan seis bytes para cada parámetro de
entrada/salida en la zona de datos de instancia. En estos bytes se introduce un
puntero POINTER a los parámetros actuales (”paso por referencia").
Notas Los parámetros de entrada y salida del tipo de datos compuestos pueden
inicializarse en la tabla de declaración de un FB, pero no los parámetros de
entrada/salida.
Los parámetros de entrada y de salida del tipo de datos compuestos no tienen
porqué ser asignados en una llamada a un FB. Los parámetros de
entrada/salida sí tienen que ser asignados.
El acceso indirecto por memoria o por registro a parámetros de entrada/salida o
a parámetros in/out del tipo de datos compuestos es diferente al de los
parámetros del tipo de datos simples (elementales).
Acceso Indirecto Cuando se pasan tipos de datos compuestos como ARRAYs y STRUCTs, sólo
puede explotarse toda la potencia si el paso de parámetros se combina con el
acceso indirecto dentro del bloque llamado.
Una acceso indirecto a los parámetros de entrada o salida del tipo de datos
compuestos se hace en dos pasos:
1. Primero, por medio de una instrucción:
LAR1 P##Medida_1 // envía puntero interárea al parámetro
// sin desfase de dirección
se carga en AR1 un puntero interárea a los parámetros en el DB de instancia.
El puntero determinado de esta manera contiene el identificador de área (DI)
y la misma dirección de byte.bit que también es mostrada por el Editor en la
declaración de parámetros en la primera columna de la declaración de
variables.
En el caso de una instancia múltiple, éste no corresponde con la dirección
actual del parámetro de entrada/salida en el DB de instancia. El desfase de
dirección de AR2 que identifica el comienzo del área de datos de instancia en
el caso de instancia múltiple debe sumarse al puntero en AR1.
TAR2 // Carga el desfase de dirección en ACCU1
+AR1 // Suma el desfase de dirección a AR1;
2. Después de esto, puede tener lugar el acceso actual al parámetro de
entrada/salida.
El DB de instancia no tiene que ser abierto separádamente ya que ya ha sido
abierto por la macro CALL en la llamada al FB.
L D[AR1,P#0.0] // Carga el 1º componente de Medida_1 etc.
Nota El acceso indirecto a los parámetros de entrada, salida y entrada/salida del tipo
de datos simples o a variables estáticas se realiza de la misma manera ya que
en este caso los valores de las direcciones también se guardan en el DB de
instancia.
Acceso Indirecto El acceso indirecto a parámetros in/out del tipo de datos compuestos difiere en
cuanto a estructura cuando se compara con el acceso a los parámetros de entrada
y salida.
Con los parámetros in/out del tipo de datos compuestos, no es el valor el que se
copia, sino sólo un POINTER al parámetro in/out en el DB de instancia.
El acceso actual tiene lugar en tres pasos:
1. Primero, por medio de la instrucción:
LAR1 P## Medida_2 // envía un puntero interárea al POINTER
un puntero interárea que es pasado al POINTER se carga en el registro AR1.
Como en el caso anterior, la dirección de byte.bit del puntero en AR1no identifica
la dirección actual del POINTER en el DB de instancia.
En el caso de una instancia múltiple, aún debe sumarse el desplazamiento de
AR2 al puntero en el Registro AR1:
TAR2 // Carga el desplazamiento de dirección en ACCU1,
// súmalo a AR1;
+AR1 // AR1 apunta ahora al POINTER en el DB de instancia;
2. En el siguiente paso, se evalúa la información del POINTER; si es necesario, se
abre el DB en el cual está situado el parámetro actual y se carga un puntero
interárea a la dirección actual en el registro AR1:
L W [AR1,P#0.0] // Carga el número de DB del POINTER al ACCU1
T #Num_DB // Transfiere el número de DB (ó 0) a la variable
AUF DB [#Num_DB] // Abre el DB
L D [AR1,P#2.0] // Carga puntero interárea al parámetro
LAR1 // Carga el puntero en AR1, AR1 apunta al parámetro
3. Después de esto, puede tener lugar el acceso actual al parámetro actual:
L D[AR1,P#0.0] // Carga el 1º componente de Medida_2 etc.
Restricciones Como regla general, el parámetro actual debe ser del mismo tipo de dato que el
Referentes al parámetro formal. Aún más, los parámetros de entrada del bloque llamante sólo
Tipo de Parámetro pueden ser creados en un párametro de entrada del bloque llamado y los
parámetros de salida sólo en parámetros de salida.
Un parámetro in/out del bloque llamante puede ser creado en principio en
parámetros de entrada, salida, y entrada/salida (in/out) del bloque llamado.
Restricciones Con respecto a los tipos de datos, hay restricciones dependiendo del diferente
Referentes al almacenamiento de los parámetros del bloque en las llamadas a la FC o FB.
Tipo de Dato Los parámetros de bloque del tipo de datos simple (elemental) pueden pasarse
sin restricciones. Los tipos de datos compuestos en parámetros de entrada y
salida sólo pueden pasarse entonces si el bloque llamante es un FB.
Los parámetros de bloque con los tipos de parámetro: TIMER, COUNTER y
BLOCK_x pueden entonces pasarse solamente de un parámetro de entrada a
un parámetro de salida, si el bloque llamado es un FB.
FB83
Min AB12
Hora AB8
Visión General El siguiente ejercicio debería mostrarle como puede acceder indirectamente a un
parámetro de entrada o salida del tipo de datos compuesto dentro de un bloque de
función con capacidad para múltiples intancias.
Debe usar la misma técnica si tiene que acceder indirectamente a otros tipos de
datos compuestos, tales como ARRAYs, STRUCTs o STRINGs.
FB84
Min AB12
Hora AB8
Visión General El siguiente ejercicio debería mostrarle cómo puede acceder indirectamente a
parámetros in/out del tipo de datos compuestos en un blouque de función con
capacidad de múltiples instancias.
Debe usar la misma técnica si tiene que acceder indirectamente a otros tipos de
datos compuestos, tales como ARRAYs, STRUCTs o STRINGs.
ORGANIZATION_BLOCK OB1
TITLE =
VERSION : 0.1
VAR_TEMP
OB1_TEMP: ARRAY[1..20] OF BYTE; //Información de inicio del OB1
BEGIN
NETWORK
TITLE =
CALL FC 51 (
IN_DT := #OB1_DATE_TIME,
Seg := AB 13,
Min := AB 12,
Hora := AB 8);
END_ORGANIZATION_BLOCK
FUNCTION_BLOCK FB 83
TITLE =
VERSION : 0.1
VAR_INPUT
IN_DT : DATE_AND_TIME ;
END_VAR
VAR
DUMMY : ARRAY [1 .. 100 ] OF INT ;
FB63_DT : FB 63;
END_VAR
BEGIN
NETWORK
TITLE =
CALL #FB63_DT (
IN_DT := #IN_DT,
Seg := AB 13,
Min := AB 12,
Hora := AB 8);
END_FUNCTION_BLOCK
END_FUNCTION_BLOCK
CALL SFC 20 (
SRCBLK := #IN_DT,
RET_VAL := #I_VAL_Ret,
DSTBLK := #DT_TEMP);
CALL #FB64_DT (
Seg := AB 13,
Min := AB 12,
Hora := AB 8,
IO_DT := #DT_TEMP);
END_FUNCTION_BLOCK
ORGANIZATION_BLOCK OB1
TITLE =
VERSION : 0.1
VAR_TEMP
OB1_EV_CLASS : BYTE ; //Bits 0-3 = 1 (Evento entrante), Bits 4-7 = 1 (Clase de evento 1)
OB1_SCAN_1 : BYTE ; //1 (Ciclo de arranque en frío 1 del OB 1), 3 (Ciclo 2-n del OB 1)
OB1_PRIORITY : BYTE ; //1 (La prioridad es la más baja)
OB1_OB_NUMBR : BYTE ; //1 (Bloque de organización 1, OB1)
OB1_RESERVED_1 : BYTE ; //Reservado para el sistema
OB1_RESERVED_2 : BYTE ; //Reservado para el sistema
OB1_PREV_CYCLE : INT ; //Tiempo de ejecución del ciclo anterior del OB1 (milisegundos)
OB1_MIN_CYCLE : INT ; //Tiempo de ciclo mínimo del OB1 (milisegundos)
OB1_MAX_CYCLE : INT ; //Tiempo de ciclo máximo del OB1 (milisegundos)
OB1_DATE_TIME : DATE_AND_TIME ; //Fecha y hora a la que arrancó el OB1
END_VAR
BEGIN
NETWORK
TITLE =
CALL FB 84 , DB 84 (
IN_DT := #OB1_DATE_TIME);
END_ORGANIZATION_BLOCK