/* Control de un puente levadizo neum tico mediante puerto paralelo 2002 V¡ctor R. Gonz lez - Angelberto Mieres */ #include #include #include "paralelo.h" #define APAGADO 0x00 /* D0-D7, pin 2-9, desactivados */ #define SIRENA 0x01 /* D0, pin 2, zumbador */ #define ROJO 0x02 /* D1, pin 3, LED */ #define VERDE 0x04 /* D2, pin 4, LED */ #define AMBAR 0x08 /* D3, pin 5, LED */ #define PUENTE_SUBE 0x10 /* D4, pin 6, electrov lvula */ #define PUENTE_BAJA 0x20 /* D5, pin 7, electrov lvula */ #define PULSA_ALIM 0x80 /* D7, pin 9, alimentaci¢n pulsadores */ #define BARCO_VIENE 0x0 /* S6, pin 10 bajo, detector IR */ #define PULSA_SUBIR 0x0 /* S7#,pin 11 bajo, pulsador n/c de subida */ #define PULSA_BAJAR 0x0 /* S5, pin 12 bajo, pulsador n/a de bajada */ /* El estado normal de los sensores (desactivados) es: S7#=1, S6=1, S5=1 */ #define T_ROJO 5 /* duraci¢n (en segundos) de la luz roja */ #define T_VERDE 5 /* duraci¢n (en segundos) de la luz verde */ #define T_AMBAR 2 /* duraci¢n (en segundos) de la luz ambar */ #define T_PARPADEO 400 /* duraci¢n (en milisegundos) del parpadeo de la luz ambar */ #define T_SUBIDA 3 /* duraci¢n (en segundos) de la elevaci¢n del puente */ #define T_BAJADA 3 /* duraci¢n (en segundos) de la bajada del puente */ #define T_ESPERA 10 /* per¡odo (en milisegundos) de atenci¢n al teclado */ /* Activa las se¤ales adecuadas del puerto */ #define Activa(valor) if (en_marcha) {outportb (DATOS, valor | PULSA_ALIM); printf("Enviado: 0x%X\n", valor);} #define SensorSubir() (inportb (ESTADO) & 0x80) /* Toma s¢lo bit 7 de ESTADO */ #define SensorBarco() (inportb (ESTADO) & 0x40) /* Toma s¢lo bit 6 de ESTADO */ #define SensorBajar() (inportb (ESTADO) & 0x20) /* Toma s¢lo bit 5 de ESTADO */ #define Apaga() outportb (DATOS, APAGADO) /* Desactiva las salidas */ int ParaleloIni (void); /* Detecta el puerto paralelo */ void Espera (float); /* Espera con atenci¢n al teclado y a las entradas digitales */ char en_marcha; /* Indica el funcionamiento o el fin del proceso */ void main (void) { /* Realiza el control si se detecta el puerto paralelo */ if ( ParaleloIni() != LPT_NINGUNO ) { Activa (PULSA_ALIM); /* Activa alimentaci¢n circuito pulsadores */ en_marcha = TRUE; /* Secuencia peri¢dica de los sem foros esperando suceso de teclado o entrada digital */ do { Activa (VERDE); Espera (T_VERDE); Activa (AMBAR); Espera (T_AMBAR); Activa (ROJO); Espera (T_ROJO); } while( en_marcha ); Apaga(); /* Apaga las se¤ales del puerto */ } else { printf ("No se encuentra ning£n puerto paralelo\n"); exit(1); } } /* Realiza una espera activa de segundos. Atiende al teclado y a las entradas digitales cada 10 ms */ void Espera (float t) { int t_max = 1000*t; /* tiempo a esperar (en ms) */ int crono = 0; /* tiempo transcurrido (en ms) */ int periodo= T_ESPERA; int tecla, sens_barco, barco = FALSE; char puente_arriba = FALSE; /* Espera hasta que se agota el crono */ while (en_marcha && crono < t_max) { if ( kbhit() ) tecla = getch(); /* Comprueba teclado */ sens_barco = SensorBarco(); /* Comprueba presencia del barco */ if (tecla == '+' || SensorSubir() == PULSA_SUBIR || (!barco && sens_barco == BARCO_VIENE)) { if (sens_barco == BARCO_VIENE) barco = TRUE; /* Eleva las hojas del puente */ for (crono=0; crono< 1000*T_SUBIDA; crono += 2*T_PARPADEO) { Activa (SIRENA + PUENTE_SUBE + AMBAR); delay (T_PARPADEO); Activa (SIRENA + PUENTE_SUBE); delay (T_PARPADEO); } Activa (SIRENA); puente_arriba = TRUE; tecla = 0; crono = 0; } else if( tecla == '-' || (!barco && SensorBajar() == PULSA_BAJAR) || (barco && sens_barco != BARCO_VIENE)) { barco = FALSE; /* Baja las hojas del puente */ for (crono=0; crono< 1000*T_BAJADA; crono += 2*T_PARPADEO) { Activa (SIRENA + PUENTE_BAJA + AMBAR); delay (T_PARPADEO); Activa (SIRENA + PUENTE_BAJA); delay (T_PARPADEO); } Apaga(); puente_arriba = FALSE; tecla = 0; crono = t_max; /* Sale del modo espera */ } else if( tecla == 'f' ) { /* Finaliza; si el puente est  elevado, lo baja */ if (puente_arriba) { Activa (PUENTE_BAJA); delay (1000*T_BAJADA); } en_marcha = FALSE; } else if (puente_arriba) { /* Si el puente sigue elevado, la sirena suena y las luces ambar parpadean */ Activa (SIRENA + AMBAR); delay (T_PARPADEO); Activa (SIRENA); delay (T_PARPADEO); } else { /* Espera hasta nueva comprobaci¢n de teclado y pulsadores */ delay (periodo); crono += periodo; } } } /* Identifica los puertos paralelos instalados en el PC Devuelve: LPT_NINGUNO: si no hay puertos instalados LPT_OTROS : si el primer puerto es de tipo desconocido LPT_SPP : si el primer puerto es SPP LPT_BIDIR : si el primer puerto es bidireccional LPT_EPP : si el primer puerto es EPP LPT_ECP : si el primer puerto es ECP */ int ParaleloIni (void) { unsigned int PuertoNum, Puerto, NumPuertos; unsigned int Byte, tmp; char PuertoEPP; int PuertoTipo; char *PuertoNombre[]={"", "Estandar (SPP)", "Bidireccional", "EPP", "ECP"}; /* Busca la direcci¢n de E/S de los puertos instalados */ NumPuertos = 0; PuertoTipo = LPT_NINGUNO; for (PuertoNum=1; PuertoNum<=3; PuertoNum++) { _lpt_dir[PuertoNum] = peek(0x0040,0x0008 + (PuertoNum-1)*2); if (_lpt_dir[PuertoNum] == 0) printf ("No se encuentra puerto asignado a LPT%d \n", PuertoNum); else { printf ("La direcci¢n asignada a LPT%d es 0x%X\n", PuertoNum, _lpt_dir[PuertoNum]); NumPuertos++; } } if (NumPuertos > 0 ) { /* Detecta el tipo de puerto del primero hallado */ printf ("\nPuerto seleccionado: LPT%d en 0x%X. ", LPT_NUM, LPT_BASE); /* Prueba puerto ECP */ Byte = inportb (CONTROL_EXT) & 0x03; /* toma bits 0 y 1 de CONTROL_EXT */ if (Byte == 1) { Byte = inportb (CONTROL); tmp = Byte; outportb (CONTROL, Byte ^ 0x03); /* pone a 0 los bits 0 y 1 de CONTROL */ Byte = inportb(CONTROL_EXT) & 0x03; if (Byte == 1) PuertoTipo = LPT_ECP; outportb (CONTROL, tmp); /* restaura CONTROL */ } /* Prueba puerto EPP */ if (!PuertoTipo) { PuertoEPP = FALSE; if (LPT_BASE != 0x03BC) { Byte = inportb (ESTADO); tmp = Byte; outportb (ESTADO, Byte & (~0x01) ); /* Pone a 0 el bit 0 de ESTADO */ for (Puerto=REG_EPP_PRI; Puerto<=REG_EPP_ULT; Puerto++) { outportb (Puerto, 0x55); Byte = inportb (Puerto); if (Byte == 0x55) { outportb (Puerto, 0xAA); Byte = inportb (Puerto); PuertoEPP = (Byte == 0xAA); if (!PuertoEPP) break; } } outportb (ESTADO, tmp); /* restaura bit 1 de ESTADO */ } if (PuertoEPP) PuertoTipo = LPT_EPP; } /* Prueba puerto SPP */ if (!PuertoTipo) { Byte = inportb (CONTROL); tmp = Byte; outportb (CONTROL, Byte | 0x20 ); /* Pone a 1 el bit 5 de CONTROL (entrada de DATOS) */ outportb (DATOS, 0x55); Byte = inportb (DATOS); if (Byte == 0x55) { outportb (CONTROL, Byte | 0x20 ); /* Pone a 1 el bit 5 de CONTROL (entrada de DATOS) */ outportb (DATOS, 0xAA); Byte = inportb (DATOS); if (Byte == 0xAA) PuertoTipo = LPT_SPP; } outportb (CONTROL, tmp); /* Restaura el bit 5 de CONTROL */ } /* Prueba puerto bidireccional */ if (!PuertoTipo) { Byte = inportb (CONTROL); tmp = Byte; outportb (CONTROL, Byte | 0x20 ); /* Pone a el 1 bit 5 de CONTROL (entrada de DATOS)*/ outportb (DATOS, 0x55); Byte = inportb (DATOS); if (Byte != 0x55) { outportb (CONTROL, Byte | 0x20 ); /* Pone a el 1 bit 5 de CONTROL (entrada de DATOS) */ outportb (DATOS, 0xAA); Byte = inportb (DATOS); if (Byte != 0xAA) PuertoTipo = LPT_BIDIR; } outportb (CONTROL, tmp); /* Restaura el bit 5 de CONTROL */ } if (PuertoTipo) { printf("Puerto tipo: %s (%i)\n", PuertoNombre[PuertoTipo], PuertoTipo); /* Pone DATOS en modo salida */ DATOS_out(); /* Pone las salidas en bajo */ outportb (DATOS, 0x00); /* reg. de DATOS */ outportb (CONTROL, inportb (CONTROL) & 0xFB); /* nibble bajo del reg. de CONTROL */ } else { PuertoTipo= LPT_OTROS; /* Puerto de tipo desconocido */ printf("Puerto de tipo desconocido\n"); } } /* NumPuertos > 0 */ return( LPT_TIPO = PuertoTipo ); }