Actividad 2:
Interfaces básicos de E/S con el p. paralelo:
salidas-entradas digitales

 

 

Circuito sin alimentación externa

Se trata de un circuito muy sencillo que usa un mínimo de componentes y proporciona un test funcional de 8 bits. Cada bit de la entrada puede ser individualmente controlado y visualizado en los LED de salida. Los diodos LED que actúan de display se alimentan únicamente con la corriente proporcionada por las propias salidas del puerto. Sería preferible alimentar los LED y utilizar la corriente absorbida para iluminarlos, pero el conector no proporciona una señal de alimentación (Vcc), de modo que se necesitaría una fuente externa. Eléctricamente, el puerto paralelo entrega señales TTL y como tal, teóricamente, se le puede conectar cualquier dispositivo que cumpla con los niveles de voltaje específicos de la lógica TTL, sin embargo el hardware del puerto paralelo está muy limitado en cuanto a su capacidad de manejo de corriente, por ésta razón se debe ser muy cuidadoso con el manejo de las señales del puerto: un cortocircuito puede dañar permanentemente la tarjeta madre del PC. Sin embargo, experimentalmente se comprueba que en la mayoría de los PC el puerto proporciona corriente suficiente para una clara indicación visual de los LED.    

Las líneas de datos (D0-D7, pines 2-9) se utilizan como líneas de salida, e iluminan los LED cuando en ellas se fija por software un 1 lógico (+5 V). Cuando se fija un 0 lógico, los LED se apagan. Como entradas se utilizan, como nibble (semibyte) bajo, las cuatro líneas asociados al registro de control (C0,C1,C2 y C3, pines 1, 14, 16 y 17) y, como nibble alto, cuatro de las líneas asociadas al registro de estado (S4,S5,S6 y S7, pines 13, 12, 10 y 11).

Obsérvese que las líneas de control se utilizan normalmente como salidas. Sin embargo, aquí deben ser configuradas como entradas. Obsérvese, asimismo, que cuatro de las líneas de entrada se corresponden con bits que utilizan lógica negativa (C0,C1,C3 y S7). Esto habrá de tenerse en cuenta cuando se realice el programa de control de esta interfaz.

Los detalles sobre el montaje de éste y los posteriores circuitos se pueden consultar en Actividades.

Volver al principio de página

 

Circuito con alimentación externa

Fijémonos ahora solamente en una de las líneas de entrada y en una de las líneas de salida. Un circuito como el siguiente utiliza una fuente externa de +5 V para alimentar los diodos LED y las señales de entrada.

Un 1 lógico en D7 (bit 7 del puerto de DATOS) produce que el LED se apague. Un 0 lógico produce la iluminación del LED. El interruptor normalmente abierto S produce que aparezca un 1 lógico (+5 V) en la entrada Busy (registro de ESTADO, S7). Cuando se cierra S un 0 lógico (GND) se aplica a la entrada Busy.

Un circuito como el precedente para las 8 líneas de entrada y salida es un alternativa al propuesto en la sección anterior.

Volver al principio de página

 

Circuito con alimentación externa y etapa separadora

Para disminuir lo más posible el riesgo de daños al puerto se puede utilizar un circuito integrado 74LS244 como etapa separadora en las líneas de salida. Al mismo tiempo se mejora la capacidad de manejo de corriente, de forma que se pueden conectar sin riesgo la serie de diodos LED que indican la actividad en las líneas de datos del puerto paralelo. El circuito se detalla en el siguiente diagrama:

Por cada línea de entrada que tomamos directamente del puerto paralelo existe una etapa amplificadora-separadora dentro del circuito integrado 74LS244 que nos permite trabajar con una tasa de entrega de corriente suficiente para desplegar en los diodos emisores de luz la información escrita en las líneas de datos del puerto. Además es posible habilitar ó deshabilitar el despliegue del nibble de orden inferior ó superior del byte escrito en el puerto. Colocando en un nivel lógico alto el pin 1 del CI 74LS244 inhabilitamos el despliegue del nibble de orden bajo y un nivel lógico alto en la patita 19 evita el despliegue del nibble de orden alto. Por comodidad, se conectan las patitas 1 y 19 permanentemente a tierra de tal manera que sea posible visualizar la actividad en los diodos LED.

