Función MOVE en Step 7

Esta entrada va a intentar responder a una duda que he recibido recientemente.

MOVE en Step 7Pensaba 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.

 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:

MOVE en Step 7

 

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)

 

 

 

Acerca de Iñigo Gútiez

Ingeniero industrial por la Escuela de Ingenieros Superiores de Bilbao. Trabajo como ingeniero de proyectos y automatización en Guardian Industries

Te puede interesar

Direccionamiento indirecto

Direccionamiento indirecto en Step 7 (I) – Memoria y punteros a área

Para empezar con el tema del direccionamiento indirecto, vamos a explicar una serie de conceptos …

6 Comentarios

  1. Gracias Iñigo!!
    Un saludo!!

  2. 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

  3. 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

  4. gracias por el aporte estoy siguiendo todos los videos estan buenisimos.
    espero que sigas ayudandonos.
    saludos….

  5. Muchas gracias Mauricio!

  6. 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