Vamos a ver algunos usos que se le puede dar a las instrucciones de desplazamiento de bits.
Concretamente del desplazamiento a la izquierda, y no a la derecha, porque verás que es más útil, en general.
Esta entrada viene respondiendo a una pregunta que me hicieron ya hace un tiempo, porque el que me la hizo, no tenía muy claro para qué sirve, o qué uso se le puede dar.
Seguramente habrá muchos otros de los que te voy a mostrar aquí.
Esto es solamente una pequeña idea, de cara a comprender la instrucción, y así que en el futuro, cuentes con ella porque sepas usarla.
Empecemos por lo que dice Siemens que hace esta instrucción.
Contenido
Descripción de desplazamiento a la izquierda
SHL_W (Desplazar 16 bits a la izquierda) se activa si la entrada de habilitación (EN) tiene el estado de señal «1».
Con la operación SHL_W se desplazan los bits 0 a 15 de la entrada IN bit a bit a la izquierda.
A los bits 16 a 31 no les afecta la operación de desplazamiento.
La entrada N indica el número de posiciones de bit en que se va a efectuar un desplazamiento.
Si N es mayor que 16, la instrucción en la salida OUT escribe un «0» y pone los bits A0 y OV de la palabra de estado a «0».
Desde la derecha se desplaza el mismo número (N) de ceros para ocupar las posiciones que quedaron libres.
El resultado de la operación de desplazamiento queda depositado en la salida OUT. La operación SHL_W pone a «0» al bit A0 y al bit OV si N es diferente de 0.
El estado de señal de ENO es igual al de de EN.
Es decir, y en cristiano:
El acumulador contiene como sabes 4 bytes.
Bueno, pues esta instrucción es solamente para los dos primeros bytes (los que están más a la izquierda).
Una vez teniendo claro que solo jugamos con 16 bits, lo que hacemos es, una vez habilitado el movimiento, desplazar los bits que están más a la derecha (los menos significativos) hacia la izquierda X posiciones, metiendo ceros en las posiciones libres que se generan en la derecha, y despreciando los bits más altos que se salen por la izquierda
Lógicamente, esta instrucción no tiene mucho sentido si desplazas más de 16 bits, ya que el desplazamiento sería demasiado grande para los dos bytes con los que estamos jugando.
En el dibujo se entiende creo que mejor que en el texto de la ayuda.
Bueno, espero que más o menos, se tenga la idea.
Ahora bien ¿para qué diantre vale esto?
Pues vamos a ver tres aplicaciones, aunque alguna de ellas, no me guste demasiado:
Crear punteros rápidamente
Esta sin duda, es la aplicación que más me gusta.
Como vemos en el curso de Step 7, los punteros se construyen indicando cuántos bits tiene el puntero. Es decir, el puntero P#0.0 contiene 0 bits, mientras que el puntero P#1.0 contiene 8 bits.
Bien.
Pues si cargo 16 como entero, y se lo transfiero a un puntero, la dirección que le cargo es la P#2.0
Si le cargo 24 como entero, tendré el P#3.0
Si le cargo un 32, tendré el P#4.0
¿hasta ahí está claro, no?
Como ves, en el fondo, si quiero obtener el puntero P#3.0 es lo mismo que cargarle 24 como entero (el número de bits). Pero 24 se puede descomponer como 3×8 ¿no?
Pues si te fijas, y coges un 3 en binario:
00000000 00000011
Y desplazamos 3 unidades hacia la izquierda…
00000000 00011000
¿qué número obtenemos?
¡Exacto! ¡Un bonito 24!
Por eso verás muchas veces cuando estás leyendo un programa creado con punteros algo de esta guisa:
L 3
SLW 3
LAR1
L 5
+AR1
¿Qué puntero ha creado?
Pues sí, el P#3.5
Así que para crear punteros, es muy típico coger la dirección entera del puntero, desplazarla hacia la izquierda 3 bit y cargarlo en el AR1. Así obtienes la dirección del byte en forma de puntero.
Posteriormente, si es necesario, le sumas el número de bits de la dirección
Pequeños tracking
Si ahora, en vez de desplazar varios bits, solo desplazamos 1, podemos hacer pequeños tracking de piezas.
Así, cargaremos siempre la pieza en el bit más a la derecha:
00000000 00000001
Y posteriormente desplazaremos una unidad cuando se produzca el movimiento:
00000000 00000010
Si por ejemplo hemos movido tres posiciones, y entra una nueva pieza, solo tendremos que poner a 1 el bit más a la derecha (el menos significativo) para seguir con el tracking, quedando algo como esto más o menos:
00000000 00001001
De esto ya hablamos en su día en un post, por lo que le puedes echar un vistazo al ejemplo que lo ilustra bastante bien
Crear secuencias de movimientos
Este es un método que te desaconsejo usar.
Yo lo he visto en algún programa, y sinceramente no me parece la mejor forma de hacer una secuencia de movimientos por la dificultad innecesaria que le estás añadiendo cuando quieras mantener el programa.
Pero yo te lo cuento, al menos para que no te sorprenda si lo ves.
Como hemos visto, podemos mover un bit hacia la izquierda cuando deseemos.
Por tanto, para realizar una secuencia, está chupao.
Cuando se generen las condiciones de arranque en automático y todo esté Ok, simplemente cargarás un 1 en el word que forma la palabra que vas a mover, teniendo en binario:
00000000 00000001
Por tanto, el bit de la derecha, será el bit que arranque la secuencia, y la máquina se pone a trabajar en la fase 1.
Cuando la fase 1 llegue a su fin, lo único que tendrás que hacer, es mover una unidad para que pase a la fase 2:
00000000 00000010
Posteriormente, la fase 3:
00000000 00000100
Y así sucesivamente.
¿Y qué tiene de malo esto?
Pues un par de ellas, que me vienen a la cabeza.
La primera es que a la hora de usar la secuencia, lógicamente usas el bit en concreto.
Quiero decir, que imaginemos que la secuencia la almacenamos en MW100.
Bien, el paso 1 será la M101.0, el paso 2 la M101.1 y así, sucesivamente.
Vale.
El primer problema que te encuentras es que quieres saber dónde se le da valor a la M101.4
Buscas referencias cruzadas… y no está dándose valor a esta variable en ningún sitio.
Podrías pensar que buscas la MW100 y ya está. Pues tampoco.
Porque si el programa es suficientemente grande y complejo, el movimiento del word MW100 no se hará solamente en un sitio (como sería deseable), sino que se le estará dando en varios sitios, uno por fase.
Entonces, de las 15 referencias cruzadas, ¿cuál es?
No te queda mas que buscar una por una hasta encontrar la M101.4 y ver que tras X condiciones, entonces se mueve un bit la MW100 y por tanto, se está activando la M101.5
Bueno, podrías buscar la M101.4 y ver donde se hace el desplazamiento.
Estás igual, o peor. Puede que la M101.4 esté aplicada en 20 sitios diferentes, así que te toca buscar en cuál de ellos, has movido la palabra.
La única solución aceptable, es poner todas las condiciones de movimiento en un unico segmento si son condiciones sencillas, o bien, si tienes que hacerlo a trozos, poner todos los pasos, uno detrás de otro.
Pero para hacer esto… ¿no es más sencillo hacer un set/reset de cada bit, y ya está?
Yo, al menos, lo veo así.
Ojo, el programa, si está bien hecho, funciona igual de bien. Pero a la hora de encontrar un problema, se me antoja más farragoso salvo que seas muy ordenado y cuidadoso.
Para gustos.
Pero para mi, no es una buena práctica por las complicaciones innecesarias que conlleva.
¿Y el desplazamiento a la derecha?
El desplazamiento a la derecha, tiene aplicaciones similares, si bien es menos intuitivo debido a la disposición de los bits.
Pero también se puede usar, como puedes intuir
¿Cómo lo ves?
¿Has usado alguna vez alguna de estas opciones?
Estoy seguro que sí.
Incluso de otras formas ¡que espero que nos lo cuentes en los comentarios!
Recuerda que si necesitas formarte en TIA Portal tienes un super curso completo, y si es Step 7 clásico lo que necesitas, también tienes cómo formarte
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.
9 Comentarios
Gracias Iñigo por estos repasos de temas de Step 7 que son elementales en cualquier programador1
Saludos!!
De nada David!
Gracias por estos Post Iñigo, un pequeño recordatorio siempre es bienvenido. El tema punteros es muy habitual en programas en AWL. Me ha venido muy bien leerlo.
Un saludo
Gracias Rubén, esa es un poco la idea. Unas cosas te viene bien a ti, y otras cosillas a otros.
Saludos!
Iñigo Gutiez:
Gracias, por compartir estos temas muy interesante.
Saludos cordiales!!
Rene Tejerina.
Hola Iñigo Gútiez deseo saber si tenes un curso de scripts para wincc (scada)
muy bueno la explicación desplazamiento.
Saluda Atte. Ricardo
Hola! muchas gracias por tus blogs, se aprecian bastante
Referente al resultado aleatorio que genera el uso de los registros rotativos y de salida normal, con un detector de flancos en la entrada del bloque se soluciona el problema.
Saludos desde México
Como puedo Realizar un desplazamiento a la izquierda del valor 170 como cadena de bits
Lo siento, pero no entiendo lo que quieres hacer.