Este circuito, al igual que el anterior y el siguiente, necesita de alimentación externa. Se puede alimentar directamente mediante una fuente de +5 V, o construir ésta usando una pila de 9 V o un adaptador universal, y un regulador de voltaje 7805. El 7805 puede regular cualquier voltaje  de entre 7 y 25 V c.c. hasta los 5 V que precisa el circuito

Volver al principio de página

 

Circuito bidireccional con alimentación externa

El siguiente circuito aprovecha la capacidad bidireccional del puerto paralelo de la práctica totalidad de los PCs actuales. Así, las 8 líneas de datos del puerto (D0-D8) se pueden utilizar a modo de un bus de datos que, en ocasiones contiene los valores que serán leídos por la computadora y, otras veces, transporta los datos que ésta envía a la salida digital. No es preciso ahora utilizar las líneas de estado y de control del puerto a modo de entradas, como se hacía en el circuito sin alimentación externa. El esquema se observa en la siguiente figura:

 

Este circuito utiliza los siguientes CI:

Ambos integrados se controlan mediante el bit C0 del registro de control. Cuando el pin 1 se halla en alto, los datos escritos por el puerto se transfieren a los LED mediante el 74573, mientras que el 74245 está aislado del bus de datos. Cuando el pin 1 está bajando, los datos a su entrada se conservan en la salida. Cuando el pin 1 está bajo el 74245 se habilita y los datos presentes en su entrada se transfieren a su salida y pueden ser leídos por el programa.

El bit C5 se utiliza como control de las operaciones de lectura/escritura del puerto bidireccional. El programa debe fijar tanto C0 como C5 a 0 para realizar una escritura (es decir, debe escribir un valor decimal 0 el el registro de control). Para llevar a cabo una lectura ambos bits deben ser establecidos a 1 (es decir, debe escribir un valor hexadecimal 0x21, o decimal 33, en el registro de control).

Volver al principio de página

 

Display de 7 segmentos

Una posibilidad es sustituir en los montajes anteriores el sistema de visualización mediante 8 diodos LED por un display numérico de 7 segmentos más un punto decimal. El circuito resulta así más compacto.

Si se trata de un display de ánodo común hay que alimentar con Vcc= +5 V las dos líneas señaladas como comunes en la figura, y es preciso poner a tierra la línea correspondiente al segmento que se quiere iluminar. Si se trata de un display de cátodo común, hay que alimentar con +5 V el segmento que se desea iluminar y poner a tierra las dos líneas comunes.

Así, en un display de cátodo común, las líneas 1-8 se pueden conectar directamente a las líneas de datos del puerto (pines 2-9 del conector DB25), y las dos líneas comunes se pueden conectar a cualquiera de las patillas de tierra del conector, por ejemplo, la 25.

Volver al principio de página

 

Actividades

Montaje de los circuitos anteriores

Los circuitos se pueden montar sobre una placa tipo "protoboard" y utilizar cable rígido para realizar las conexiones necesarias entre los componentes.

Placa "protoboard" simple

Las entradas/salidas del circuito hacia el PC se pueden reunir en un conector DB25 macho unido a la placa por líneas de cable rígido o de cable plano. A su vez, el conector macho se puede unir directamente al conector hembra del PC mediante un cable de extensión paralelo, lo que normalmente resulta más cómodo para acceder a la parte trasera del PC donde se sitúa el conector hembra.

Conector DB25 macho con líneas de cable rígido.
Otra posibilidad, utilizar cable plano.
Cable de extensión paralelo.

Para simplificar los circuitos que utilizan interruptores a modo de entradas digitales, éstos se pueden reunir en un único DIP switch de ocho posiciones. También, por una cuestión de orden, las líneas que proviene del conector macho pueden introducirse en la placa mediante regletas apilables como las mostradas en la figura.

 

DIP switch (izquierda) y regletas (derecha).

Conector DB25 macho con líneas de salida, entrada y tierra finalizadas en regletas. Ejemplo de circuito terminado, conectado al PC.

Naturalmente, una vez finalizado el circuito, lo más recomendable es probar el correcto funcionamiento del mismo antes de conectarlo al puerto paralelo del PC. Una vez ensamblado, se puede alimentar con una fuente regulada de +5 V y conectar temporalmente los pines del conector DB25 macho a tierra o a + 5 V, según se necesite (un adaptador universal estabilizado, que da normalmente tensiones entre 1.5 V y 12 V, es una solución válida y barata, y sirve también para los circuitos que requieren alimentación externa, los que utilizan motores de distintas clases, etc). Una vez que se ha verificado el correcto funcionamiento del circuito, está listo para conectarlo al puerto paralelo del PC.

