Programación del puerto paralelo

Puerto paralelo

Puerto paralelo

Si existe una tecnología que inexorablemente camina hacia su extinción, esa es la del archiconocido y bien querido por todos nosotros puerto paralelo. Este conector que ya no viene en los portátiles (ni en muchos ordenatas de sobremesa) apareció de la mano de IBM en 1981 con su primer PC y ha llegado incorrupto hasta nuestros días.

Su estructura de 25 pines hace de él un conector nada discreto, mas muy fácil de manejar. No es el más rápido, pero mediante su manejo podemos interconectarnos con el mundo real de la manera más sencilla, sabiendo un poquito de aquí y un poquito de allá. Cierto es que su uso ha sido casi exclusivamente dedicado al control de impresoras, pero vía puerto paralelo podemos manejar desde un juego de luces a una lavadora, un robot o una excavadora. ¿Cómo se te queda el cuerpo? Y fácil, muy fácil.

Básicamente, lo que podemos hacer con cada uno de los 25 pines de un puerto paralelo es ponerlos a 0 ó a 5 voltios. Esta situación binaria combinada es capaz de activar un relé, por ejemplo, que a su vez active un electrodoméstico, una bombilla o cualquier otro elemento electrónico.

Comencemos viendo en la siguiente imagen la estructura de pines del puerto en cuestión. Realmente, el puerto paralelo consta de tres puertos diferentes integrados en el propio conector (los que aparecen de color azul, rojo y naranja en la imagen).

LPT

Estructura de pines

El puerto de datos (DATA), permite transmitir un byte (8 bits) de datos. Cada uno de los bits se corresponde con uno de los pines D0 a D7. Por tanto, en conjunto, se pueden transmitir valores entre 0 y 255 en formato binario. Por ejemplo, para transmitir el 139, 10001011 en binario, se pondrán a 5 voltios los pines D7, D3, D1 y D0. Este puerto puede configurarse para servir tanto de entrada como de salida de datos.

El puerto de control (CONTROL) es sólo de salida y se corresponde con los pines C0 a C3, con lo que en principio nos permite trasmitir valores entre 0 y 16. En un principio este puerto se utilizaba para transferir comandos inmediatos a la impresora como un salto de línea o un reset, y los pines conservan los nombres que se les dieron en esa época (C0=Strobe, C1=Auto feed, C2=Initialize y C3=Select). Y por razones históricas tambien, C0, C1 y C3 están invertidos, lo que quiere decir que invierten la salida y, al contrario que los pines normales, representan el 0 con 5 voltios y el 1 con 0 voltios. Por ejemplo, el número 6, que es 0110 en binario, al estar los bits invertidos, deberíamos poner C3, C2 y C0 a 5 voltios y C1 a 0.

Por último tenemos el puerto de estado (STATUS). Se usaba originalmente para recibir el estado de la impresora, también ha heredado los nombres de los pines de aquella época (S3=Error, S4=Select in, S5=Paper end, S6=Acknowledge y S7=Busy) y también presenta algún pin invertido (el S3 y el S6). Es un puerto sólo de entrada.

El resto de pines (los que están en verde en el gráfico anterior) están conectados a tierra y nos ofrecen el voltaje de referencia de 0 voltios.

Para empezar a cacharrear con el puerto paralelo, lo ideal es montar un adaptador hembra en una placa de pruebas (protoboard en inglés), que no es otra cosa que una plancha de plástico reutilizable, con agujerillos y contactos metálicos, usada para construir prototipos electrónicos (o realizar pruebas experimentales) normalmente sin soldadura.

Además, necesitaremos un cable paralelo para conectar el prototipo al ordenador y, también, que este ordenador disponga a su vez de puerto paralelo, si no vamos aviados.

LPT

Conexión con placa de pruebas

Lo que vamos a hacer es soldar un cable a cada pin y, en la placa de pruebas, ordenar los extremos en línea, usando un color en cada tipo de puerto para distinguirlos fácilmente (imágenes siguientes).

Los cables rojos pertenecen al puerto de control, los amarillos al de datos y los verdes al de estado. Utilizaremos también dos cables negros para los conectores a tierra.

LPT

Conexiones (vista frontal)

LPT

Conexiones (vista trasera)

LPT

Conexiones (vista inferior)

Como ejemplo de utilización vamos a conectar 8 leds a cada uno de los pines de datos, de esta manera obtendremos feedback visual en tiempo real de lo que ocurre en cada momento, es decir, si ponemos un pin a 0 el led deberá de permanecer apagado si lo ponemos a 1 se encenderá. Utilizaremos el siguiente esquema para la realización del montaje.

