Recientemente he recibido un email pidiendo ayuda para comprender un programa sobre un display de 7 segmentos realizado en Micro-Win.
He de decir, que yo en MicroWin no he programado nunca ya que todos los PLC con los que he trabajado siempre han sido de la serie 300 y 400 y nunca del 200. Es así. Pero bueno, le he echado un vistazo, y al final conociendo S7, es fácil de comprender.
Vamos a intentar resolver las dudas que pueda haber en el ejemplo. Para ello vamos a tocar una serie de conceptos y funciones, como hacer un AND entre bytes y palabras, mover bits a la derecha y la función SEG tanto en S7 como en Microwin.
Vamos a ver los conceptos teóricos necesarios y como siempre terminaremos viendo un vídeo explicativo de la solución, en este caso tanto en Step 7 como en Microwin.
Pero para eso, hagamos por un momento de profesor y redactemos el enunciado del problema:
[box type=»note» style=»flat» border=»full»]Realizar un programa que dado un número de 3 cifras, obtengamos cada segundo las centenas, decenas y unidades en un único display de 7 segmentos.[/box]
Bien, para ir paso a paso, enumeremos los ingredientes necesarios:
- Saber qué es un display de 7 segmentos y cómo funciona
- Tratar el número de 3 cifras y poder obtener cada una de ellas por separado
- Tomar esa cifra y sacarla de tal forma que el display lo entienda.
Contenido
¿Qué es un display de 7 segmentos ?
Haciendo una una copia descarada de la wikipedia:
[quote]El visualizador de siete segmentos (llamado también display) es una forma de representar números en equipos eléctronicos. Está compuesto de siete segmentos que se pueden encender o apagar individualmente. Cada segmento tiene la forma de una pequeña línea. Se podría comparar a escribir números con cerillas o fósforos de madera.[/quote]
Sigamos leyendo:
A cada uno de los segmentos que forman el display se les denomina a, b, c, d, e, f y g y están ensamblados de forma que se permita activar cada segmento por separado consiguiendo formar cualquier dígito numérico. A continuación se muestran algunos ejemplos:
- Si se activan o encienden todos los segmentos se forma el número «8».
- Si se activan sólo los segmentos: «a, b, c, d, e, f,» se forma el número «0».
- Si se activan sólo los segmentos: «a, b, g, e, d,» se forma el número «2».
- Si se activan sólo los segmentos: «b, c, f, g,» se forma el número «4».
Bien, nos hacemos una idea ¿verdad?
¿Cómo tratamos los datos?
Inicialmente vamos a disponer de un número de 3 cifras como dice el enunciado, lo que viene siendo un entero de 0 a 999. Ahora bien, para poderlo tratar va a ser pasar este número entero a BCD. He elegido un número de 3 cifras porque la conversión de entero a BCD (operación ITB) sólo es válida para números entre +- 999.
¿Qué es un número BCD?
Hoy es el día de la wikipedia:
[quote]En sistemas de computación, Binary-Coded Decimal (BCD) o Decimal codificado en binario es un estándar para representar números decimales en el sistema binario, en donde cada dígito decimal es codificado con una secuencia de 4 bits. [/quote]
Esto en cristiano, y para lo que nos interesa, es que con un byte vamos a poder representar dos dígitos, desde 00 a 99. Usaremos por tanto 4 bits para cada dígito.
Es decir, y poniendo ejemplos para los primeros 4 bits:
- El 0 en binario se representa con 0 0 0 0
- El 1 en binario se representa con 0 0 0 1
- el 2 en binario se representa con 0 0 1 0
- el 3 en binario se representa con 0 0 1 1
y así sucesivamente hasta..
- el 8 en binario se representa con 1 0 0 0
- el 9 en binario se representa con 1 0 0 1
¿ y el 10?
Pues pasaremos el testigo (a llevada) a los siguientes 4 bits, poniendo a cero los primeros 4 bits.
Puedes comprobar que no existe el número BCD 1 1 1 1 por poner un ejemplo. No se usan todos los que se podrían usar para codificar un número (como puede ser en un entero donde 1 1 1 1 es 127).
En definitiva, se codifica en binario normal con esos 4 bits hasta llegar al 9, a partir del cual ya no hay más. Para construir un número de 2 dígitos necesitamos otros 4 bits. Y así sucesivamente claro.
Espero que no te hayas quedado dormido, así que sigamos.
Tratar y filtrar un número de 3 cifras
Una vez comprendido qué es un display de 7 segmentos, y qué es un número en BCD (gracias de nuevo a la wikipedia), vamos a tratar el siguiente punto, que es filtrar nuestro número para ir quedándonos con cada cifra.
Para ello vamos a usar una operación AND. Pero no una cualquiera, sino una operación con palabra (WAND)
Perdona, pero.. que ¿qué?
Bien sabes lo que es hacer un AND entre dos bits: si ambos están a 1, el resultado es 1. Si no lo son, un rosco.
Pues hacer un filtrado con un WAND no es mas que hacer lo mismo, pero en vez de con un bit, con 16. En AWL la operación WAND se llama UW.
Vale. Más o menos lo pillo… pero ¿para qué?
Aquí viene lo interesante: puedo filtrar (quedarme) con la parte de un WORD que yo quiera. ¿Cómo? Pues haciendo un WAND de mi palabra con una palabra donde los bits que me quiero quedar, son 1.
Ya si eso, igual con un ejemplo…
Imagina que tenemos una palabra, la MW0 cuyo valor en bits es: 0101 1101 1000 1101
Y quiero quedarme sólamente con los 4 primeros bits, los marcados en azul Bilbao (la tierra tira). ¿Cómo lo hago?
Pues muy sencillo. Hago un WAND de mi MWO con un 0000 0000 0000 1111 es decir, en hexadecimal W#16#000F o simplemente W#16#F
Haciéndolo, lo que nos da como resultado es curiosamente todo ceros, salvo lo que queremos filtrar: 0000 0000 0000 1101
¿Cómo se te ha quedado el cuerpo?
Ahora viene lo mejor: como nuestro número está en BCD y cada 4 bits es un dígito, haciendo este tipo de filtrado, obtenemos nuestras unidades, decenas… en función de dónde pongamos el filtro.. ¿si?
Pero hay una pega a solventar: después de nuestro éxito sin parangón filtrando las unidades queremos filtrar además las decenas, te vas a decir a ti mismo.. esto está chupado… el filtro será W#16#00F0 o W#16#F0 y mi resultado serán las decena…
Pues lamentablemente, no. Si hacemos ese filtro, ojito lo que tendríamos:
MW0 = 0000 0101 1000 0101
W#16#F0 = 0000 0000 1111 0000
WAND = 0000 0000 1000 0000
Correcto, pero eso no es un 8, sino un 80 en BCD.
Mmmmm y ¿cómo lo soluciono yo ahora?
Tampoco es que estemos muy lejos de la solución ¿no? Sólo son unos cuantos ceros que nos sobran.
Para eliminar esos ceros,y pasar nuesto 80 a un 8, que es lo que nos interesa, necesitamos…
Desplazar los bits a la derecha
Existen varias funciones de desplazamiento y rotación en Step 7. Hoy vamos a tocar sólamente 1, que es la de rotar X bits a la derecha. Otro día veremos más en profundidad tanto las rotaciones como el tema de las operaciones lógicas con palabras.
Pero al grano: Tenemos nuestro 80 en BCD del cual nos queremos cepillar el cero… si fueramos capaces de eliminar los 4 bits iniciales, la cosa estaba hecha.. y como estos alemanes piensan en CASI todo, tenemos la operación SHR_W..
¿Que es lo que hace la operación SHR_W?
Pues resumiendo, desplazar los N bits que le indiquemos hacia la derecha (eliminando los que estaban) y metiendo O por la izquierda para completar la palabra. En nuestro caso, lo que va a hacer:
Nuestra palabra sin rotar: 0000 0000 1000 0000
Nuestra palabra rotada : 0000 0000 0000 1000 0000
Es decir, elimina los 4 bits que teníamos en marrón, desplazando el resto, introduciendo 4 flamantes y nuevecitos bits a cero por la izquierda.
Pues ¡tachán! ya tenemos nuestro 80 en BCD convertido en un 8 bien chulo (como no podía ser menos).
¿Y las centenas ?
Estoy convencido que ahora ya sabrias hacer el resto. Como bien imaginas:
- Filtrar con W#16#F00
- Girar 8 bits en vez de 4 para obtener las centenas.
Tú que estás al loro, seguro que te has dado cuenta de un pequeño detalle: Las centenas no hace falta filtrarlas, con girar los 8 bits es suficiente puesto que no hay cifras a la izquierda… pues sí. No hace falta porque es un número positivo ya que en caso de un número negativo los 4 bits más altos son todo unos . Por tanto, digamos que para estandarizar el procedimiento sería como lo comentado.
Representación en un display de 7 segmentos
Una vez que tengamos cada dígito, tenemos que sacarlo en un display de 7 segmentos… ¿cómo?
Habría dos formas:
- Un codificador hardware de BCD a 7 segmentos (por ejemplo el 7447)
- Codificar por software y dar la salida de los 7 segmentos.
Lógicamente, y ya que estamos, pues lo codificamos nosotros ¿no?
Para eso S7 disponone una función de codificación de un display de 7 segmentos , el FC93 «SEG» dentro de Standard Library /TI-S7 Converting blocks
La descripción de la ayuda de Step 7 dice lo siguiente:
[quote]La función «Crear el patrón de bits para el display de siete segmentos» (SEG) convierte los cuatro dígitos hexadecimales de una determinada palabra fuente (IN) en cuatro códigos equivalentes para hacer posible el display de siete segmentos, y escribe el resultado en la palabra doble de salida (OUT).[/quote]
¿Una palabra a una doble?
Piénsalo bien. Introducimos un word (16 bits), es decir, 4 dígitos en BCD. Si lo queremos sacar en 7 segmentos, necesitamos una doble palabra, o sea, 4 bytes, un byte por cada número de tal forma que cada bit ilumine una patita del display de 7 segmentos (sobrandonos un bit, que es de regalo).
El cuadro sería el siguiente:
Como puedes ver, además de números como es el caso, podríamos representar caracteres en función de la activación de unos u otros bits según la codificación indicada.
Un momento, ¡¡ tú me has estado tomando el pelo todo el rato !!…
Un poco sí. Perdón. Me he equivocado. No volverá a suced… ejem.
Como hemos dicho, la función SEG toma un valor en BCD de 16 bits y lo transforma en su salida binaria, volcándolo en 4 bytes, y por tanto, no hacía falta filtrar ni rotar absolutamente nada, simplemente con elegir el byte de las unidades, decenas, centenas y millares, hubiera bastado ¿no?
Pues sí. Imaginemos que volcamos la información en el MD0, así tendremos
MB0: Signo del número
MB1: Centenas
MB2:Decenas
MB3: Unidades
Ya. Pero no hubieras aprendido:
- A usar en WAND
- A desplazar bits.
…por no decir lo bien que lo hemos pasado… o ¿no?
Mientras te baja la inflamación del cuello, si te apetece, puedes ver el resultado en el siguiente vídeo
Recuerda que el proyecto está disponible en exclusiva para todos aquellos que adquieren el libro cómo programar Step 7 y no morir en el intento además de muchos otros ejemplos.
Referencias:
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.
4 Comentarios
Gracias de nuevo…eres un crack…
te felicito por el blog …sobre que los alemanes lo piensan casi todo…….mejor que no piensen tanto!!
un saludo dese Barcelona
Hola Iñigo.
Muy bueno,todo muy claro y explicado al minimo detalle.
Viendo tutoriales como este te anima a seguir a ampliar conocimientos.
La verdad me sirvio de gran ayuda.
Enhorabuena
Saludos
Gracias Orlando.
Me alegra que te haya ayudado.
Seguiremos intentando sacar temas interesantes.
Un saludo.
Excelente explicacion Iñigo muchas gracias