Para conectar el circuito al puerto apáguese en primer lugar la computadora. Conéctese el cable al puerto paralelo asegurándose que el conector esté firme en su lugar. Aliméntese el circuito (si procede) y por último enciéndase la computadora. Por regla general, el circuito de restablecimiento de la computadora coloca inicialmente en las líneas de datos del puerto paralelo un valor igual a 0x0h. Por tanto, todos los diodos deben estar apagados una vez que la computadora ha terminado su proceso de arranque. Sin embargo, si algún diodo permanece encendido esto no indica necesariamente un fallo, y es responsabilidad del software de control que se escriba inicializarlo con un valor adecuado antes de realizar cualquier otra operación.

Ejemplo de montaje del circuito sin alimentación externa, al que también se le ha añadido el display de 7 segmentos.

 

Programas de control del interfaz básico de E/S

 

        Soluciones:

'	ENT_SAL.BAS
'
'       CONTROL DE ACTUADORES Y SENSORES MEDIANTE PUERTO PARALELO
'
'       Programaci¢n de la interface b sica de 8 LED y 8 microinterruptores
'       Actuadores - LED en las 8 l¡neas de DATOS:
'                                                7   6   5   4   3   2   1   0
'                                               D7  D6  D5  D4  D3  D2  D1  D0
'
'       Sensores   - DIP switch de 8 pos. en 4 l¡neas de CONTROL y 4 de ESTADO:
'                                                7   6   5   4   3   2   1   0
'                                               S7# S6  S5  S4  C3# C2  C1# C0#
'
'       2002 Víctor R. González

DECLARE SUB Espera (segundos AS SINGLE)

' Direcciones del puerto paralelo
CONST LPTBASE = &H378
CONST DATOS = LPTBASE
CONST ESTADO = LPTBASE + 1
CONST CONTROL = LPTBASE + 2

DIM byte AS INTEGER
DIM i AS INTEGER, j AS INTEGER

	' Control de actuadores digitales (8 diodos LED en el puerto de DATOS)
	PRINT "Control de salidas digitales (valor > 255 para fin):"
	byte = 0        ' La primera vez apaga los diodos (envía 0)
	DO WHILE byte < 256
		OUT DATOS, byte

		INPUT "   Introduce el byte que se enviará al puerto: ", byte
	LOOP


	' Control de sensores digitales (8 microinterruptores -DIP switch-
	'  4 en líneas de CONTROL y 4 en líneas de ESTADO)
	PRINT "Control de entradas digitales (f<intro> para fin):"
	OUT CONTROL, &H4        ' Pone CONTROL en modo entrada (si posible)
	DO
		byte = ((INP(CONTROL) AND &HF) OR (INP(ESTADO) AND &HF0)) XOR &H8B

		PRINT "   Byte leído del puerto: "; byte

	LOOP UNTIL INKEY$ = "f"


	' Interacción de actuadores y sensores
	PRINT "Realimentaci¢n de las salidas con las entradas digitales (f<intro> para fin):"
	PRINT "    entrada <  16 = dirige la entrada a la salida"
	PRINT "    entrada <  32 = destello impares"
	PRINT "    entrada <  64 = destello pares"
	PRINT "    entrada < 128 = intermitencia 5 s"
	PRINT "    entrada < 256 = destello progresivo"
	DO
		' Toma nibble bajo de CONTROl y alto de ESTADO
		' e invierte bits 0, 1, 3 y 7
		byte = ((INP(CONTROL) AND &HF) OR (INP(ESTADO) AND &HF0)) XOR &H8B
		PRINT "   Byte le¡do: "; byte

		SELECT CASE byte
			CASE IS < 16    ' Envía el valor de la entrada a la salida
				OUT DATOS, byte

			CASE IS < 32    ' Realiza un destello en las salidas impares
				OUT DATOS, 85   ' Enciende
				Espera .5
				OUT DATOS, 0    ' Apaga

			CASE IS < 64    ' Realiza un destello en las salidas pares
				OUT DATOS, 170  ' Enciende
				Espera .5
				OUT DATOS, 0    ' Apaga

			CASE IS < 128   ' Intermitencia durante 5 segundos
				FOR i = 1 TO 10
					OUT DATOS, 0:    Espera .25     ' Apaga
					OUT DATOS, 255: Espera .25      ' Enciende todos
				NEXT i

			CASE ELSE       ' Destello progresivo
				FOR i = 1 TO 10
					j = 7
					DO
						OUT DATOS, j
						Espera .05
						j = j * 2
					LOOP WHILE j <= 224
					j = 224
					DO
						OUT DATOS, j
						Espera .05
						j = j / 2
					LOOP WHILE j >= 7
				NEXT i
		END SELECT

	LOOP UNTIL INKEY$ = "f"

