Para realizar el control de dispositivos mediante el puerto paralelo debemos hacer uso de las funciones de QBasic que permiten acceder a los puertos hardware. En lo que sigue se proporcionan unos ejemplos básicos de la programación de la E/S por el puerto paralelo. Estos ejemplos se presentan con un grado de estructuración creciente en el estilo de programación.
En el primer ejemplo se supone que el PC está equipado con un puerto
paralelo de tipo estándar localizado en la dirección 0x378
,
como suele ser habitual, de modo que el registro
de datos se localiza en esa misma dirección y el de estado
en 0x378+1
. En el ejemplo se envía un byte a las líneas de datos y se recibe un byte
de las líneas de estado con las
funciones OUT
e INP
utilizando
un estilo de programación muy básico:
' CTRL.BAS ' Ejemplo básico de E/S digital mediante el puerto paralelo ' Salidas: líneas de datos (bits D0-D7 del registro de datos) ' Entradas: líneas de estado (bits S3-S7 del registro de estado) ' ' 2002 Víctor R. González ' ' Suponemos puerto estándar en la dirección H378 ' ' byte para operaciones de E/S INPUT "Introduce el byte que se enviará al puerto: ", byte% OUT &H378, byte% ' envía un byte a las líneas de datos INPUT "Polariza las líneas de estado y pulsa <INTRO>", tecla byte% = INP(&H378 + 1) ' lee un byte de las líneas de estado PRINT "El valor leído es "; byte% END |
En el siguiente ejemplo se supone que el PC está equipado con un puerto
paralelo de tipo bidireccional localizado en la dirección 0x378
de modo que el registro
de datos se localiza en esa misma dirección y el de control
en 0x378+2
. El bit
C5
del registro de control se utiliza como conmutador del modo
salida (escritura en las líneas de datos) al modo entrada (lectura de las
líneas de datos). En el ejemplo se envía y se recibe un byte de las líneas de
datos del puerto aprovechando su capacidad bidireccional utilizando las
funciones OUT
e
INP
sin mayores
complicaciones en la programación:
' CTRL_0.BAS ' Ejemplo básico de E/S digital mediante el puerto paralelo ' ' 2002 Víctor R. González ' ' Suponemos puerto bidireccional (comprobar en BIOS) ' en la dirección H378 ' ' byte para operaciones de E/S INPUT "Introduce el byte que se enviará al puerto: ", byte% ' pone el puerto en modo salida (bit 5 del reg. CONTROL a 0) OUT &H378 + 2, 0 OUT &H378, byte% ' envía un byte INPUT "Polariza las líneas del puerto y pulsa <INTRO>", tecla ' pone el puerto en modo entrada (bit 5 del reg. CONTROL a 1) OUT &H378 + 2, 32 byte% = INP(&H378) ' lee un byte PRINT "El valor leído es "; byte% END |
El siguiente ejemplo es funcionalmente idéntico al anterior, aunque se hace
uso de las constantes de BASIC para dotar al programa de mayor elegancia y claridad.
También, facilita la reprogramación en caso de que, por ejemplo, el puerto no
se halle en la dirección supuesta. Obsérvese que la constante 0x378
sólo aparece ahora una vez en el código fuente, frente a las cuatro veces que
lo hacía en CTRL_0.BAS
. Se ha hecho uso
asimismo de la notación hexadecimal para los valores que activan y desactivan
el bit C5
del registro de control.
' CTRL_1.BAS ' Ejemplo básico de E/S digital mediante el puerto paralelo ' ' 2002 Víctor R. González ' ' Suponemos puerto bidireccional (comprobar en BIOS) ' en la dirección H378 ' CONST LPTBASE = &H378 ' dirección base del puerto paralelo CONST DATOS = LPTBASE ' dirección de E/S del reg. de datos CONST CONTROL = LPTBASE + 2 ' dirección de E/S del reg. de control CONST C5ON = &H20 ' bit 5 de control a 1 CONST C5OFF = &H0 ' bit 5 de control a 0 ' byte para operaciones de E/S INPUT "Introduce el byte que se enviará al puerto: ", byte% OUT CONTROL, C5OFF ' pone el puerto en modo salida OUT DATOS, byte% ' envía un byte INPUT "Polariza las líneas del puerto y pulsa <INTRO>", tecla OUT CONTROL, C5ON ' pone el puerto en modo entrada byte% = INP(DATOS) ' lee un byte PRINT "El valor leído es "; byte% END |
Todavía alguna sofisticación más: esta vez no es sólo maquillaje. Cuando
en los ejemplos anteriores hemos activado y desactivado el bit C5
,
hemos podido también modificar el estado del resto de los bits del registro de
control. Normalmente, es de buen gusto respetar el estado original del puerto
cuando uno finaliza la ejecución de su programa. Así pues, en el siguiente
ejemplo se lee en primer lugar el estado del registro de control y se almacena
en un byte (que llamamos ctrl%
). Cuando utilizamos OUT,
lo
hacemos de modo que únicamente modificamos individualmente el bit deseado, y no
todos. Finalmente escribimos el byte ctrl%
al registro de control
para recuperar el estado original. Obsérvese que se usa el operador ~
para
realizar el complemento a 1 de C5ON
, de modo que nos ahorramos el
definir otra constante simbólica para la condición de bit apagado.
' CTRL_2.BAS ' Ejemplo básico de E/S digital mediante el puerto paralelo ' ' 2002 Víctor R. González ' ' Suponemos puerto bidireccional (comprobar en BIOS) ' en la dirección H378 ' CONST LPTBASE = &H378 ' dirección base del puerto paralelo CONST DATOS = LPTBASE ' dirección de E/S del reg. de datos CONST CONTROL = LPTBASE + 2 ' dirección de E/S del reg. de control CONST C5ON = &H20 ' bit 5 de control a 1 ctrl% = INP(CONTROL) ' guarda el valor actual del reg. de control ' byte para operaciones de E/S INPUT "Introduce el byte que se enviará al puerto: ", byte% OUT CONTROL, ctrl% AND NOT (C5ON) ' pone el puerto en modo salida OUT DATOS, byte% ' envía un byte INPUT "Polariza las líneas del puerto y pulsa <INTRO>", tecla OUT CONTROL, ctrl% OR C5ON ' pone el puerto en modo entrada byte% = INP(DATOS) ' lee un byte PRINT "El valor leído es "; byte% OUT CONTROL, ctrl% ' restaura el valor original del reg. de control END |
Ahora un cambio significativo: vamos a determinar, y no a suponer, dónde se
halla situado el puerto paralelo (consúltese la sección correspondiente
de El Puerto Paralelo del PC para conocer
los detalles acerca de cómo determinar cuántos puertos se hallan instalados y
qué direcciones de E/S ocupan). Para ello accedemos a la zona de memoria donde
se registran las direcciones de los puertos paralelos presentes en el PC (en la zona
de las variables de la BIOS), por mediación de la función PEEK
. Una vez detectados los puertos presentes, nos quedamos con el primero y
programamos la entrada-salida exactamente igual que en CTRL_2.BAS
.
' CTRL_3.BAS ' Ejemplo básico de E/S digital mediante el puerto paralelo ' ' 2002 Víctor R. González ' CONST C5ON = &H20 ' bit 5 de control a 1 ' determina los puertos instalados y sus direcciones DEF SEG = 0 ' selecciona el segmento de memoria 0 FOR puerto% = 2 TO 0 STEP -1 ' número de puerto paralelo ' 0 (LPT1), 1 (LPT2), 2 (LPT3) ' dirección del puerto LPTBASE% = PEEK(&H408 + puerto% * 2) + 256 * PEEK(&H408 + puerto% * 2 + 1) IF LPTBASE% = 0 THEN PRINT "No hay puerto asignado a LPT"; puerto% + 1 ELSE PRINT "La dirección de LPT"; puerto% + 1; " es "; LPTBASE% END IF NEXT puerto% DATOS% = LPTBASE% ' dirección de E/S del reg. de datos CONTROL% = LPTBASE% + 2 ' dirección de E/S del reg. de control IF LPTBASE% > 0 THEN ' suponemos puerto bidireccional (comprobar en BIOS) ctrl% = INP(CONTROL%) ' guarda el valor actual del reg. de control ' byte para operaciones de E/S INPUT "Introduce el byte que se enviará al puerto: ", byte% OUT CONTROL%, ctrl% AND NOT (C5ON) ' pone el puerto en modo salida OUT DATOS%, byte% ' envía un byte INPUT "Polariza las líneas del puerto y pulsa <INTRO>", tecla OUT CONTROL%, ctrl% OR C5ON ' pone el puerto en modo entrada byte% = INP(DATOS%) ' lee un byte PRINT "El valor leído es "; byte% OUT CONTROL%, ctrl% ' restaura el valor original del reg. de control END IF END |
Por último, integraremos el código que localiza la dirección
del puerto en una función que devuelve dicha dirección. Para ello definimos la
función PuertoDir%
, sin argumentos y de tipo entero
.
Si dicha función no localiza ningún puerto devuelve un 0
, lo que
brinda al programa una posibilidad de terminar la ejecución cuando en un PC no
existe puerto paralelo disponible.
DECLARE FUNCTION PuertoDir% () ' determina la dirección del primer puerto ' ' CTRL_5.BAS ' Ejemplo básico de E/S digital mediante el puerto paralelo ' ' 2002 Víctor R. González ' CONST C5ON = &H20 ' bit 5 de control a 1 LPTBASE% = PuertoDir ' dirección base del primer puerto paralelo DATOS% = LPTBASE% ' dirección de E/S del reg. de datos CONTROL% = LPTBASE% + 2 ' dirección de E/S del reg. de control IF LPTBASE% > 0 THEN ' suponemos puerto bidireccional (comprobar en BIOS) ctrl% = INP(CONTROL%) ' guarda el valor actual del reg. de control ' byte para operaciones de E/S INPUT "Introduce el byte que se enviará al puerto: ", byte% OUT CONTROL%, ctrl% AND NOT (C5ON) ' pone el puerto en modo salida OUT DATOS%, byte% ' envía un byte INPUT "Polariza las líneas del puerto y pulsa <INTRO>", tecla OUT CONTROL%, ctrl% OR C5ON ' pone el puerto en modo entrada byte% = INP(DATOS%) ' lee un byte PRINT "El valor leído es "; byte% OUT CONTROL%, ctrl% ' restaura el valor original del reg. de control END IF END ' Determina la dirección del primer puerto paralelo FUNCTION PuertoDir% ' determina los puertos instalados y sus direcciones DEF SEG = 0 ' selecciona el segmento de memoria 0 FOR puerto% = 2 TO 0 STEP -1 ' número de puerto paralelo ' 0 (LPT1), 1 (LPT2), 2 (LPT3) ' dirección del puerto dir% = PEEK(&H408 + puerto% * 2) + 256 * PEEK(&H408 + puerto% * 2 + 1) IF dir% = 0 THEN PRINT "No hay puerto asignado a LPT"; puerto% + 1 ELSE PRINT "La dirección de LPT"; puerto% + 1; " es "; dir% END IF NEXT puerto% PuertoDir% = dir% END FUNCTION |
Todo lo anterior se puede realizar igualmente utilizando lenguaje TurboC. A continuación se ofrece el código fuente correspondiente a los programas BASIC anteriores en este lenguaje C. Obsérvense las acusadas similitudes, al menos a este nivel de programación, entre los códigos en C y en BASIC.
Para realizar el control de dispositivos mediante el puerto paralelo debemos hacer uso de las funciones de TurboC que permiten acceder a los puertos hardware. En lo que sigue se proporcionan unos ejemplos básicos de la programación de la E/S por el puerto paralelo. Estos ejemplos se presentan con un grado de estructuración creciente en el estilo de programación.
En el primer ejemplo se supone que el PC está equipado con un puerto
paralelo de tipo estándar localizado en la dirección 0x378
,
como suele ser habitual, de modo que el registro
de datos se localiza en esa misma dirección y el de estado
en 0x378+1
. En el ejemplo se envía un byte a las líneas de datos y se recibe un byte
de las líneas de estado con las
funciones outportb
e inportb
utilizando
un estilo de programación muy básico (código equivalente a CRTL.BAS
):
/* CTRL.C Ejemplo básico de E/S digital mediante el puerto paralelo Salidas: líneas de datos (bits D0-D7 del registro de datos) Entradas: líneas de estado (bits S3-S7 del registro de estado) 2002 Víctor R. González Suponemos puerto estándar en la dirección 0x378 */ #include <stdio.h> #include <dos.h> main () { unsigned char byte; /* byte para operaciones de E/S */ printf ("Introduce el byte que se enviará al puerto: "); scanf("%u", &byte); getchar(); outportb (0x378, byte); /* envía un byte a las líneas de datos */ printf ("Polariza las líneas de estado y pulsa una tecla\n"); getchar(); byte = inportb (0x378+1); /* lee un byte de las líneas de estado */ printf ("El valor leído es %i", byte); return 0; } |
En el siguiente ejemplo se supone que el PC está equipado con un puerto
paralelo de tipo bidireccional localizado en la dirección 0x378
de modo que el registro
de datos se localiza en esa misma dirección y el de control
en 0x378+2
. El bit
C5
del registro de control se utiliza como conmutador del modo
salida (escritura en las líneas de datos) al modo entrada (lectura de las
líneas de datos). En el ejemplo se envía y se recibe un byte de las líneas de
datos del puerto aprovechando su capacidad bidireccional utilizando las
funciones outportb
e inportb
sin mayores
complicaciones en la programación (código equivalente a CRTL_O.BAS
):
/* CTRL_0.C Ejemplo básico de E/S digital mediante el puerto paralelo 2002 Víctor R. González Suponemos puerto bidireccional (comprobar en BIOS) en la dirección 0x378 */ #include <stdio.h> #include <dos.h> main () { unsigned char byte; /* byte para operaciones de E/S */ printf ("Introduce el byte que se enviará al puerto: "); scanf("%u", &byte); getchar(); /* pone el puerto en modo salida (bit 5 del reg. CONTROL a 0) */ outportb (0x378+2, 0); outportb (0x378, byte); /* envía un byte */ printf ("Polariza las líneas del puerto y pulsa una tecla\n"); getchar(); /* pone el puerto en modo entrada (bit 5 del reg. CONTROL a 1: 00100000) */ outportb (0x378+2, 32); byte = inportb (0x378); /* lee un byte */ printf ("El valor leído es %i", byte); return 0; } |
El siguiente ejemplo es funcionalmente idéntico al anterior, aunque se hace
uso de las constantes
simbólicas de C para dotar el programa de mayor elegancia y claridad.
También, facilita la reprogramación en caso de que, por ejemplo, el puerto no
se halle en la dirección supuesta. Obsérvese que la constante 0x378
sólo aparece ahora una vez en el código fuente, frente a las cuatro veces que
lo hacía en CTRL_0.C
. Se ha hecho uso
asimismo de la notación hexadecimal para los valores que activan y desactivan
el bit C5
del registro de control (código equivalente a CRTL_1.BAS
):
/* CTRL_1.C Ejemplo básico de E/S digital mediante el puerto paralelo 2002 Víctor R. González Suponemos puerto bidireccional (comprobar en BIOS) en la dirección 0x378 */ #include <stdio.h> #include <dos.h> #define LPT_BASE 0x378 /* dirección base del puerto paralelo */ #define DATOS LPT_BASE /* dirección de E/S del reg. de datos */ #define CONTROL LPT_BASE+2 /* dirección de E/S del reg. de control */ #define C5_ON 0x20 /* bit 5 de CONTROL a 1 */ #define C5_OFF 0x00 /* bit 5 de CONTROL a 0 */ main () { unsigned char byte; /* byte para operaciones de E/S */ printf ("Introduce el byte que se enviará al puerto: "); scanf("%u", &byte); getchar(); outportb (CONTROL, C5_OFF ); /* pone el puerto en modo salida */ outportb (DATOS, byte); /* envía un byte */ printf ("Polariza las líneas del puerto y pulsa una tecla\n"); getchar(); outportb (CONTROL, C5_ON ); /* pone el puerto en modo entrada */ byte = inportb (DATOS); /* lee un byte */ printf ("El valor leído es %i", byte); return 0; } |
Todavía alguna sofisticación más: esta vez no es sólo maquillaje. Cuando
en los ejemplos anteriores hemos activado y desactivado el bit C5
,
hemos podido también modificar el estado del resto de los bits del registro de
control. Normalmente, es de buen gusto respetar el estado original del puerto
cuando uno finaliza la ejecución de su programa. Así pues, en el siguiente
ejemplo se lee en primer lugar el estado del registro de control y se almacena
en un byte (que llamamos ctrl
). Cuando utilizamos outportb,
lo
hacemos de modo que únicamente modificamos individualmente el bit deseado, y no
todos. Finalmente escribimos el byte ctrl
al registro de control
para recuperar el estado original. Obsérvese que se usa el operador ~
para
realizar el complemento a 1 de C5_ON
, de modo que nos ahorramos el
definir otra constante simbólica para la condición de bit apagado (código
equivalente a CRTL_2.BAS
):
/* CTRL_2.C Ejemplo básico de E/S digital mediante el puerto paralelo 2002 Víctor R. González Suponemos puerto bidireccional (comprobar en BIOS) en la dirección 0x378 */ #include <stdio.h> #include <dos.h> #define LPT_BASE 0x378 /* dirección base del puerto paralelo */ #define DATOS LPT_BASE /* dirección de E/S del reg. de datos */ #define CONTROL LPT_BASE+2 /* dirección de E/S del reg. de control */ #define C5_ON 0x20 /* bit 5 de CONTROL a 1 */ main () { unsigned char byte; /* byte para operaciones de E/S */ unsigned char ctrl; /* byte para estado de CONTROL */ ctrl = inportb(CONTROL); /* guarda el valor actual del reg. de CONTROL */ printf ("Introduce el byte que se enviará al puerto: "); scanf("%u", &byte); getchar(); outportb (CONTROL, ctrl & ~C5_ON ); /* pone el puerto en modo salida */ outportb (DATOS, byte); /* envía un byte */ printf ("Polariza las líneas del puerto y pulsa una tecla\n"); getchar(); outportb (CONTROL, ctrl | C5_ON ); /* pone el puerto en modo entrada */ byte = inportb (DATOS); /* lee un byte */ printf ("El valor leído es %i", byte); outportb (CONTROL, ctrl); /* restaura el valor original del reg. de CONTROL */ return 0; } |
Ahora un cambio significativo: vamos a determinar, y no a suponer, dónde se
halla situado el puerto paralelo (consúltese la sección correspondiente
de El Puerto Paralelo del PC para conocer
los detalles acerca de cómo determinar cuántos puertos se hallan instalados y
qué direcciones de E/S ocupan). Para ello accedemos a la zona de memoria donde
se registran las direcciones de los puertos paralelos presentes en el PC (en la zona
de las variables de la BIOS), por mediación de la función peek
. Una vez detectados los puertos presentes, nos quedamos con el primero y
programamos la entrada-salida exactamente igual que en CTRL_2.C
(código equivalente a CRTL_3.BAS
):
/* CTRL_3.C Ejemplo básico de E/S digital mediante el puerto paralelo 2002 Víctor R. González */ #include <stdio.h> #include <dos.h> #define LPT_BASE puerto_dir /* dirección base del puerto paralelo */ #define DATOS LPT_BASE /* dirección de E/S del reg. de datos */ #define CONTROL LPT_BASE+2 /* dirección de E/S del reg. de control */ #define C5_ON 0x20 /* bit 5 de CONTROL a 1 */ main () { unsigned char byte; /* byte para operaciones de E/S */ unsigned char ctrl; /* byte para estado de CONTROL */ int puerto; /* número de puerto paralelo: 0 (LPT1), 1 (LPT2), 2 (LPT3) */ unsigned int puerto_dir; /* dirección del puerto */ /* Determina los puertos instalados y sus direcciones */ for (puerto=2; puerto>=0; puerto--) { LPT_BASE = peek(0x0040,0x0008 + puerto*2); if (LPT_BASE == 0) printf("No hay puerto asignado a LPT%d \n", puerto+1); else printf("La dirección de LPT%d es 0x%X\n", puerto+1, LPT_BASE); } if (LPT_BASE > 0) { /* Suponemos puerto bidireccional (comprobar en BIOS) */ ctrl = inportb(CONTROL); /* guarda el valor actual del reg. de CONTROL */ printf ("Introduce el byte que se enviará al puerto: "); scanf("%u", &byte); getchar(); outportb (CONTROL, ctrl & ~C5_ON ); /* pone el puerto en modo salida */ outportb (DATOS, byte); /* envía un byte */ printf ("Polariza las líneas del puerto y pulsa una tecla\n"); getchar(); /* pone el puerto en modo entrada */ outportb (CONTROL, ctrl | C5_ON ); byte = inportb (DATOS); /* lee un byte */ printf ("El valor leído es %i", byte); outportb (CONTROL, ctrl); /* restaura el valor original del reg. de CONTROL */ } return 0; } |
De nuevo, una sofisticación más que hace ganar claridad al código fuente y
le proporciona mayor estructuración. Las constantes simbólicas que hemos
definido hasta ahora para manejo del puerto pueden formar parte de un conjunto
de definiciones que usaremos permanentemente cuando realicemos control con el
puerto paralelo y que, con seguridad, ampliaremos con el uso. Así, podemos
reunirlas en un archivo de cabecera (header) que incluiremos en todos
nuestros programas de control. Llamaremos, por ejemplo, ctrl.h
a
este archivo de cabecera.
/* CTRL_4.C Ejemplo básico de E/S digital mediante el puerto paralelo 2002 Víctor R. González */ #include <stdio.h> #include <dos.h> #include "ctrl.h" main () { unsigned char byte; /* byte para operaciones de E/S */ unsigned char ctrl; /* byte para estado de CONTROL */ int puerto; /* número de puerto paralelo: 0 (LPT1), 1 (LPT2), 2 (LPT3) */ /* Determina los puertos instalados y sus direcciones */ for (puerto=2; puerto>=0; puerto--) { LPT_BASE = peek(0x0040,0x0008 + puerto*2); if (LPT_BASE == 0) printf("No hay puerto asignado a LPT%d \n", puerto+1); else printf("La dirección de LPT%d es 0x%X\n", puerto+1, LPT_BASE); } if (LPT_BASE > 0) { /* Suponemos puerto bidireccional (comprobar en BIOS) */ lee_control (ctrl); /* guarda el valor actual del reg. de CONTROL */ printf ("Introduce el byte que se enviará al puerto: "); scanf("%u", &byte); getchar(); control ( ctrl & ~C5_ON ); /* pone el puerto en modo salida */ escribe (byte); /* envía un byte */ printf ("Polariza las líneas del puerto y pulsa una tecla\n"); getchar(); /* pone el puerto en modo entrada */ control ( ctrl | C5_ON ); lee (byte); /* lee un byte */ printf ("El valor leído es %i", byte); control (ctrl); /* restaura el valor original del reg. de CONTROL */ } return 0; } |
Vemos que en el programa anterior han desaparecido misteriosamente todas las
referencias a las funciones inportb
y outportb
, para
dejar paso a otras como escribe
, lee
, lee_control
y control
. Ello es porque, además, en ctrl.h
hemos
definido unas macros con
dichos nombres, de forma que la notación del programa resulta más breve y
cómoda. Con una ventaja adicional muy interesante: si en algún momento
queremos utilizar nuestros programas usando otro compilador diferente,
seguramente las funciones de E/S no se llamarán exactamente inportb
y outportb
(aunque los nombres serán parecidos). Si esto sucede,
un ligero retoque en nuestro archivo de cabecera permitirá dejar intactos el
resto de los programas que hayamos realizado. De lo contrario, habría que
seguir todas las línea de código de todos los programas para modificar la
sintaxis de la referencia a dichas funciones. Véase a continuación cómo queda
el mencionado archivo de cabecera.
/* CTRL.H Declaraciones. constantes y macros para ejemplo básico de E/S digital mediante el puerto paralelo 2002 Víctor R. González */ unsigned int puerto_dir; /* dirección del puerto */ #define LPT_BASE puerto_dir /* dirección base del puerto paralelo */ #define DATOS LPT_BASE /* dirección de E/S del reg. de datos */ #define CONTROL LPT_BASE+2 /* dirección de E/S del reg. de control */ #define C5_ON 0x20 /* Bit 5 de CONTROL a 1 */ #define escribe(byte) outportb (DATOS, byte) /* escribe un byte en el puerto */ #define lee(byte) (byte = inportb (DATOS)) /* lee un byte del puerto */ #define control(byte) outportb (CONTROL, byte) /* escribe un byte en las líneas de control */ #define lee_control(byte) (byte = inportb (CONTROL)) /* lee un byte de las líneas de control */ |
Por último, integraremos el código que localiza la dirección
del puerto en una función que devuelve dicha dirección. Para ello definimos la
función PuertoDir()
, sin argumentos y de tipo unsigned int
.
Si dicha función no localiza ningún puerto devuelve un 0
, lo que
brinda al programa una posibilidad de terminar la ejecución cuando en un PC no
existe puerto paralelo disponible (código equivalente a CRTL_5.BAS
):
/* CTRL_5.C Ejemplo básico de E/S digital mediante el puerto paralelo 2002 Víctor R. González */ #include <stdio.h> #include <dos.h> #include "ctrl.h" unsigned int PuertoDir(); /* Determina la dirección del primer puerto */ main () { unsigned char byte; /* byte para operaciones de E/S */ unsigned char ctrl; /* byte para estado de CONTROL */ if (PuertoDir > 0) { /* Suponemos puerto bidireccional (comprobar en BIOS) */ lee_control (ctrl); /* guarda el valor actual del reg. de CONTROL */ printf ("Introduce el byte que se enviará al puerto: "); scanf("%u", &byte); getchar(); control ( ctrl & ~C5_ON ); /* pone el puerto en modo salida */ escribe (byte); /* envía un byte */ printf ("Polariza las líneas del puerto y pulsa una tecla\n"); getchar(); /* pone el puerto en modo entrada */ control ( ctrl | C5_ON ); lee (byte); /* lee un byte */ printf ("El valor leído es %i", byte); control (ctrl); /* restaura el valor original del reg. de CONTROL */ } return 0; } unsigned int PuertoDir () { int puerto; /* número de puerto paralelo: 0 (LPT1), 1 (LPT2), 2 (LPT3) */ /* Determina los puertos instalados y sus direcciones */ for (puerto=2; puerto>=0; puerto--) { LPT_BASE = peek(0x0040,0x0008 + puerto*2); if (LPT_BASE == 0) printf("No hay puerto asignado a LPT%d \n", puerto+1); else printf("La dirección de LPT%d es 0x%X\n", puerto+1, LPT_BASE); } return LPT_BASE; } |
Puesto que se trata de un montaje inicial, en el que se es posible sacrificar el orden respecto de la sencillez, se puede llevar a cabo uniendo directamente con regletas los componentes a los cables, e introduciendo estos en en las hembrillas del conector del PC. Por supuesto, es preferible realizar montajes más estables del estilo de los que se exponen en la actividad 2: Interfaces básicos de E/S con el p. paralelo: salidas-entradas digitales.
Nota: no es preciso puentear exteriormente entre sí las líneas 18-25 puesto que cada una de ellas es ya la tierra del puerto.En éste montaje se ha conectado un LED (salida digital) en el pin 2 del puerto (bit D0 del registro de datos) y un interruptor (entrada digital) en el pin 15 (bit S3 del registro de estado).
- Realícese un programa en QBasic para la iluminación del LED y para la detección del estado del interruptor (véase el programaCTRL.BAS
de la sección Programación básica de la E/S en QBasic).
- Realícese un programa en TurboC para la iluminación del LED y para la detección del estado del interruptor (véase el programaCTRL.C
de la sección Programación básica de la E/S en TurboC).
![]()
Ahora se supone que el puerto paralelo tiene capacidad bidireccional y se ha conectado el interruptor (entrada digital) en el pin 3 del puerto (bit D1 del registro de datos).
- Realícese un programa en QBasic para la iluminación del LED y para la detección del estado del interruptor (véase el programaCTRL_0.BAS
de la sección Programación básica de la E/S en QBasic).
- Realícese un programa en TurboC para la iluminación del LED y para la detección del estado del interruptor (véase el programaCTRL_0.C
de la sección Programación básica de la E/S en TurboC).