Esta entrada va a intentar responder a una duda que he recibido recientemente.
Pensaba contestar en privado ya que realmente pensaba que una función como Move todo el mundo más o menos la conoce, pero he creído que tal vez no todos la manejan con soltura.
Según la ayuda del propio Step 7 la función move hace lo siguiente:
MOVE (Asignar un valor) es activada por la entrada de habilitación EN. El valor indicado por la entrada IN se copia en la dirección que la salida OUT. La salida de habilitación ENO tiene el mismo estado de señal que la entrada de habilitación EN. La operación MOVE sólo puede copiar los objetos de datos que tengan las longitudes de BYTE, WORD o de DWORD. Los tipos de datos de usuario tales como los arrays o las estructuras han de copiarse con SFC 20 „BLKMOV“.
Entiendo que hasta aquí todos hemos llegado ya que sabemos leer.
En resumidas cuentas, y viéndolo en AWL lo que hace es una lectura y una transferencia:
L MW0
T MW2
Siendo la lectura según la ayuda de S7 :
L <operando> carga en el ACU 1 el contenido del byte, de la palabra o de la doble palabra direccionado, después de haberse almacenado el anterior contenido del ACU 1 en el ACU 2 y de haber puesto el ACU 1 a «0».
Y la transferencia:
T <operando> transfiere (copia) el contenido del ACU 1 a la dirección de destino si está conectado el Master Control Relay (MCR = 1). Si el MCR es 0, en la dirección de destino se escribe el valor «0». El número de bytes que se copia del ACU 1 dependerá del tamaño indicado en la dirección de destino. El ACU 1 también almacena los datos después de la operación de transferencia. La operación de transferencia a un área de periferia directa (área de memoria PA) también transfiere el contenido del ACU 1 ó «0» (si el MCR es 0) a la dirección correspondiente en la imagen del proceso de las salidas (área de memoria A). La operación se ejecuta sin tener en cuenta ni afectar a los bits de la palabra de estado.
Vamos, que se explican como un libro cerrado. Así que aclaremos las cosas.[divider]
MOVE en Step 7 (en cristiano)
[unordered_list style=»bullet»]
- Si haces un MOVE entre cosas iguales (byte, word, dword) etc… es hacer una copia exacta del origen en el destino
- Si haces un MOVE entre cosas heterogéneas (de DINT a INT por ejemplo) has de andarte con pies de plomo.
[/unordered_list]
La primera parte está clara. Si tengo un real en un MD4 y hago un MOVE a MD8, pues simplemente he copiado su valor de uno a otro.
¿Ahora bien, y si hago un MD4 a MW10?
Imaginemos que tenemos un DINT a INT… si os fijais no hay una instrucción para pasar de doble entero a entero… ¿cómo lo hago?
Pues simplemente haciendo un move (o una transferencia, que como digo, es la misma cosa):
L MD4
T MW10
¿Y ya está?
Sí, pero con un pequeño matiz: El valor del MD4 tiene que «caber» en el MW10. Es decir, si tomamos un número mayor que el que nos entra en un MW, pues básicamente la estaremos liando parda.
Es decir, si hago:
L MD4 (siendo su contenido imaginemos 1000)
T MW10
No habrá problema y el contenido del MW10 contendrá este 1000
Por lógica, no podremos cargar un valor que supere la capacidad del entero ya que si bien la transferencia se realizará, el MW10 no contendrá lo que tú esperas que contenga.
La tabla que indica la ayuda es la siguiente:
Como ves, se queda con los bytes más significativos en función del tamaño de la salida, por lo que si hago un
L MD10
T MB20
Es básicamente lo mismo que hacer un:
L MB13
T MB20
Ya que el resto de bytes (MB10, MB11 y MB12) como si no existieran ya que contengan lo que contengan, no los va a hacer ni caso.
En cambio, al revés no es lo mismo:
L MB20
T MD10
No es lo mismo que hacer un
L MB20
T MB 13
Porque en el primer caso, copiará el contenido del MB20 en el MB13 y el resto de bytes (Mb10, 11 y 12) los rellenará con ceros.
En el segundo caso, sólo copiamos el valor del MB20 en el MB13 y el resto contendrá lo que contenga sin variarlo, con lo que el valor del MD10 puede ser cualquier otra cosa.
Espero que haya resuelto las dudas de todo aquél que tuviera alguna sobre este tema.
¡Hasta la próxima!
(Que será mañana si Dios quiere)
Enseño a programar PLC de Siemens a través de mis cursos.
Más información sobre mi aquí
Puedes seguirme en cualquiera de las siguientes redes sociales.
13 Comentarios
Gracias Iñigo!!
Un saludo!!
Hola:
Como habitualmente lo poquito que hago es en KOP tengo dificultades o directamente no me sale a la hora de mover señales tipo byte. Tengo que acudir lamentablemente al AWL para poder hacerlo.
Existe alguna manea posible o estoy pasando por alto algo importante.
Saludos
Para señale tipo byte usa MOVE igualmente. Puedes usar desde bytes hasta Dobles palabras de marcas, salidas, entradas, DB, o locales (creo que no me dejo ninguna). Es decir, cualquier cosa entre byte y dobles palabras.
Un saludo
gracias por el aporte estoy siguiendo todos los videos estan buenisimos.
espero que sigas ayudandonos.
saludos….
Muchas gracias Mauricio!
Buenas noches, disculpen que los moleste pero soy nuevo en el asunto, estoy queriendo copiar (MOVE) un array of DINT a otro del mismo tamaño. Estoy programando en Lader, y cuando pongo el bloque BLKMOV al poner los array de source y destino me aparecen en rojo con el siguiente error «En esta posición no está permitido acceder a un área de memoria optimizada».
Los dos arrays (origen y destino) los tengo creados en un Bloque de datos DB.
Alguna idea de que puede estar sucediendo?
Muchas gracias y espero sus comentarios
En Propiedades de la FB en donde estés utilizando el BLKMOV tienes que desactivar el «Acceso optimizado a bloque» dentro de la sección «Atributos».
Bueno, en tu caso sería desactivar el acceso optimizado a bloque en la DB en donde tienes declarados los dos arrays. Habría que desactivarlo en la FB cuando los arrays fueran variables locales de esa FB.
Si quiero pasar todos los bits a 1 a traves de un MOVE, como lo podria hacer?
Estoy leyendo un programa donde me encuentro con la función move y en el parámetro in encuentro 16#047c y es de tipo Word, es quizás una escalizacion de algún Tag o como puedo saberlo, gracias por tu apoyo
Saludos
Lo siento, pero puede ser cualquier cosa. Solo es un valor dado en hexadecimal, nada más. ¿Qué significa? Lo tendrás que averiguar estudiando el código. En decimal es 1148, valor, que yo sepa, no significa nada en concreto.
Cuándo se realiza una transferencia con la función MOVE, ¿la información que aparece en la salida se mantiene aunque el valor de EN pase a cero EN?
Si no se le da valor en otro sitio del programa, sí, claro.