END

' Rutina de espera
SUB Espera (segundos AS SINGLE)

	tIni! = TIMER
	DO WHILE TIMER - tIni! < segundos: LOOP

END SUB

En la parte de control de sólo las entradas digitales existen dos sentencias, indicadas con negrita en el cuadro siguiente:

	OUT CONTROL, &H4	' Pone CONTROL en modo entrada (si posible) 
	DO
		byte = ( (INP(CONTROL) AND &HF) OR (INP(ESTADO) AND &HF0) ) XOR &H8B

		PRINT "   Byte leído del puerto: "; byte

	LOOP UNTIL INKEY$ = "f"

y que merecen una explicación detallada.

La primera de ellas: OUT CONTROL, &H4 permite utilizar las cuatro líneas de control como líneas de entrada. Recuérdese que, estrictamente, son de salida. Sin embargo, al poner las líneas en alto escribiendo 0100, es decir, 0x04, en LPT_BASE+2, la dirección del registro de control (bits C3-C2-C1-C0), se hace que las salidas "floten" y que un dispositivo externo pueda forzar a bajo alguna de las salidas. Esto podría no ser posible en todos los puertos. Sin embargo, en algún puerto que en principio aparentemente no es posible, se consigue si lo configuramos en modo SPP o en la emulación SPP del modo ECP

La segunda: byte = ( (INP(CONTROL) AND &HF) OR (INP(ESTADO) AND &HF0) ) XOR &H8B , lee un byte de las entradas del interface de la siguiente manera: extrae los cuatro bits bajos del registro de control (bits C3-C2-C1-C0), los cuatro bits altos del registro de estado (bits S7-S6-S5-S4), los concatena e invierte todos los bits que sea necesario (dado que los bits C3,C1,C0 y S7 se utilizan en lógica negativa). Para ello, se utilizan los operadores de manipulación de bits AND, OR y XOR que proporciona Qbasic. La operación se explica paso a paso y gráficamente en lo que sigue. En las tablas que figuran a continuación una X o una Y indican bits que se necesitan finalmente mientras que ? indica bits prescindibles. Asimismo, el color azul indica bits en lógica positiva mientras que el color rojo y el suprarrayado indican bits en lógica negativa (estos últimos necesitarán ser invertidos).

INP(CONTROL) AND &HF

INP(CONTROL)
? ? ? ? X X X X
&HF
0 0 0 0 1 1 1 1
AND
0 0 0 0 X X X X

INP(ESTADO) AND &HF0

INP(ESTADO)

Y Y Y Y ? ? ? ?
&HF0
1 1 1 1 0 0 0 0
AND 
Y Y Y Y 0 0 0 0

(INP(CONTROL) AND &HF) OR (INP(ESTADO) & &HF0)

INP(CONTROL) AND &HF
Y Y Y Y 0 0 0 0
INP(ESTADO) AND &HF0
0 0 0 0 X X X X
OR
Y Y Y Y X X X X

byte = ( (INP(CONTROL) AND &HF) OR (INP(ESTADO) AND &HF0) ) XOR &H8B

(INP(CONTROL) AND &HF) OR (INP(ESTADO) AND &HF0)
Y Y Y Y X X X X
&H8B
1 0 0 0 1 0 1 1
XOR
Y Y Y Y X X X X

/*	ENT_SAL.C
	CONTROL DE ACTUADORES Y SENSORES MEDIANTE PUERTO PARALELO

	Programación de la interface básica de 8 LED y 8 microinterruptores
	Actuadores - LED en las 8 líneas de DATOS:
						 7   6   5   4   3   2   1   0
						D7  D6  D5  D4  D3  D2  D1  D0

	Sensores   - DIP switch de 8 pos. en 4 líneas de CONTROL y 4 de ESTADO:
						 7   6   5   4   3   2   1   0
						S7# S6  S5  S4  C3# C2  C1# C0#

	2002 Víctor R. González
*/