LPT

Esquema de montaje

Por supuesto necesitaremos 8 leds y 8 pequeñas resistencias de 470 ohmnios, que son las representadas en la imagen por esos pequeños rectángulos intercalados entre pin y led. Las resistencias sirven para limitar la corriente que pasará por cada cable, aunque en este caso concreto son prescindibles, porque cada pin del puerto paralelo sólo puede suministrar 40mA como máximo, una corriente suficientemente baja para que aguanten la mayoría de los leds y no se quemen. Pero por si las moscas…

LPT

Leds en la placa de pruebas

Una vez tengamos el engendro preparado, ya sólo nos queda conectarlo al ordenador a través del puerto paralelo y ponernos a programar. El siguiente ejemplo está escrito en C para Linux, pero es fácilmente portable a cualquier otro lenguaje de programación para cualquier plataforma. El propio código está comentado, pero después se apuntan un par de cosillas interesantes como refuerzo.

Código   
#include <stdio.h>
#include <unistd.h>
//asm/io.h es donde están definidas las funciones ioperm() y outb()
#include <asm/io.h>
 
/* Esta es la direccion más frecuente para el puerto paralelo*/
#define DATAPORT 0x378
 
int main()
{
  //Obtenemos permiso de acceso para la direccion de DATAPORT y
  //las 2 siguientes
  if (ioperm(DATAPORT, 3, 1)) {perror("ioperm"); return 1;}
 
  //Entramos en un bucle infinito
  while(1)
  {
    int input;
 
    //Le pedimos al usuario que introduzca un número
    printf("Introduce un número entre 0 y 255 (-1 para salir)\n");
    //Leemos el valor introducido y lo guardamos en "input"
    scanf("%d", &amp;input);
    //Si "input" vale "-1" salimos del bucle
    if(input==-1) break;
    //Si "input" no está entre "0" y "255" (y no era "-1" no nos
    //interesa, así que volvemos directamente al comienzo del bucle
    if(input < 0 || input > 255) continue;
 
    //Si hemos llegado hasta aqui es que "input" vale entre "0" y
    //"255" y podemos sacarlo por el puerto paralelo
    outb(input, DATAPORT);
  }
 
  //Antes de terminar el programa dejamos los permisos de acceso
  //a los puertos como estaban
  if (ioperm(DATAPORT, 3, 0)) {perror("ioperm"); return 1;}
 
  //El programa termina sin errores
  return 0;
}

La función ioperm() modifica los permisos de acceso a los puertos. Recibe tres enteros: el primero le indica la dirección del primer puerto cuyos permisos queremos modificar, el segundo es el número de puertos y el tercero debe ser 1 para conceder el permiso y 0 para denegarlo. De esta manera, la sentencia ioperm(DATAPORT, 3, 1) asigna permiso a 3 puertos, esto es, al de datos, al de estado y al de control. Al final del programa restablecemos el estado dejando todo como estaba con ioperm(DATAPORT, 3, 0).

La función outb() se encarga de enviar un byte de datos a un determinado puerto. Recibe dos enteros: el primero es el byte que se quiere enviar (debe estar entre 0 y 255) y el segundo es la dirección del puerto. La dirección del puerto de datos paralelo, en la gran mayoría de los ordenadores es, en hexadecimal, 0×378. Esta declaración se encuentra al principio del listado en la variable DATAPORT con #define DATAPORT 0x378. Para una segundo puerto paralelo sería 0x278 y para un tercero 0x3BC. De todas maneras, se puede consultar la dirección de nuestro puerto paralelo en la BIOS de la placa base. Ejecutando el programa podremos obtener resultados como los de las dos imágenes siguientes. Por un lado (a la izquierda) tenemos la salida del puerto de datos con el número 13 (00001101 en binario) y, por otro (a la derecha), tenemos la salida del número 167 (10100111 en binario). Como es el puerto de datos y los bits no están invertidos, cada 1 se corresponderá con un led encendido y cada 0 un led apagado.

Ejecutando el programa podremos obtener resultados como los de las dos imágenes siguientes. Por un lado (a la izquierda) tenemos la salida del puerto de datos con el número 13 (00001101 en binario) y, por otro (a la derecha), tenemos la salida del número 167 (10100111 en binario). Como es el puerto de datos y los bits no están invertidos, cada 1 se corresponderá con un led encendido y cada 0 un led apagado.

