7 - Capitulo 5
7 - Capitulo 5
7 - Capitulo 5
CAPÍTULO 5
PARA PROGRAMACIÓN DEL PUERTO PARALELO
OBJETIVOS:
Al completar este tema usted podrá:
Hemos visto con bastante detenimiento aspectos que hacen al hardware de las PC,
así como una cantidad de detalles acerca de cómo podemos hacer para conectar la
PC con elementos externos a ella y que deseamos controlar.
Cualquier lenguaje de alto nivel es apto para ello, o sea que podríamos usar Pascal,
C, Visual Basic, e inclusive (con mayor dificultad) lenguajes de bajo nivel como el
Assembler.
Entre todos ellos, hemos seleccionado el Qbasic, que es muy sencillo de entender,
muchos niños y jóvenes están familiarizados con él, y además porque viene
conjuntamente con el sistema operativo MS-DOS, de manera que, en muchos casos
sin saberlo, lo tenemos ya instalado en nuestras máquinas.
Otra ventaja del Qbasic, es que trabaja en el entorno DOS, de manera que no
necesitamos tener Windows instalado para usarlo (lo que nos habilita a usar
cualquier vieja PC) y además es perfectamente hábil para el manejo de puertos,
tanto el serie como el paralelo.
En marzo de 1982, IBM lanzó el primer compilador Basic para sus IBM-PC. Esta
versión fue escrita por Microsoft, usando códigos y métodos desarrollados por Bill
Gates, Greg Whitten, y otros.
El Basic original, por su sencillez y utilidad, tuvo una tremenda aceptación a nivel
mundial, lo que impulsó su posterior evolución. En 1986 nace el Quick Basic 1.0.
con características similares al Basic que tenía en uso IBM, pero esta vez lanzado
directamente por Microsoft. Tanto éxito tiene Microsoft con este lenguaje, que
lanza sucesivamente las versiones 2.0, 3.0, 4.0 hasta que en 1988 lanza el 4.5, que
muchos programadores utilizan aún en la actualidad. Finalmente en 1989
Microsoft saca el Quick Basic 7.0, que al igual que el VBDos (Visual Basic para
DOS), trabajan todos en ambiente DOS. El VBDos, lanzado en el mismo 1989,
Capítulo 5: Programando el manejo del Puerto Paralelo: Fundamentos de Qbasic – 2001 2
Autor: Ing. Jorge J. Ferrero Bajado de: www.profesormolina.com.ar
utiliza exactamente el mismo código de programación que el Qbasic, pero ya tiene
su nueva interfase con el usuario, que lo hace muy atractivo y que rápidamente
desplaza al Qbasic.
Con el nacimiento del Windows, nace el Visual Basic para Windows, no saliendo
más versiones de Qbasic. En la actualidad se utiliza el Visual Basic 6.0 (para
Windows, obviamente), que tiene posibilidades de programación de interfases PC -
usuario casi inimaginables, pero que paralelamente ofrece algunas dificultades
para programar pues, como es lógico, más completos los programas, más complejo
es manejarlos.
El actual Visual Basic 6.0 tiene todavía muchos elementos del Qbasic, de manera
que eligiendo este lenguaje, quien desee después pasar al Visual Basic, lo podrá
hacer aprovechando los conocimientos adquiridos para el Qbasic.
Instalación
Una vez situados en el directorio donde están los dos archivos citados, tecleo
"Qbasic<enter>" (sin comillas) y aparecerá una pantalla con fondo azul y un
mensaje de bienvenida, que me da dos opciones: <enter> para referencia básica
(ayuda) y <escape> para ir a la pantalla de edición. Se recomienda familiarizarse
con la ayuda, y siempre con <escape> podemos pasar a la pantalla de edición. En
este estado de cosas, tenemos la PC lista para comenzar a programar!
Hola Juan!
En el primer renglón, luego del tilde (que se puede escribir también como
alt+039) hay un comentario que luego no tiene efecto sobre el programa
(podemos probar de borrarlo). Es decir, todo lo que se escriba después del tilde
es ignorado por el compilador. Esto es muy útil para hacer comentarios acerca
de quien o cómo se hizo un programa, qué criterios se usaron, aclaraciones
varias, etc. Además, el tilde se puede poner en el mismo renglón de una
sentencia ejecutable (como CLS), para hacer una aclaración, e igualmente todo
lo que se coloque después del tilde será ignorado por el compilador.
Para pasar de un renglón al siguiente, hay que dar <enter>.
La sentencia PRINT manda a imprimir en la pantalla del monitor todo lo que
se coloque entre las comillas, en forma textual.
La sentencia PRINT sin nada a continuación, manda a escribir un renglón
blanco.
Si se escribe Print ó print en lugar de PRINT, vemos que se cambia todo a
mayúsculas cuando doy el <enter>
Pero si escribo Pint en lugar de Print, no lo cambia a mayúsculas, porque Pint
no es una sentencia conocida para Qbasic, de manera que cuando hacemos un
programa, éste es un primer control para que no cometamos errores de "tipeo".
La sentencia END da por terminado el programa.
Luego que Qbasic ha ejecutado el programa, me da el aviso "Presione cualquier
tecla y continúe", como una forma de avisar que ha concluido con su trabajo.
Probar de colocar un tilde delante de CLS (o sea, hacer ignorar esta sentencia,
es como borrarla) y ejecutar nuevamente el programa un par de veces. Observe
cual es la diferencia. Saque el tilde y vuelva a ejecutar.
Qbasic no reconoce acentos, ni signos tales como ¡ y ¿.
Probablemente la pregunta que nos haremos sea ¿porqué complicar la cosa con las
distintas variables? (cuando podríamos usar directamente la más grande). La
respuesta está en que la capacidad de manejo de memorias Qbasic no es ilimitada,
por lo que a veces hay "que sacar cuentas" cuando los programas son muy grandes.
En nuestro caso, y para nuestras aplicaciones, podremos trabajar siempre
tranquilos en single, que es la opción por defecto, sin preocuparnos mucho por el
tamaño de nuestros programas.
Como todavía no debe estar muy claro qué son y como se usan las variables,
vamos a hacer algunos ejemplos:
CLS
numero = 123
PRINT numero
END
CLS
numero = 123.4567
PRINT numero
END
CLS
INPUT numero
PRINT "El numero ingresado es "; numero
END
Ahora podemos ingresar datos por el teclado, que pueden ser guardados por
variables de los tipos conocidos.
Tenemos una forma de verificar que los datos ingresados son correctos,
mediante su impresión en la pantalla.
Mediante la sentencia PRINT, podemos imprimir, además de los valores de las
variables, mensajes textuales, colocándolos entre comillas.
El punto y coma que separa el mensaje textual de la variable, se coloca para
imprimir ambos en el mismo renglón de la pantalla.
Nota importante: En Qbasic cualquier número se puede escribir en forma
decimal, hexadecimal o binario, ya sea para imprimir, ingresar como dato
programar, etc.. Para que Qbasic sepa en qué forma he decido ingresar el
número, se sigue la siguiente convención:
Si no se coloca ningún prefijo Æ el número ingresado o impreso es
decimal.
Si se antepone &H Æ el número ingresado o impreso es hexadecimal.
Si se antepone &O Æ el número ingresado o impreso es octal.
No existe prefijo para binario en Qbasic.
Este comando repite todo lo que esté entre el FOR y el NEXT hasta que se cumpla
una determinada condición:
CLS
FOR i = 1 TO 100
PRINT i
NEXT i
END
Si lo ejecutamos, veremos que este programa va a imprimir todos los valores que
tome i desde 1 hasta 100, de uno en uno. Igualmente, si hubiese una serie de
cálculos, con distintos valores de i después del FOR y antes del NEXT, el
programa los ejecutaría uno a uno para cada valor de i. Luego esta sentencia hace
tantos lazos como sean necesarios, incrementando i en uno cada vuelta de lazo,
hasta que se cumple la condición de que i = 100.
CLS
FOR i = 90 TO 100 STEP 2
PRINT i
NEXT i
END
CLS
FOR i = 91 TO 100 STEP 2
PRINT i
NEXT i
END
el último valor de i hubiese sido 99, pues 99 + 2 = 101, que supera al límite 100.
Aquí vemos que el rótulo "infinito:" puede tener en realidad cualquier nombre;
queda identificado como rótulo para Qbasic por el hecho de agregarle los dos
puntos al final.
El inconveniente es que el programa no se detiene nunca, lo cual puede ser útil
en algunos casos, por ejemplo en el relevamiento de datos. Para detener la
ejecución del programa en estos casos, se puede apretar simultáneamente las
teclas Ctrl-Pausa o Ctrl-Break del teclado.
Bueno, en este caso son pocas líneas, pero hay mucho que aprender. Analicemos:
Hasta este momento hemos utilizado la sentencia INPUT para ingresar valores
de una variable por teclado, pero no habíamos enviado mensaje a la pantalla
mediante INPUT. Cuando ejecutamos este programa, vemos primero que en la
pantalla aparece el interrogante Que quieres hacer?? con dos signos de
interrogación, dado que el primero es el de la frase que hemos mandado a
imprimir, y el segundo corresponde a la pregunta del valor de la variable
opcion que debemos ingresar (1 ó 2). O sea que INPUT funciona muy parecido
a PRINT, ya que podemos imprimir un mensaje e imprimir (ingresar) el valor
de una variable.
A continuación podemos ver claramente la decisión condicionada que implica
la sentencia IF...THEN, ya que si la variable opcion vale 1 hace saltar el flujo
del programa al rótulo borrar y la sentencia CLS, mientras que si vale 2, salta
al rótulo hola y luego manda a imprimir hola!...etc.
Aunque no se desprende del programa ejemplo, vale advertir que después del
THEN puede colocarse cualquier sentencia válida de Qbasic en lugar del
GOTO. Igualmente puede reemplazarse el "=" (signo igual) por cualquier
símbolo matemático tal como ">" (mayor que), "<" (menor que), "<>" (distinto
a).
Capítulo 5: Programando el manejo del Puerto Paralelo: Fundamentos de Qbasic – 2001 10
Autor: Ing. Jorge J. Ferrero Bajado de: www.profesormolina.com.ar
Como ejercicio, se sugiere ejecutar el siguiente programa:
CLS
PRINT "Programa Ejemplo-01"
PRINT "Trata de adivinar el numero que estoy pensando, entre 1 y 10."
PRINT "Solo tienes tres oportunidades."
INPUT "Primera oportunidad"; numero
IF numero = 3 THEN GOTO lapegaste
PRINT "Lo lamento!"
INPUT "Segunda oportunidad"; numero
IF number = 3 THEN GOTO lapegaste
PRINT "Vas mal!"
INPUT "Ultima oportunidad"; numero
IF numero = 3 THEN GOTO lapegaste
PRINT "Lastima! El numero era 3!"
END
lapegaste: PRINT "Bravo! Ganaste!"
END
Desafío:
Esta es otra instrucción muy útil, pero como ya tenemos "cierta experiencia" en
programación Qbasic, lo que haremos ahora será reproducir exactamente lo que
dice el menú de ayuda de Qbasic, de manera que no familiaricemos con él y de esta
forma podamos consultar cualquier otra sentencia que no sepamos usar.
DO
[bloqueinstrucciones]
LOOP [{WHILE | UNTIL} condición]
Ejemplo:
i% = 0
PRINT "El valor de i% al principio del bucle es "; i%
DO WHILE i% < 10
i% = i% + 1
DO UNTIL a = 10
prueba = prueba + 1
PRINT "Prueba numero"; prueba
Capítulo 5: Programando el manejo del Puerto Paralelo: Fundamentos de Qbasic – 2001 12
Autor: Ing. Jorge J. Ferrero Bajado de: www.profesormolina.com.ar
PRINT
PRINT "Adivina el numero supersecreto!"
INPUT "Arriesga:"; a
LOOP
Por supuesto, hay siempre al menos dos caminos para hacer todo en cualquier
lenguaje de programación. En el caso de nuestro programa anterior, se podría
haber puesto, en lugar de "DO UNTIL a = 10", "DO WHILE a <> 10", y las cosas
hubiesen funcionado exactamente igual.
Un uso interesante del DO...LOOP es para hacer el clásico "presione una tecla para
continuar" que tantas veces hemos visto. Esto se puede hacer con la sentencia de
Qbasic INKEY$, que me devuelve la tecla presionada en el teclado (ver ayuda de
Qbasic), como se ve en el siguiente ejemplo:
Y hasta aquí llega nuestro tutorial de Qbasic; no olvidemos que este no es un curso
de Qbasic!! Lo que hemos visto es menos de lo que vamos a usar, pero la idea ha
sido tomar un primer contacto con este lenguaje de programación, y en particular,
tomar conciencia que cualquier sentencia que encontremos en un determinado
programa de Qbasic, podemos saber perfectamente para qué sirve y cómo se usa
mediante el uso de la ayuda. De ahora en más esto haremos cuando tengamos
dudas acerca de un programa, de manera que volvemos entonces al manejo de
nuestro puerto paralelo mediante Qbasic.
Sentencias para manejo del puerto paralelo. Sentencias PEEK, OUT, INP
Cuando vimos cómo está constituida una PC, hemos analizado uno de los caminos
para averiguar las direcciones de los puertos, mediante Assembler (Ver "Cómo se
averiguan las direcciones de los puertos?" en "Arquitectura interna de una
computadora", pág. 9). Esta forma de hacerlo, aunque sencilla, no puede encararse
desde Qbasic. Si yo quiero manejar puertos desde Qbasic, es necesario que el
mismo programa de manejo de puertos me averigüe las direcciones de los puertos
disponibles, y en todo caso que el programa me interrogue acerca de cual usar, si
hubiese más de un puerto disponible.
entonces la pantalla me devuelve 888 = 0378h (o la dirección del LPT1, que puede
no ser esa). Notar que este programa es idéntico a este otro:
DEF SEG = 64
adr = PEEK(8) + 256 * PEEK(9)
PRINT adr
END
DEF SEG = 0
adr = PEEK(1032) + 256 * PEEK(1033)
PRINT adr
END
Esto se comprende teniendo en cuenta que, como antes se dijo, cada segmento
tiene 16 bytes. Luego, hasta el segmento 40h = 64d hay 64 segmentos (desde el 0
hasta el 63) de 16 bytes cada uno, lo que hace 64 x 16 = 1024 bytes. Pero el LPT1
está en el 8º y 9º byte del 64º segmento, luego en PEEK debo poner 1024 + 8 =
1032 y el siguiente, 1033. De esta manera PEEK me devuelve la dirección del
LPT1.
DEF SEG = 0
adr = PEEK(1032) + 256 * PEEK(1033)
PRINT HEX$(adr)
END
Se recomienda hacer todos estos ejemplos en cualquier PC, por obvios que nos
parezcan!
Tal como hemos dicho en "Arquitectura interna....", pág. 17 (Anatomía del puerto
paralelo), si bien identificamos al LPT1 como 0378h, éste en realidad es el primero
de los 8 registros de 8 bit cada uno que tiene reservados el puerto LPT1. De estos
ocho registros, en nuestro curso sólo utilizaremos los tres primeros, el 0378h,
0379h y 037Ah (o, lo que es lo mismo, si igualamos la variable adr = 888, los tres
registros usados serán adr, adr+1 y adr+2). Notar que adr = 888 es lo mismo que
adr = &H378 para Qbasic.
Estas tres direcciones de registros son las mismas a las que hicimos referencia
como Dirección Base, Dirección Base + 1 y Dirección Base + 2 en los tres
cuadros vistos en las páginas 17 y 18 de "Arquitectura interna....", donde el
primero (Dirección Base) corresponde al Registro de Datos, y como tiene su
origen en la PC, es para enviar datos fuera de ella. El Registro de STATUS
(Dirección Base + 1) tiene su origen en el mundo exterior y se podrá usar para
ingresar datos dentro de la PC, y finalmente el Registro de Control (Dirección
Base + 2), tiene su origen en la PC y por lo tanto sirve también para enviar datos
fuera de ella. NOTA: Cuando decimos "tiene su origen en...", está claro que nos referimos al origen del
sentido del flujo de información, que obviamente puede ser desde PC hacia fuera de ella y viceversa, desde
el mundo exterior hacia la PC).
donde puerto% es un número entre 0 y 65.535 que identifica el puerto por donde
quiero sacar los datos de la PC, y datos% es un número entre 0 y 255, que es el
número que saldrá por el puerto cada vez que se ejecute la sentencia OUT.
Y eso es todo! Complicado? Realmente creo que no!! Y para qué sirve? Veamos...
OUT &H378,255
END
Capítulo 5: Programando el manejo del Puerto Paralelo: Fundamentos de Qbasic – 2001 15
Autor: Ing. Jorge J. Ferrero Bajado de: www.profesormolina.com.ar
Al ejecutarlo, verificaremos que los 8 leds conectados a los pines 2...9 (o sea el
registro de datos) han encendido, y permanecen encendidos.
Escribamos ahora este otro programa:
OUT &H378,0
END
OUT &H378,170
END
Al ejecutarlo, vemos que prenden los leds 2º, 4º, 6º y 8º. Ya nos estamos
imaginando lo que sigue: El número 255d = 1111 1111b; el 0d = 0000 0000b y el
170d = 1010 1010b. O sea que a través del registro de datos del puerto paralelo
puedo sacar de esta manera, en forma binaria, cualquier número comprendido entre
0 y 255 (ya que solo estoy usando 8 bits). De esta forma es que se puede enviar,
por ejemplo, cualquier letra (mediante su correspondiente código ASCII), por
ejemplo, a la impresora (que es para lo que fue creado el puerto paralelo).
Pero más importante aún, para nosotros que queremos controlar el mundo, es que
de esta manera podemos enviar una señal eléctrica (un 1 lógico) o un conjunto de
señales, como consecuencia de la medición de un evento y una determinada
programación (que se puede hacer en Qbasic) para controlar una acción
determinada. Para poder medir un evento, necesitamos saber ingresar datos a la
PC, y esto lo haremos mediante la sentencia INP.
INP puerto%
donde puerto% es un número entre 0 y 65535 que indica la dirección del registro
que se debe leer. Como ya estamos imaginando, en nuestro caso, la única dirección
posible que vamos a leer, es la dirección de base + 1 (por ejemplo, &H379), por
ser la única que ingresa datos desde el mundo exterior con la configuración de
puerto SPP unidireccional.
denuevo:
x = INP (&H379)
PRINT x
goto denuevo
La solución del problema simplemente consiste en "levantar" bit por bit lo que
ingrese al registro de status, y esto es muy fácil hacerlo mediante la sentencia
AND del álgebra booleana. Después mediante programación, componemos los bits
levantados en función de nuestra conveniencia. Veamos como se hace:
Recordemos que
entonces, haciendo el número levantado del registro AND 8, 16, 32, 64 o 128,
obtendré el estado del bit 3, 4, 5, 6 o 7 correspondiente. Veámoslo haciendo el
siguiente programa:
denuevo:
x = INP (&H379) AND 64
PRINT x
goto denuevo
Aquí se debe interpretar que "64" significa 0100 0000, es decir 1 lógico en el bit 6.
Si me interesa mostrar en la pantalla el 1 lógico o el 0 lógico, simplemente uso este
programa:
denuevo:
x = (INP (&H379) AND 64)/64
PRINT x
goto denuevo
denuevo:
x = INP (&H379) AND 16
PRINT x
goto denuevo
denuevo:
x = (INP (&H379) AND 16)/16
PRINT x
goto denuevo