#include <stdio.h>
#include <dos.h>

/* Direcciones del puerto paralelo */
#define LPT_BASE	0x378
#define DATOS		LPT_BASE
#define ESTADO		LPT_BASE+1
#define CONTROL		LPT_BASE+2


main ()
{
	unsigned byte;
	unsigned i, j;

	/* Control de actuadores digitales (8 diodos LED en el puerto de DATOS) */
	printf ("Control de salidas digitales (valor > 255 para fin):\n");
	byte = 0;	/* La primera vez apaga los diodos (envía 0) */
	while (byte < 256) {
		outportb (DATOS, byte);

		printf ("   Introduce el byte que se enviará al puerto: ");
		scanf ("%u", &byte);	getchar();
	 }


	/* Control de sensores digitales (8 microinterruptores -DIP switch-
	   4 en líneas de CONTROL y 4 en líneas de ESTADO) */
	printf ("\nControl de entradas digitales (f<intro> para fin):\n");
	outportb (CONTROL, 0x04);	/* Pone CONTROL en modo entrada (si posible) */
	do {
		byte = ((inportb(CONTROL) & 0x0F) | (inportb(ESTADO) & 0xF0)) ^ 0x8B;

		printf ("   Byte leído del puerto: %u   ", byte);

	} while (getchar() == '\n');
	getchar();


	/* Interacción de actuadores y sensores */
	printf ("\nRealimentación de las salidas con las entradas digitales (f<intro> para fin):");
	printf ("\n\t entrada <  16 = dirige la entrada a la salida");
	printf ("\n\t entrada <  32 = destello impares");
	printf ("\n\t entrada <  64 = destello pares");
	printf ("\n\t entrada < 128 = intermitencia 5 s");
	printf ("\n\t entrada < 256 = destello progresivo\n");
	do {
		/* Toma nibble bajo de CONTROl y alto de ESTADO
		e invierte bits 0, 1, 3 y 7 */
		byte = (inportb(CONTROL) & 0x0F | inportb(ESTADO) & 0xF0) ^ 0x8B;
		printf ("   Byte leído: %u   ", byte);

		if (byte < 16)			/* Envía el valor de la entrada a la salida */
			outportb (DATOS, byte);

		else if (byte < 32) {	/* Realiza un destello en las salidas impares */
			outportb (DATOS, 85);	/* Enciende */
			delay (500);
			outportb (DATOS, 0);	/* Apaga */
		}
		else if (byte < 64) {	/* Realiza un destello en las salidas pares */
			outportb (DATOS, 170);	/* Enciende */
			delay (500);
			outportb (DATOS, 0);	/* Apaga */
		}
		else if (byte < 128)	/* Intermitencia durante 5 segundos */
			for (i=1; i<=10; i++ ) {
				outportb (DATOS, 0);	delay (250);	/* Apaga */
				outportb (DATOS, 255);	delay (250);	/* Enciende todos */
			}

		else					/* Destello progresivo */
			for (i=1; i<=10; i++ ) {
				for (j=7; j<=224; j*=2) {
					outportb (DATOS, j);
					delay(50);
				}
				for (j=224; j>=7; j/=2) {
					outportb (DATOS, j);
					delay(50);
				}
			}

	} while (getchar() == '\n');

	return 0;
}

En la parte de control de sólo las entradas digitales existen dos sentencias, indicadas con negrita en el cuadro siguiente:

	outportb (CONTROL, 0x04);	/* Pone CONTROL en modo entrada (si posible) */
	do {
		byte = ((inportb(CONTROL) & 0x0F) | (inportb(ESTADO) & 0xF0)) ^ 0x8B;

		printf ("   Byte leído del puerto: %u   ", byte);

	} while (getchar() == '\n');

y que merecen una explicación detallada.

La primera de ellas: outportb (CONTROL, 0x04); permite utilizar las cuatro líneas de control como líneas de entrada. Recuérdese que, estrictamente, son de salida. Sin embargo, al poner las líneas en alto escribiendo 0100, es decir, 0x04, en LPT_BASE+2, la dirección del registro de control (bits C3-C2-C1-C0), se hace que las salidas "floten" y que un dispositivo externo pueda forzar a bajo alguna de las salidas. Esto podría no ser posible en todos los puertos. Sin embargo, en algún puerto que en principio aparentemente no es posible, se consigue si lo configuramos en modo SPP o en la emulación SPP del modo ECP