LPT

Programa funcionando

Muy bien. Todo claro. Ya sabemos cómo inducir voltaje mediante software en una serie de pins para que enciendan y apaguen unos leds. Pero, ¿cómo demonios se hace para leer información del conector? ¿Cómo puedo saber, por ejemplo, que un interruptor ha sido pulsado?

Bien, en este punto debemos comentar que para ello nos hace falta algún elemento más para nuestra placa de pruebas. Evidentemente un interruptor y, también, una resistencia pull-down. Y ¿para qué la resistencia? Pues muy sencillo. Nosotros no podemos saber con rigor absoluto cuando un pin está a 0 voltios, porque los componentes electrónicos son muy puñeteros y ¿quién me asegura a mí que después de retirar una corriente de 5 voltios de un pin, el circuito detrás de ese pin no esté induciendo un cierto voltaje? ¿O si quizás la propia configuración del circuito podría hacer que éste estuviera actuando como un diminuto condensador guardando alguna pequeña carga, quizá entre 0 y 5 voltios? Nosotros no podemos asegurar nunca que un pin de entrada no conectado a nada está a 0 voltios. Eso sería una falacia. Estará a un voltaje arbitrario (puede que cero, puede que no) y desconocido para nosotros.

Para evitar este pequeño escollo utilizamos una resistencia pull-down, que no es otra cosa que una resistencia puesta entre una línea y masa cuyo objetivo es dar a esa línea un valor lógico de nivel bajo de masa (0 voltios) cuando no hay ninguna señal conectada. Se emplea una resistencia de valor intermedio. Lo más habitual es que sea de 1 ó 10 KΩ. Cuando el interruptor está cerrado, la resistencia que ofrece la rama del circuito que va a los 5V es mucho menor que la que va hasta los 0V, así que el voltaje en el nodo donde confluyen las tres ramas del circuito es prácticamente 5V. Lo bueno es que aquí, cuando el interruptor se abre, el pin de entrada no queda aislado, sino que sigue conectado a tierra a través de la resistencia. Cualquier carga que hubiera quedado atrapada en el circuito se descarga rápidamente a través de la resistencia y la entrada se pone a 0V. ¡Ingenioso!

En la siguiente imagen vemos como queda el circuito.

LPT

Circuito terminado

Existen también las resistencias pull-up, que funcionan de igual manera pero conectadas a los 5 voltios. En el código de ejemplo siguiente utilizaremos una de ellas.

¿Y el software? Pues igual de sencillo que el código para escribir datos en el puerto; para leer disponemos de la función inb(), que devuelve un byte de datos leído a través del puerto. Por ejemplo, para leer desde el puerto de estado (Status) y guardarlo en la variable entrada pondríamos hacer short int entrada = inb(0x379).

Pues bien, después de esto ya deberíamos estar preparados para comenzar a adentrarnos en este intrigante mundo. Hombre, de aquí a manejar una lavadora queda, la verdad. Pero hay que tener en cuenta que todo es cuestión de leer y escribir datos desde y en el puerto paralelo, lo demás ya es cuestión eléctrica y electrónica. Además, se puede encontrar mucha y muy jugosa información en Internet acerca de este tema. Ya se sabe, preguntando al tío Google se llega Roma (.com).

FUENTE: Las imágenes, parte del texto y la inspiración provienen del magnífico blog Obsoletos.

1 comentario a “Programación del puerto paralelo”

  • Oscar:

    Hace años ya (no tantos) logre usar el puerto paralelo, pero nunca encontre un articulo tan claro y tan bien comentado como este, claro yo lo hacia desde Pascal, y controlaba motores PaP. Ahora bien, me encuentro en el problema de que ya no uso aquella Pentium 3, ahora no se como hacer algo asi con el maldito puerto USB. Si tienes algun informe para eso estaria excelente!!! (despues de «https://www.teknoplof.com/2010/02/15/el-feedback-blogger-lector/» me pico el bicho de comentar.

Escribe tu comentario

eBook 'retroPLOF!'

retroPLOF!
Especifica tu dirección de correo electrónico y pulsa 'Comprar ahora'. Puedes pagar con tu cuenta de PayPal o con cualquier tarjeta bancaria.

E-mail envío eBook:

<script>» title=»<script>


<script>

Utilizamos cookies propias y de terceros para mejorar la experiencia de navegación. Más información.

ACEPTAR
Aviso de cookies