1 Julián González Ramírez Electiva tecnológica LABORATORIO DE CONTROL POR EL PUERTO PARALELO DEL COMPUTADOR Un microprocesador tiene tres tipos de buses que se encargan de transportar información binaria. Por medio de los buses se pueden extraer e introducir información (señales digitales), para poder ejecutar acciones de control. BUSES INTERNOS Está compuesto por los buses de Direcciones, Datos y Control del microprocesador y algunas señales generadas por otros circuitos del computador. Las ventajas de la conexión de una tarjeta de adquisición de datos directamente a este son: alta velocidad de muestreo, bajo costo y tamaño reducido. La potencia para alimentar los circuitos de adquisición de datos se obtiene directamente de los terminales del bus. Para computadores PC compatibles, los tipos de buses más utilizados son ISA, EISA, PCI y Microcanal. BUSES EXTERNOS Hay dos buses externos llamados puertos (serial y paralelo) a través de ellos se conectan los periféricos. Estos puertos (serial y paralelo) se encuentran en la parte posterior del computador y son fáciles de diferenciar ya que el paralelo utiliza un conector DB25 hembra, mientras que el serial utiliza un conector DB9 macho. PUERTO SERIAL El puerto serial, también denominado RS-232 o de comunicaciones. entrada/salida en forma serial. Manipula los datos de Ventajas de emplear el puerto serial en adquisición de datos y para realización de control: • Requiere pocas líneas • Es posible configurar sistemas de cualquier tamaño • Los circuitos de adquisición de datos se ubican a cualquier distancia del computador central, por ejemplo cerca del sensor. • Son compatibles con casi todo tipo de computadores e instrumentos PUERTO PARALELO El puerto para impresora o puerto paralelo del computador, también denominado Centronics, está compuesto por un conjunto de entradas/salidas digitales que permiten la operación de la impresora. Este puerto es el ideal para experimentar con circuitos, programas y sistemas. En algunas aplicaciones reales de control se le pueden conectar directamente sensores o actuadores. Para utilizar el puerto paralelo del computador en la conexión del circuito experimental, se deben tener en cuenta los siguientes aspectos. Las líneas de tierras están representadas por circuitos pequeños y las líneas de entrada y salida se indican con flechas que apuntan en el sentido correspondiente. 2 Julián González Ramírez Electiva tecnológica FUNCIONES DE CADA TERMINAL EN EL CONECTOR DB-25 Las señales del bus se clasifican en cuatro grupos (Salidas de datos, Tierras, Entradas de protocolo, salidas de protocolo) Salidas de datos: Transportan la información desde el computador hacia el periférico. Lo hacen en grupos de ocho bits (1 byte) al tiempo, utilizando los terminales 2 al 9 del conector DB-25. El bit D0 es el de menor peso o LSB (bit menos significativo) y el bit D7 es el de mayor peso o MSB (bit más significativo). Los bits están representados por niveles de voltaje TTL (Lógica transistor transistor). Una señal entre 0.8 y 2.4 voltios es un nivel bajo (cero lógico) y una señal entre 2.5 y 5 voltios es un nivel alto (uno lógico). Líneas de tierra: Tienen por objetivo realizar dos funciones: La primera es la de unir las tierras entre el computador y el periférico de tal forma que haya una referencia de potencial común. La segunda, es realizar el blindaje de las señales contra ruidos externos (señales perturbadoras) al cable, evitando interferencias entre las mismas señales que transporta el cable ribbon que es utilizado generalmente para esta conexión. 3 Julián González Ramírez Electiva tecnológica El cable de tierra conectado al Terminal 19 del conector DB25 realiza el blindaje entre los terminales 6 y 7. Lo anterior evita el acople capacitivo que puede ocurrir entre las líneas de datos D4 y D5 a lo largo del cable Ribbon que une el computador y el periférico. Entradas y salidas de protocolo El computador es mucho más rápido que cualquier periférico y por lo tanto, le puede transmitir más datos de los que puede recibir. Por esa razón, los circuitos de los periféricos , como la impresora, usan señales especiales, para indicarle al computador que detenga momentáneamente el envío de datos hasta qe se encuentre listo para recibirlos. De esta manera el computador tiene la oportunidad de ejecutar otras tareas hasta que el periférico le indique, por intermedio de una señal de protocolo, que se encuentra listo para recibir datos. Las líneas de protocolo strobe (inicio), busy (ocupado) y acknowledge (reconcimiento) son las más utilizadas para realizar la coordinación entre un computador rápido y un periférico lento. Cuando el computador tiene datos para enviar por el puerto paralelo, lo hace acompañado por una señal de strobe, el periférico responde con una señal de busy hasta que termina de aceptar o procesar los datos; así evita que el computador le envíe nuevos datos, y cuando se encuentra listo le responde al computador con una señal de acknow ledge. Según la documentación de algunos computadores y del sistema operativo es posible tener hasta tres puertos paralelos en un computador (LPT1, LPT2, LPT3). Los diseñadores de computadores asignan una dirección, entre las posibles, a cada puerto de entrada/ salida, donde no pueden haber dos iguales, en un computador cda posición de memoria y cada periférico tiene su dirección específica. Cada puerto paralelo del computador está formado por 12 líneas de salida de información hacia el mundo exterior y 5 líneas de entrada. Son requeridos 3 bytes (tres palabras de 8 bits) para manejar esta información. Por lo tanto, a cada puerto paralelo se le deben asignar 3 direcciones. En la tabla se hace referencia a las direcciones asignadas a los posibles puertos paralelos en el computador. También se indica el número de cada Terminal del conector DB25 y la entrada o salida que le corresponde a cada bit de los tres bytes de cada puerto. Observe en la tabla, que las señales de los puertos se clasifican solamente como entradas y salidas. 4 Julián González Ramírez Electiva tecnológica 5 Julián González Ramírez Electiva tecnológica En la figura siguiente se muestra el diagrama del circuito del proyecto. Las ocho líneas de salida de los datos (D0 a D7) son los terminales 2 a 9 del conector DB-25 macho, se conectan por medio de las compuertas inversoras (CI 74LS04) de los circuitos integrados CI-1 y CI-2 a los 8 diodos emisores de luz (LEDS). Estos leds nos representarán las salidas digitales sobre las cuales se quiere realizar control. E una aplicación industrial se pueden reemplazar por relés o triacs para manejar cargas de mayor potencia. Las resistencias de 330 ohmios imitan la corriente por los leds y las de 4.7 dilo ohmios evitan falsos disparos de las señales del circuito. A los terminales de entrada 12, 13 y 15 del conector DB-25 se conectan 3 pulsadores (normalmente abiertos P1, P2 y P3). Estos representan las entradas digitales. En una aplicación real pueden ser detectores de proximidad, interruptores de final de carrera o cualquier sensor de tipo digital. Ensamble del circuito. El proyecto se ensambla en una tarjeta universal o un protoboard con los elementos que se describen en la lista de componentes. Alimentación del circuito. Tanto los circuitos INVERSORES, como los LEDS, necesitan un voltaje de 5 voltios (voltaje corriente directa), para obtener este voltaje existen dos maneras; utilizando una fuente externa de 5 voltios conectada a los terminales de alimentación o tomarlo de la fuente interna del computador. Si se tiene alguna experiencia en el montaje de proyectos electrónicos se sugiere hacer lo siguiente. Remueva la cubierta del computador e identifique con la ayuda de manuales, si los tiene y de un voltímetro digital, los terminales de la fuente de 5 voltios en el interior del equipo. Retire una de las láminas posteriores que cubren los espacios disponibles para las tarjetas de expansión o de controladores especiales. Haga dos perforaciones y ubique en ella rceptáculos aislados para bananas, uno de color rojo (+) y otro de color negro (-). Suelde a los terminales dos cables de igual color y conéctelos a las salidas de 5V previamente identificadas y arme nuevamente su computador. LISTA DE COMPONENTES Resistencias de ¼ W, 5% Tres resistencias (R1,R2, R3) de 2.2 k Ω Ocho resistencias (R4 a R11) de 4.7k Ω Ocho resistencias (R12 a R19) de 330 Ω (rojo rojo rojo) (amarillo violeta rojo) (naranja naranja marrón) Semiconductores Ocho diodos LEDS rojos 5mm (D1 a D8) Dos circuitos integrados 74LS04 (CI1 CI2) Varios Tres pulsadores miniatura (P1, P2, P3) 1 conector para impreso de 12 pines (macho y hembra) CN1 1 conector DB25 macho con carcaza 1 metro de cable ribbon de 12 líneas 1 protoboard 2 cables de conexión con caimanes y bananas 6 Julián González Ramírez Electiva tecnológica PLANO ELÉCTRICO DEL PROYECTO 7 Julián González Ramírez Electiva tecnológica ASPECTO DEL CABLE Para cumplir con el objetivo es necesario estudiar cuatro instrucciones del lenguaje C++ y los dos elementos con los cuales interactúa el cerebro (micro procesador) del computador. Al ejecutar cualquier labor, la unidad central de proceso del computador (CPU) siempre está tomando datos de dos fuentes diferentes: la memoria o un puerto de entrada/salida. De igual manera, el resultado de las operaciones de la CPU tienen como destino uno de estos dos elementos. El manejo de la memoria y de los puertos tienen el mismo esquema para su direccionamiento (el acceder a una posición de memoria o un puerto en particular), en un momento dado, para distinguir entre la memoria y un puerto, el computador genera señales diferentes. Para tener acceso a los puertos IOWR (para escritura) o IORD (para lectura) Para tener acceso a la memoria MEMWR (para escritura) o MEMRD (para lectura) El acceso a la memoria es muy importante, bien sea para almacenar/leer datos o para tomar/modificar algunos parámetros de funcionamiento del computador, los cuales se cargan en la memoria RAM. El tipo de monitor, el número y dirección de los puertos seriales y paralelos, las últimas teclas digitadas, la fecha y la hora del sistema, entre una gran cantidad de información, son algunos de los elementos que se pueden conocer mediante la consulta de unas posiciones de memoria bien definidas. Para acceder a la memoria, existen instrucciones básicas en el lenguaje C++ peek (lectura) y poke (escritura), cada una de ellas posee una variante: peekb pokeb. Mientras peek lee una palabra (dos bytes consecutivos), peekb lee solamente un byte, igual sucede con sus análogos pokeb y poke. 8 Julián González Ramírez La sintaxis para estas instrucciones es la siguiente. Electiva tecnológica Palabra = peekb(segmento, offset); pokeb(segmento, offset, Palabra); Byte=peek (segmento, offset); Poke (segmento, offset, Byte); Debido a que las direcciones dentro del computador superan los 64 Kbytes , es necesario definirlas en dos partes: segmento y offset, los segmentos definen bloques de 64 Kbytes y el offset (desplazamiento) apunta a una dirección particular dentro de este bloque; la dirección completa en hexadecimal se puede reconstruir con la operación: Dirección = Segmento *10h + offset Se debe tener en cuenta que no existe una forma única de representar una dirección. Por ejemplo, si hacemos referencia a las siguientes posiciones de memoria. Segmento = 40hOffset Segmento = 04hOffset Segmento = 00hOffset = 00h = 3C0h = 400h [0040:0000] [0004:03C0] [0000:0400] Realmente se refiere a la misma posición de memoria, la 400h. Para verificar lo anterior se puede emplear el comando Debug que viene en el sistema operativo MSDOS o el comando SID del DRDOS. Desde allí se puede ejecutar la instrucción D 40:0 y la D0:400 se podrá verificar que los contenidos de las posiciones de memoria que se muestran son los mismos (Para salir de este programa utilice el comando Q) Las posibilidades de expresar una misma posición de memoria con diferentes segmentos y desplazamientos son amplias. En el lenguaje C++, las instrucciones se encargan de interpretar esta dirección para leer o escribir sobre ella. Por ejemplo, se encuentra en manuales de los computadores, que la dirección del primer puerto paralelo disponible se encuentran en las posiciones de memoria definidas por 0040:0008 y siguiente. Al observar estas posiciones de memoria con el comando Debug, se observa que en la posición 0008 se encuentra el número 78 (o el número BC) y en la siguiente el número 03 (ó el 02); la interpretación correcta será la dirección 0378h (03BC o 0278, según la configuración del computador) Esto es debido a que primero se almacena en la memoria el byte menos significativo. Con el lenguaje C++, se tienen dos opciones de conocer la dirección del primer puerto paralelo disponible. Se puede consultar el valor de la palabra que se encuentra a partir de la posición 040:0008 o averiguar el valor de cada uno de los bytes y luego reconstruir la dirección del puerto, multiplicando el contenido de la posición de memoria 040:0009 por el decimal 256 y luego sumarle el contenido de la dirección 040:0008; en ambos casos el resultado debe ser el mismo. Las dos opciones que tenemos para este caso son entonces las instrucciones: 9 Julián González Ramírez Electiva tecnológica Puerto = peek (0x40, 0x8); Puerto = peekb(0x40, 0x9) *256+peekb (0x40, 0x8); Un ejemplo de programa que obtiene la dirección del primer puerto paralelo disponible, es el siguiente: #include <conio.h> #include <dos.h> #include <iostream.h> Void main() { int puerto; clrscr(); puerto=peekb (0x40,0x8); cout<<”Dirección: ” <<puerto; getch(); } Cuando se ejecuta el programa, el computador imprime en la pantalla el valor hexadecimal correspondiente a la dirección del primer puerto disponible. Se pueden hacer las modificaciones necesarias con respecto a la instrucción peek o con la forma de representar la dirección [segmento offset], los resultados deben ser los mismos. Al conocer las posiciones de memoria, podemos hablar de los puertos. Estos son indispensables debido a que a través de ellos es como ingresa la información al computador (a través de un modem, un scanner, un convertidor análogo a digital, etc) y a través de otros puertos es como sale la información (unidad de disco, una impresora, un MODEM, un convertidor digital a análogo, etc) Pueden conectarse en teoría 65536 puertos al computador y cada no de ellos tiene su propia dirección. El lenguaje C++ permite tanto la lectura como la escritura de los puertos a través de instrucciones similares a las descritas anteriormente. Para leer el puerto existen las instrucciones inport e inportb. La sintaxis de estas instrucciones es la siguiente: Palabra=inportb(puerto); outportb(puerto, Palabra); Byte=inport(puerto); outport(puerto, Byte); Las instrucciones que terminan en b se refieren a la lectura o escritura de un byte, y las que no terminan en esta letra se refiere a una palabra (dos bytes) Ejemplos prácticos Este ejemplo se aplica al circuito conectado al puerto paralelo del computador, teniendo en cuenta las características de voltaje y demás, antes mencionadas. #include <conio.h> #include <dos.h> void main() { int puerto; clrscr(); puerto=peek(0x40,0x8) 10 Julián González Ramírez outportb(puerto, 0x1); getch(); } Electiva tecnológica Cuando se ejecuta el programa, se observa que el primer LED (el menos significativo) se activa (si no es así, proceda a revisar las conexiones realizadas y a verificar que el circuito tenga la alimentación correcta); Si desea encender los otros LEDS se debe cambiar el valor que se obtiene por el puerto. En el ejemplo siguiente se activa el primer LED (el menos significativo), generado por uno (1) lógico en el bit cero del puerto paralelo, pero además de esto el usuario tiene la opción de desactivar el LED, generando un cero (0) lógico en el puerto. Esto es realizado por el usuario, ingresando un valor de cero (0), por medio del teclado. #include <iostream.h> #include <conio.h> #include <dos.h> int puerto; void main() { int dato; clrscr(); puerto=peek(0x40,0x8) outportb(puerto, 1); cout<<”El LED menos significativo, esta activado \n”; cout<<”Digite cero(0) para desactivarlo \n”; cin>>dato; if (dato==0) outportb(puerto,0); getch(); } El siguiente ejemplo ilustra la manera de cómo se puede ingresar información al puerto, mostrando el posible estado de cada uno de los pulsadores en la pantalla del computador, también se puede utilizar una estructura switch() – case, para lograr el mismo efecto. #include <iostream.h> #include <conio.h> #include <dos.h> void main() { clrscr(); int leeInform, puerto; puerto=peek(0x40,0x8) leeInform=inportb(puerto+1); if (leeInform == 79) cout<<”Pulsador 1 cerrado”; else cout<<”Pulsador 1 abierto”; if (leeInform == 87) cout<<”Pulsador 2 cerrado”; 11 Julián González Ramírez else cout<<”Pulsador 2 abierto”; if (leeInform == 103) cout<<”Pulsador 3 cerrado”; else cout<<”Pulsador 3 abierto”; getch(); } Electiva tecnológica Analizando el plano del circuito se observa que cada una de las líneas que van desde los pulsadores (normalmente abiertos) hacia el puerto del computador, permanecen conectadas a tierra (cero lógico) por medio de las resistencias de 2.2K Ω , cuando se acciona uno de los pulsadores la línea correspondiente se conecta a 5 Vcc+ (uno lógico) Cualquiera de estos datos lógicos pueden conocerse por medio de la lectura del puerto (en la dirección puerto +1) con la función inporb y asignar este valor a una variable (leeInform). Los valores capturados por la variable leeInform para este ejemplo son: Pulsador1=79, Pulsador2=87, Pulsador3=103, pero estos valores pueden ser diferentes en otros computadores. Para averiguar los valores para un computador determinado, se debe conectar el circuito y hacer una prueba pulsando cada pulsador, e ir imprimiendo los valores de la variable leeInform en la pantalla. Como ejercicio se puede crear una rutina o función que detecte los valores para cada uno de los pulsadores antes de utilizarlos en el programa general. El siguiente programa muestra la aplicación de la estructura switch.case del lenguaje C++. Este programa permite al usuario activar por medio del teclado uno de los ocho leds del circuito del proyecto, se activará uno de los ocho leds, el que corresponda al valor digitado (1 al 8) por usuario a través del teclado. #include <iostream.h> #include <conio.h> #include <dos.h> void main() { int puerto, leeInform; clrscr(); puerto=peek(0x40,0x8) cout<<”Digite un valor de 1 a 8 para activar el respectivo led”; cin>> leeInform; switch(leeInform){ case1: outportb(puerto, 0x01);break; case2: outportb(puerto, 0x02);break; case3: outportb(puerto, 0x04);break; 12 Julián González Ramírez case4: outportb(puerto, 0x08);break; case5: outportb(puerto, 0x10);break; case6: outportb(puerto, 0x20);break; case7: outportb(puerto, 0x40);break; case8: outportb(puerto, 0x80);break; default: outportb(puerto, 0);break; } getch(); } Electiva tecnológica En el siguiente programa se ilustra como se puede trabajar con la estructura do while, este programa mejora el desempeño del programa anterior, si se tiene en cuenta que no es necesario ejecutar el programa cada vez que sea necesario activar un led determinado. #include <iostream.h> #include <conio.h> #include <dos.h> void main() { int puerto, leeInform; char salir; clrscr(); puerto=peek(0x40,0x8) do{ cout<<”Digite un valor de 1 a 8 para activar el respectivo led”; cin>> leeInform; switch(leeInform){ case1: outportb(puerto, 0x01);break; case2: outportb(puerto, 0x02);break; case3: outportb(puerto, 0x04);break; case4: outportb(puerto, 0x08);break; case5: outportb(puerto, 0x10);break; case6: outportb(puerto, 0x20);break; case7: outportb(puerto, 0x40);break; 13 Julián González Ramírez Electiva tecnológica case8: outportb(puerto, 0x80);break; default: outportb(puerto, 0);break; } cout<<”Digite s si desea salir del programa \n”; cin>> salir; }while(tolower(salir)!=’s’; }