La segunda: byte = ((inportb(CONTROL) & 0x0F) | (inportb(ESTADO) & 0xF0)) ^ 0x8B; , lee un byte de las entradas del interface de la siguiente manera: extrae los cuatro bits bajos del registro de control (bits C3-C2-C1-C0), los cuatro bits altos del registro de estado (bits S7-S6-S5-S4), los concatena e invierte todos los bits que sea necesario (dado que los bits C3,C1,C0 y S7 se utilizan en lógica negativa). Para ello, se utilizan los operadores de manipulación de bits & (AND), | (OR) y ^ (XOR) que proporciona C. La operación se explica paso a paso y gráficamente en lo que sigue. En las tablas que figuran a continuación una X o una Y indican bits que se necesitan finalmente mientras que ? indica bits prescindibles. Asimismo, el color azul indica bits en lógica positiva mientras que el color rojo y el suprarrayado indican bits en lógica negativa (estos últimos necesitarán ser invertidos).

inportb(CONTROL) & 0x0F

inportb(CONTROL)
? ? ? ? X X X X
0x0F
0 0 0 0 1 1 1 1
& (AND)
0 0 0 0 X X X X

inportb(ESTADO) & 0xF0

inportb(ESTADO)

Y Y Y Y ? ? ? ?
0xF0
1 1 1 1 0 0 0 0
& (AND) 
Y Y Y Y 0 0 0 0

(inportb(CONTROL) & 0x0F) | (inportb(ESTADO)& 0xF0)

inportb(ESTADO)& 0xF0
Y Y Y Y 0 0 0 0
inportb(CONTROL)& 0x0F
0 0 0 0 X X X X
| (OR)
Y Y Y Y X X X X

byte = ((inportb(CONTROL) & 0x0F) | (inportb(ESTADO) & 0xF0)) ^ 0x8B

(inportb(CONTROL) & 0x0F) | (inportb(ESTADO) & 0xF0)
Y Y Y Y X X X X
0x8B
1 0 0 0 1 0 1 1
^ (XOR)
Y Y Y Y X X X X

Soluciones:

'   DISPLAY7.BAS
'   CONTROL DE ACTUADORES Y SENSORES MEDIANTE PUERTO PARALELO
'
'   Programación de un display de 7 segmentos de cátodo común
'   Segmentos y punto decimal en las 8 líneas de DATOS:
'
'   punto  seg.7  seg.6  seg.5  seg.4  seg.3  seg.2  seg.1
'     D7    D6     D5     D4     D3     D2     D1     D0
'                                                              3
'                                                             ---
'                                                           2 |  | 4
'                                                           1 ---
'                                                           5 |  | 7
'                                                             ---   o8
'                                                              6
'   2002 Víctor R. González

DECLARE SUB Activa (valor%)

' Direcciones del puerto paralelo
CONST LPTBASE = &H378
CONST DATOS = LPTBASE
CONST ESTADO = LPTBASE + 1
CONST CONTROL = LPTBASE + 2

CONST APAGADO = &H0      ' display apagado   

DIM i AS INTEGER, segmento(11) AS INTEGER

	' Valores que activan los segmentos
	segmento(0) = &H7E	' segmentos  ,7,6,5,4,3,2, : 01111110
	segmento(1) = &H48	' segmentos  ,7, , ,4, , , : 01001000
	segmento(2) = &H3D	' segmentos  , ,6,5,4,3, ,1: 00111101
	segmento(3) = &H6D	' segmentos  ,7,6, ,4,3, ,1: 01101101
	segmento(4) = &H4B	' segmentos  ,7, , ,4, ,2,1: 01001011
	segmento(5) = &H67	' segmentos  ,7,6, , ,3,2,1: 01100111
	segmento(6) = &H73	' segmentos  ,7,6,5, , ,2,1: 01110011
	segmento(7) = &H4C	' segmentos  ,7, , ,4,3, , : 01001100
	segmento(8) = &H7F	' segmentos  ,7,6,5,4,3,2,1: 01111111
	segmento(9) = &H4F	' segmentos  ,7, , ,4,3,2,1: 01001111
	segmento(10) = &H80	' segmentos 8, , , , , , , : 10000000

	CLS : PRINT "Control de un display de 7 segmentos:"

	' Cuenta adelante
	PRINT : INPUT "Pulsa <intro> para comenzar una cuenta adelante ...", a$
	FOR i = 0 TO 10
		IF segmento(i) <> PUNTO THEN
			PRINT "  "; i;
		ELSE
			PRINT "   . ";
		END IF
		Activa segmento(i)
		SLEEP 1
	NEXT i

	' Cuenta atrás
	PRINT : INPUT "Pulsa <intro> para comenzar la cuenta atrás ...", a$
	FOR i = 10 TO 0 STEP -1
		IF segmento(i) <> PUNTO THEN
			PRINT "  "; i;
		ELSE
			PRINT "   . ";
		END IF
		Activa segmento(i)
		SLEEP 1
	NEXT i

	' Apaga el display
	PRINT : INPUT "Pulsa <intro> para apagar y salir ...", a$
	Activa APAGADO

END

' Envía un valor al puerto de datos
SUB Activa (valor%)

	OUT DATOS, valor%

END SUB

 

/*	DISPLAY7.C
	CONTROL DE ACTUADORES Y SENSORES MEDIANTE PUERTO PARALELO

	Programación de un display de 7 segmentos de cátodo común
	Segmentos y punto decimal en las 8 líneas de DATOS:

	punto  seg.7  seg.6  seg.5  seg.4  seg.3  seg.2  seg.1
	  D7    D6     D5     D4     D3     D2     D1     D0
								   3
								  ---
								2 |  | 4
								1 ---
								5 |  | 7
								  ---   o8
								   6
	2002 Víctor R. González
*/
#include <stdio.h>
#include <dos.h>

/* Direcciones del puerto paralelo */
#define LPT_BASE	0x378
#define DATOS		LPT_BASE
#define ESTADO		LPT_BASE+1
#define CONTROL		LPT_BASE+2

/* Valores que activan los segmentos */
#define CERO	0x7E		/* segmentos  ,7,6,5,4,3,2, : 01111110 */
#define UNO	0x48		/* segmentos  ,7, , ,4, , , : 01001000 */
#define DOS	0x3D		/* segmentos  , ,6,5,4,3, ,1: 00111101 */
#define TRES	0x6D		/* segmentos  ,7,6, ,4,3, ,1: 01101101 */
#define CUATRO	0x4B		/* segmentos  ,7, , ,4, ,2,1: 01001011 */
#define CINCO	0x67		/* segmentos  ,7,6, , ,3,2,1: 01100111 */
#define SEIS	0x73		/* segmentos  ,7,6,5, , ,2,1: 01110011 */
#define SIETE	0x4C		/* segmentos  ,7, , ,4,3, , : 01001110 */
#define OCHO	0x7F		/* segmentos  ,7,6,5,4,3,2,1: 01111111 */
#define NUEVE	0x4F		/* segmentos  ,7, , ,4,3,2,1: 01001111 */
#define PUNTO	0x80		/* segmentos 8, , , , , , , : 10000000 */
#define APAGADO 0x00		/* display apagado */

/* Macro que envía un valor al puerto de DATOS */
#define Activa(valor)	outportb (DATOS, valor)

/* Macro que realiza una espera en segundos */
#define espera(valor)	delay (1000*valor)


main ()
{
	int i;
	unsigned segmento[] = { CERO,  UNO,  DOS,   TRES, CUATRO,
				CINCO, SEIS, SIETE, OCHO, NUEVE,
				PUNTO
				};

	printf ("Control de un display de 7 segmentos:\n");

	/* Cuenta adelante */
	printf ( "\nPulsa <intro> para comenzar una cuenta adelante ...");
	getchar();
	for (i=0; i<=10; i++ ) {
		if (segmento[i] != PUNTO)
			printf ("   %i", i);
		else
			printf ("   .");
		Activa (segmento[i]);
		espera (1);
	}

	/* Cuenta atrás */
	printf ( "\n\nPulsa <intro> para comenzar la cuenta atrás ...");
	getchar();
	for (i=10; i>=0; i-- ) {
		if (segmento[i] != PUNTO)
			printf ("   %i", i);
		else
			printf ("   .");
		Activa (segmento[i]);
		espera (1);
	}

	/* Apaga el display */
	printf ( "\n\nPulsa <intro> para apagar y salir ...");
	getchar();
	Activa (APAGADO);

	return 0;
}

 

Reproducir película que muestra el control del circuito sin alimentaciópn externa y con display.

Volver al principio de página

volver a Inicio