unidad iv.docx

35
LENGUAJES DE INTERFAZ UNIDAD IV Programación de Dispositivos

Upload: davidmr905

Post on 25-Oct-2015

1.505 views

Category:

Documents


2 download

DESCRIPTION

Programación de dispositivos

TRANSCRIPT

UNIDAD IV

Programación de Dispositivos

ÍNDICE4. Programación de dispositivos…………………………………..…………………...2

4.1 El buffer de video en modo texto……………………………..…..………..2

4.1.1 Escritura directa en el búfer de vídeo…………………….…….…..…...4

4.1.2. Ejemplos completos en modo texto…………………………………….5

4.2 Acceso a discos en lenguaje ensamblador……………………………………….5

4.2.1. Particiones del DOS………………………………………………….…..6

4.2.2. Parámetros absolutos de un Disco Duro………………………………6

4.2.3. Acceso a dispositivos de almacenamiento…………………………….7

4.2.4. Acceso a disco usando lenguaje ensamblador………………………..7

4.3 Programación del puerto serial……………………………………………………10

4.3.1. Explicación de los registros……………………………………………..11

4.3.2. Abrir un canal asociado a un puerto serie……………………………..12

4.3.3. Modificar los parámetros de transmisión…….…………………...…....13

4.3.4. Monitorización de eventos……………………………………………….13

4.3.5. Escribir en el puerto serie……………….………………………….……14

4.3.6. Esperar a que haya algo para leer…………………………………...…15

4.3.7. Leer desde el puerto serie…………………………………………….…16

4.4 Programación del puerto paralelo………………………………………………….17

4.4.1. Conector Puerto Paralelo……………………………………………...…18

4.5 Programación híbrida………………………………………………………………..20

4.5.1. Operadores………………………………………………………………..20

4.6 Programación de puerto USB……………………………………………...............23

Bibliografía………………………………………...…………………………………...…24

David Montiel Ramirez 1

David Montiel Ramirez 2

4. Programación de dispositivos

4.1 El buffer de video en modo texto

Se llama modo texto a cualquier modo de vídeo de un ordenador en el que el contenido de la pantalla se representa internamente en términos de caracteres textuales en lugar de píxeles individuales.

Las aplicaciones en modo texto se comunican con el usuario mediante líneas de comandos (CLIs) e interfaces textuales de usuario (TUIs). Muchos juegos de caracteres usados en aplicaciones en modo texto también incluyen un conjunto limitado de caracteres semi -gráficos predefinidos que pueden usarse para dibujar cajas y otros gráficos rudimentarios usados para destacar el contenido o simular widgets u controles como los presentes en las aplicaciones escritas para interfaces gráficas (GUIs).

Las ventajas de los modos de texto respecto a los gráficos incluyen el menor consumo de memoria y la más rápida manipulación de pantalla. Además, las aplicaciones en modo texto tienen unos requisitos de ancho de banda relativamente bajos en uso remoto. Una desventaja obvia del modo texto es la restricción del contenido de pantalla, que lo hace inviable para muchos tipos de aplicaciones.

Una característica importante de los programas en modo texto es que asumen un ancho constante de las fuentes, donde cada carácter tiene la misma anchura en pantalla, lo que permite mantener fácilmente la alineación vertical cuando se muestran caracteres semi-gráficos.

Según el entorno, el buffer de pantalla puede ser directamente accesible, como memoria convencional, para los programas locales. Los programas que muestran salidas en una terminal remota deben enviar secuencias de control especiales para manipular el buffer de pantalla. Los estándares más populares de dichas secuencias de control son ANSI y VT100. Los programas que acceder al buffer de pantalla mediante secuencias de control pueden perder la sincronización con la pantalla real, por lo que muchos programas en modo texto tienen un comando para «refrescar» toda la pantalla, a menudo asociado con la combinación de teclas Ctrl+L.

La distinción entre los programas en modo texto y gráfico puede a veces ser difusa, especialmente en ordenadores con tarjetas VGA, debido a que muchos programas en modo texto recientes llevaron al extremo las posibilidades de dicho hardware manipulando la controladora de vídeo. Por ejemplo, redefinían

David Montiel Ramirez 3

el juego de caracteres para crear caracteres semi-gráficos a medida, e incluso simulaban un cursor de ratón gráfico redefiniendo la apariencia de los caracteres sobre los que dicho cursor quedaba en cada momento. También pueden usarse estas técnicas para videojuegos 2D que necesiten aprovechar la mayor velocidad de manipulación de los modos de texto respecto a los gráficos. Muchos programas modernos con interfaz gráfica simulan el estilo de los programas en modo texto, especialmente cuando es importante preservar la alineación vertical del texto, por ejemplo, durante la programación. Existen también componentes software que emulan modos de texto, tales como los emuladores de terminal o la consola de Windows.

Búfer de vídeo. Físicamente se encuentra ubicada en la tarjeta de vídeo, pero forma parte de la memoria RAM del PC, aunque su acceso es mucho más lento que ésta. Aquí se almacenan los datos que posteriormente serán visualizados en el monitor.

Un sistema de vídeo viene definido por los siguientes parámetros:

En la memoria RAM de vídeo en modo texto, dada una página determinada, la primera posición la ocupa el primer carácter de la primera posición de la pantalla (esquina superior izquierda: fila 0, columna 0), a continuación viene el byte del atributo, luego el siguiente carácter de la línea seguido de su byte de atributo y así sucesivamente. Cuando termina la primera línea el siguiente carácter se corresponde con la primera posición a la izquierda de la siguiente

David Montiel Ramirez 4

fila y así sucesivamente. Podríamos calcular la posición en memoria de vídeo RAM de cualquier posición de la pantalla mediante la siguiente fórmula:

Posición en memoria = Línea * 160 + Columna * 2.

En el modo de texto sólo se puede trabajar con los 256 (de 0 a 255) caracteres ASCII que podemos ver en el Apéndice A, cada carácter ocupa una columna de las 80 que caben en cada una de las 25 filas posibles. Un pixel en modo gráfico es el menor puntito que podemos iluminar en la pantalla, en el modo 13h es de 320 puntitos por cada una de las 200 líneas posibles. En ambos casos empezamos a contar desde la esquina superior izquierda, avanzando hacia la derecha y cuando llegamos al extremo derecho bajamos a la fila inmediatamente inferior en su extremo izquierdo.

4.1.1 Escritura directa en el búfer de vídeo

El búfer de vídeo se encuentra localizado en la posición de memoria B800:0000 para tarjetas en color y en B000:0000 para tarjetas monocromo. De tal modo que podemos escribir directamente aquí sin usar las interrupciones BIOS o DOS para conseguir su salida a pantalla. Veamos a continuación el mismo ejemplo anterior pero usando escritura directa al búfer de vídeo:

La ventaja que obtenemos escribiendo directamente en la memoria de vídeo es mucha mayor rapidez, puesto que las interrupciones son muy lentas, en cuanto a un programa crítico en tiempo, como puede ser un juego.

Por contra saltarse el método estándar, como son las interrupciones, supone un riesgo de encontrarse un hardware que no soporte nuestro método de acceso a la memoria de vídeo, en este caso los resultados pueden ser impredecibles.

Veamos ahora un ejemplo muy interesante de escritura directa al búfer de vídeo para escribir en cada página de vídeo:

David Montiel Ramirez 5

4.1.2. Ejemplos completos en modo texto

Copper bars: Son unas barras que se mueven por la pantalla, incluso sobre el texto. Para ello modificaremos el color 0 (negro) desde que termina un barrido horizontal y antes de empezar el siguiente, de esta forma no notaremos ninguna interferencia en la pantalla. Este efecto no funciona bien en modo texto en la ventana MSDOS de mi Windows XP, pero sí en el del Windows 98, por ejemplo (podremos verlo en Windows XP cambiando a modo gráfico con MOV AH, 13h Int 10h). Para poderlos ver de forma correcta es necesario ejecutarlos a pantalla completa (Alt+Intro) sobre la ventana del MS-DOS.

Existen dos formas básicas de mover las barras: mediante un contador o siguiendo una matriz de datos correspondiente a la función seno, ello es debido a la que la función seno es cíclica "sube y baja".

Veamos el primer ejemplo de una barra sobre la pantalla con el primer método.

4.2 Acceso a discos en lenguaje ensamblador

En un ordenador sólo es posible trabajar directamente con los datos de la memoria RAM. Pero la memoria RAM es volátil, es decir, pierde su contenido cuando se apaga el ordenador. Por este motivo, para conservar datos de manera permanente se utilizan dispositivos de almacenamiento tales como disquetes o discos duros. En cualquier caso, cabe distinguir tres elementos:

Unidad de Disco. Dispositivo mecánico formado por una pila de uno o más discos (plato), que rotan sobre un eje, y dos o más cabezas de lectura/escritura cuya misión es leer y escribir la información en el disco. En las unidades de disquetes el plato comienza a girar cada vez que se accede al disquete, mientras que en las unidades de disco duro el movimiento giratorio es constante durante todo el tiempo que está encendido el ordenador. El plato de un disco duro gira a una velocidad de entre 3.600 y 5.400 r.p.m.

David Montiel Ramirez 6

Controlador de Disco. Dispositivo electrónico que establece la conexión entre el procesador y el disco. Por una parte, enlaza físicamente la unidad de disco con el bus de datos (camino por el que fluyen los datos dentro del ordenador). Y por otro lado, transforma las peticiones del sistema operativo en instrucciones especiales que actúan directamente sobre la unidad de disco.

Disco. Dispositivo magnético que almacena la información. Normalmente, los discos se componen de una superficie circular plana de plástico (disquete) o metal (disco duro) recubierta de algún óxido magnetizable. La información se graba sobre el disco mediante alteraciones de su superficie con un campo magnético.

4.2.1 Particiones del DOS.Para usar un disco duro primero hay que particionarlo (FDISK) y a continuación dar formato a cada una de las particiones (FORMAT). Bajo DOS, un disco duro puede tener dos particiones, una partición primaria y una partición extendida.

La partición primaria es imprescindible y designa la partición en la cual se almacenan los ficheros de arranque del sistema. La partición primaria es la partición activa.

La partición extendida puede dividirse a su vez en varias unidades lógicas. Una partición extendida sólo puede crearse cuando ya existe una partición primaria.

4.2.2. Parámetros absolutos de un Disco Duro.

Para acceder a los parámetros del disco duro, independientemente del número de las particiones, hay que obtener el contenido de la palabra doble de memoria situada en la dirección 0000:0104 que contiene la dirección donde se guarda una tabla de 16 bytes con los parámetros absolutos de la primera unidad de disco duro.

David Montiel Ramirez 7

Si se trata de una partición extendida, los datos de la entrada corresponden al total de las unidades lógicas que almacena. La partición extendida posee su propia tabla de particiones, pero sólo se usan las dos primeras entradas. La primera entrada corresponde a la primera unidad lógica de la partición extendida, y la segunda indica si hay otra unidad lógica. En caso afirmativo, ésta contiene de nuevo una tabla de particiones.

Con ello se crea una especie de lista enlazada que permite acceder a la información de las diferentes particiones.

4.2.3 Acceso a dispositivos de almacenamiento

Un dispositivo de almacenamiento de acceso directo, es cualquier tipo de dispositivos de almacenamiento secundario que tiene un tiempo de acceso bajo en proporción a su capacidad.

Un disco es una superficie plana, magnética dividida en círculos concéntricos a los cuales se les llama Tracks (pistas), además de tener 2 lados, cabe mencionar que los primeros discos únicamente tenían 1 sola cara. Cada track está dividido en sectores, los cuales almacenan un determinado número de bytes.

Las unidades de disco, son dispositivos capaces de leer o escribir en un disco para eso tiene una cabeza lectora quien realiza una operación de moverse al track deseado (Seek Time), y luego espera por el sector seleccionado (Latency Time).

4.2.4.- Acceso a disco usando lenguaje ensamblador

David Montiel Ramirez 8

Para leer o escribir en un disco, no se realiza byte a byte, sino más bien en bloque de bytes, debido a que el acceso a disco implica movimientos mecánicos además de que el acceso se da por sectores; en este proceso no intervienen el CPU, puesto que solo envía los comandos a la interface que maneja la unidad de disco y está es la que se encarga de leer o escribir información de un área en especial de memoria, llamada DMA; en este proceso es conocido acceso directo a memoria.

Rutinas que permiten lectura y escritura absoluta de sectores, así como la determinación del espacio libre disponible en un disco.

Rutina_AbsolutedRead: Transfiere el contenido de uno o más sectores del disco al buffer especificado, accesando directamente a los sectores lógicos. En caso de error, se enciende el bit de acarreo y AX contiene el código del error.

Rutina_AbsoluteWrite:

Transfiere el contenido del buffer especificado a uno o más sectores de disco, accesando directamente a los sectores lógicos. En caso de error, se enciende el bit de acarreo y AX contiene el código del error.

David Montiel Ramirez 9

Rutina_FreeDiskSpace: Devuelven en DX:AX el espacio libre en disco (en Kb). En caso de error, se enciende el bit de acarreo.

David Montiel Ramirez 10

4.3 Programación del puerto serial Puerto: Es un conjunto de líneas (interfaz) que puede utilizar el CPU para intercambiar información con otros dispositivos.

Puerto Serie: Transmite un bit a la vez, e.g. RS-232. Un puerto serie o puerto serial es una interfaz de comunicaciones de datos digitales, frecuentemente utilizado por computadoras y periféricos,donde la información es transmitida bit a bit enviando un solo bit a la vez, en contraste con el puerto paralelo que envía varios bits simultáneamente.

El canal serie del PC es uno de los recursos más comunes para la conexión de periféricos como pueden ser dispositivos de puntero (mouse) o de comunicación (modem, cables de conexión entre PCs).

Configuración del puerto serie

Cada uno de los puertos COM tiene 7 registros a comentar:

Registro base+0: tiene 3 funciones

Transmitter Hlding Register (THR); Su función es la de transmitir un dato (palabra) por el Puerto.

Reciver Data Register (RDR): Su función es la de recibir un dato (palabra) del puerto.

Baud Rate Divisor Low (BRDL): Velocidad del canal, parte baja.

Registro base+1: Tiene 2 funciones

Baud Rate Divisor High (BRDH): Velocidad del canal, parte alta. Interrupt Enable Register (IER): Activar o desactivar las interrupciones para

el puerto COM.

Registro base+2:

Interrupt ID Register (IIR): Controla la prioridad de las interrupciones. Registro Base+3: Line Control Register (LCR): Controla los parámetros de configuración del

canal serie (velocidad…).

Registro base+4:

Modem Control Register (MCR): Activa las señales del MODEM.

Registro base+5:

Line Status Register (MSR): Muestra el estado del modem.

Registro base+6:

David Montiel Ramirez 11

Modem Status Register (MSR): Muestra el estado del Modem.

Debemos configurar correctamente el puerto serial antes de trabajar con él. Y para configurarlo hacemos lo siguiente:

Primero configuramos el LCR, pero poniendo el bit DLAB a 1. Luego configuro el DRDL, seguidamente el BRDH y finalmente vuelvo a configurar el LCR con los mismos bits que antes, pero esta vez el bit DLAB a 0.

4.3.1 Explicación de los registros

LCR: Con este registro definimos (configuramos) los parámetros de la comunicación serie.

DLAB es el bit de más peso y Num (1) el de menos peso.

Stop: Indica el número de bits de stop que enviará (o esperará) del puerto. Lo normal es poner un 0 en este bit para conseguir un bit de stop. Pero si ponemos un 1, el canal usará 1.5 bits de stop si el número de bits de la palabra (configurada en Num) es de 5. En caso de que sean más de 5, se usaran 2 stop bits. Puede que en determinados momentos nos sea de utilidad, pero yo lo único que veo es que envía 10 bits en lugar de 9, cosa que implica más tiempo en él envió, así que siempre ponemos un 0 (1 stop bit).

Paridad: Indica si hay paridad en la comunicación serial. Con un 0 le diremos que nos queremos paridad, y con un 1 que sí. La paridad es una manera de detectar errores, pero debemos programar nuestro programa para que lo detecte. Así que de momento ponemos un 0.

Tipo: Este bit nos indicará el tipo de paridad que vamos a usar. Con un 0 le indicaremos que vamos a mirar la paridad de modo impar, mientras que con 1 miraremos la paridad de modo par.

Stick: Indica el nivel que usaremos para la paridad, si ponemos un 0, contaremos el número de 1 para la paridad. Y si ponemos un 1 contaremos el número de 0 para la paridad.

Break: Fuerza un corte de la comunicación. Si lo dejamos a 0 no pasará nada, pero si lo ponemos a i cortamos la comunicación y forzamos la salida a 0.

David Montiel Ramirez 12

DLAB: Bit interno, de uso no es decisivo. Lo que hace es configurar una vez el puerto poniendo a 1 este bit, configurar la velocidad (los 2 registros) y luego volver a configurar el puerto poniendo un 0.

4.3.2. Abrir un canal asociado a un puerto serieLo primero que necesitamos es un fichero asociado a nuestro puerto serie. Para eso usaremos la función del API CreateFile. CreateFile es una función con muchas opciones y que sirve para muchas cosas, pero ahora nos centraremos en el puerto serie.

Veremos ahora los valores posibles de los siete parámetros que necesita esta función:

1. LPCTSTR lpFileName: Nombre del fichero. Se trata de una cadena que contiene el nombre del puerto que queremos abrir. Los valores posibles son "COM1", "COM2", "COM3" y "COM4".

2. DWORD dwDesiredAccess: Tipo de acceso. En general querremos leer y escribir en el puerto, por lo tanto especificaremos los valores GENERIC_READ | GENERIC_WRITE.

3. DWORD dwShareMode: modo en que se comparte el fichero. En nuestro caso, un puerto serie no puede ser compartido, de modo que usaremos 0 para este parámetro.

4. LPSECURITY_ATTRIBUTES lpSecurityAttributes: Atributos de seguridad, especifican el modo en que el fichero se puede heredar por procesos hijos. En nuestro caso no queremos que eso ocurra, de modo que usamos el valor NULL.

5. DWORD dwCreationDistribution: modo de creación. Los puertos serie son dispositivos físicos, por lo tanto, existen. El modo de creación será OPEN_EXISTING.

6. DWORD dwFlagsAndAttributes: Atributos del fichero. Por ahora no nos interesa ninguno de estos atributos, usaremos el valor 0.

7. HANDLE hTemplateFile: Plantilla de fichero. Se puede especificar un fichero existente del cual se copirarán los atributos. En nuestro caso no usaremos esta opción, y usaremos el valor NULL para este parámetro.

idComDev = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE,

0, NULL, OPEN_EXISTING, 0, NULL);

David Montiel Ramirez 13

4.3.3 Modificar los parámetros de transmisiónEn general, necesitaremos establecer los parámetros de la línea serie que vamos a usar. Tendremos que fijar la velocidad de transmisión, el número de bits de datos, la paridad, y los bits de stop. Y a veces algunos parámetros más.

Para hacer esto, primero recuperaremos los parámetros del canal que acabamos de abrir, los modificaremos y actualizaremos la coniguración del canal.

Para recuperar los parámetros usaremos la función GetCommState. Esta función nos devuelve una estructura DCB, que contiene la configuración actual del puerto serie.

fSuccess = GetCommState(idComDev, &dcb);

De todos los valores que incluye la estructura DCB, de momento sólo nos preocuparemos por unos pocos:

1. DWORD BaudRate: Velocidad en baudios. Este parámetro puede tener los siguientes valores:

CBR_110, CBR_300, CBR_600, CBR_1200, CBR_2400, CBR_4800, CBR_9600, CBR_14400, CBR_19200, CBR_38400, CBR_56000, CBR_57600, CBR_115200, CBR_128000 y CBR_256000.

2. BYTE ByteSize: Tamaño de los datos en bits. Tradicionalmente 7 u 8.3. BYTE Parity: Valor de paridad. Se admiten los valores EVENPARITY,

para paridad par; MARKPARITY; NOPARITY, para no paridad y ODDPARITY, para paridad impar.

4. BYTE StopBits: Bits de stop. Admite los valores ONESTOPBIT, 1 bit de stop; ONE5STOPBITS, 1.5 bits de stop y TWOSTOPBITS, 2 bits de stop.

Una vez que hemos actualizado la estructura de datos podemos configurar el puerto enviándosela mediante la función: GetCommState.

SetCommState(idComDev, &dcb);

4.3.4. Monitorización de eventosPodemos especificar qué eventos de los que se pueden producir en el puerto serie nos interesa procesar o monitorizar. De este modo, el sistema operativo nos avisará cada vez que se produzca uno de esos eventos.

El modo de especificar los eventos de interés es mediante una máscara, y para hacerlo usaremos la función SetCommMask.

Se pueden especificar varios eventos, pero generalmente nos interesararán sólo dos de ellos, al menos en la aplicaciones normales:

David Montiel Ramirez 14

1. EV_RXCHAR: se ha recibido un carácter y se a colocado en el buffer de entrada.

2. EV_TXEMPTY: de ha enviado el último carácter del buffer de salida.

Para nuestro ejemplo sólo monitorizaremos el evento EV_RXCHAR.

4.3.5. Escribir en el puerto serie

Para enviar caracteres al puerto serie se usa la función WriteFile.

Sin embargo, como ya hemos explicado, no basta con enviar los caracteres al puerto serie, el destinatario puede interrumpir la transmisión si no es capaz de procesar los datos a la misma velocidad que se los enviamos, de modo que los datos que intentamos enviar pueden no ser enviados por completo.

Para estar seguros de que enviamos toda la información que queremos, usaremos uno de los parámetros que devuelve la función, y que nos dice cuántos caracteres se han enviado. Colocando la función WriteFile en un bucle, podemos enviar los caracteres que aún están pendientes hasta que todos hayan sido enviados.

WriteFile puede retornar con valor false si se ha producido un error. Sin embargo, uno de los errores no es tal, el error ERROR_IO_PENDING en realidad sólo nos informa de que no se ha completado la operaci ón de escritura. En caso de recibir ese error, debemos continuar enviado datos al puerto serie.

void EscribirSerie(char *buf){char Buffer[1024];DWORD n, l, p, err;strcpy(Buffer, buf);l = strlen(Buffer); // Longitud de los datosp = 0; // Posición actual de los datos a enviarwhile(l) {if(!WriteFile(idComDev, &Buffer[p], 1, &n, NULL)) {err = GetLastError();if(err != ERROR_IO_PENDING) {Comunicacion = false;return;}}

David Montiel Ramirez 15

l -= n;p += n;

}

}

4.3.6 Esperar a que haya algo para leer

Por la misma naturaleza de las transmisiones, y debido a que nuestro ordenador normalmente será muy rápido en comparación con las velocidades de transmisión, la mayor parte del tiempo no estaremos recibiendo nada por el puerto serie.

Ya hemos definido la máscara de eventos que queremos recibir del puerto serie. Para saber si se ha producido uno de esos eventos tenemos que llamar a la función WaitCommEvent.

Pero, tal como hemos configurado el puerto serie, esta función no regresa mientras no se produzca uno de los eventos que hemos definido. Esto nos impide que nuestro programa realice otras tareas, como por ejemplo, enviar información al puerto.

Necesitamos un mecanismo que avise a nuestro programa cuando existan datos para leer, pero no debemos bloquear el sistema preguntando constantemente si hay algo preparado. Ni siquiera debemos bloquear nuestro programa, a menudo hay otras cosas que hacer además de esperar la llegada de nueva información.

La mejor forma es introducir la función WaitCommEvent en un hilo distinto del de nuestro programa principal. Podemos hacer que ese hilo espere a que se produzca un evento, y cuando eso ocurra, que lo procese.

En nuestro caso, sólo se puede producir un evento, de modo que una función posible para procesarlo es:

// Hilo de escucha del puerto serie:DWORD Hilo(LPDWORD lpdwParam){DWORD dwEvtMask;do {if(WaitCommEvent(idComDev, &dwEvtMask, NULL))if(dwEvtMask & EV_RXCHAR) LeeSerie();} while(true);

David Montiel Ramirez 16

return 0;}

Esta función coloca la función WaitCommEvent en un bucle infinito, y cuando detecta el evento EV_RXCHAR, hace una llamada a la función LeeSerie(), que procesa los datos recibidos.

Por supuesto, en algún lugar del programa, debemos lanzar el hilo, esto se hace con la función CreateThread.

hHilo = CreateThread(NULL, 0, Hilo, &param, 0, &id);

4.3.7 Leer desde el puerto serieLo primero que necesitamos saber es cuantos caracteres hay en el buffer de entrada. Para eso podemos usar la función ClearCommError. Esta función nos actualiza una estructura COMSTAT, uno de cuyos miembros es cbInQue, que nos dice cuantos caracteres hay en el buffer de entrada.

Con ese dato podemos llamar a la función ReadFile, y leer todos los caracteres que haya en el buffer.

// Leer datos del puerto serie:void LeeSerie(){int i, j, k;DWORD x;COMSTAT cs;// Actualizar COMSTAT, sirve para// averiguar el número de bytes en el buffer de entrada:ClearCommError(idComDev, &x, &cs);// Leer cs.cbInQue caracteres:ReadFile(idComDev, cad, cs.cbInQue, &x, NULL);// Actualizar el fin de cadena:cad[x]=0;// Mostrar caracteres leídos:cout << cad;return;}

David Montiel Ramirez 17

4.4 Programación del puerto paralelo

Puerto Paralelo: Transmite más de un bit a la vez, e.g. 8-bits.

Originalmente, el puerto paralelo de la PC, fue pensado para conectar impresoras, pero puede ser usado para manejar dispositivos en general .Las 12 salidas TTL (0-5v) usan latches internos y pueden programarse vía instrucciones IN/OUT del CPU.

El puerto paralelo de una PC es ideal para ser usado como herramienta de control de motores, LED's, etc. El mismo posee un bus de datos de 8 bits (Pin 2 a 9) y muchas señales de control, algunas de salida y otras de entrada que también pueden ser usadas fácilmente.

Las PC's generalmente poseen solo uno de estos puertos (LPT1) pero se le puede adicionar una tarjeta con un segundo puerto paralelo (LPT2). En reglas generales la dirección hexadecimal del puerto LPT1 es igual a 0x378 (888 en decimal) y 0x278 (632 en decimal) para el LPT2. Esto se puede verificar fácilmente en el setup de la PC.

Las 5 entradas son "steady-state input points" y pueden programarse vía instrucciones IN del CPU, las 3 direcciones del puerto (DATA, STATUS, CONTROL) inician comúnmente en la 378H (otras direcciones comunes son la 278H y 3BCH); una de las líneas de entrada es además una interrupción (que puede habilitarse vía programa) y ademas hay una línea tipo "power-on reset"Buscando Direcciones del Puerto Paralelo.

Normalmente la PC tiene definidos tres puertos paralelo de impresión: LPT1, LPT2 y LPT3:

LPT: En las localidades 0000:0408H a 0000:040DH de la PC se encuentran las direcciones de cada puerto [5]

EJEMPLO: Sean los siguientes valores de una PC hipotética

Tabla 1. LPT1 se localiza en 378H, LPT2 en 278H y LPT3 no está presente.

David Montiel Ramirez 18

Podemos localizar la dirección precisa de cada puerto paralelo en una PC de las siguientes formas:

Desde DEBUG: Mediante el comando d 0:408 40d

Desde Windows: Inicio / Configuración / Panel de Control / Sistema / Administrador de Dispositivos / Puertos (COM y LPT) / Puerto de Impresora / Recursos.

Programando el Puerto Paralelo

Control de Impresora: Se envían datos ó comandos seguidos de una señal strobe que ocasiona que la impresora lea el puerto y responda por las líneas de status cuando esté lista para recibir más información (not bussy) ó en su defecto, indica si hay algún error Opciones para Controlar el Puerto Paralelo [4]:

Acceso Directo: Usando ensamblador o un lenguaje de programación, leyendo variables del sistema, manipulando bits y leyendo/escribiendo puertos

Via BIOS: La INT 17H del BIOS provée 3 servicios: inicializar, imprimir y status (sólo trabajan para LPT1)Via DOS: La INT 21H servicio 05h escribe un caracter y el servicio 40h que trabaja con archivos.

4.4.1 Conector Puerto Paralelo

El puerto paralelo de un PC posee un conector de salida del tipo DB25 hembra cuyo diagrama y señales utilizadas podemos ver en la siguiente figura:

David Montiel Ramirez 19

Características del puerto paralelo ó LPT

En el ámbito de la electrónica comercial se le denomina como conector DB25 ("D-subminiature type B, 25 pin"), esto es D-subminiatura tipo B, con 25 huecos para pines.

Se utilizaba principalmente para la conexión de impresoras, unidades de lectura para discos ZIP y escáneres.

Para conectar y desconectar los dispositivos, así como para que la computadora los reconozca de manera correcta, es necesario apagar y reiniciar la computadora.

Modos del puerto paralelo ó LPT

a) Modo SPP: significa ("Standar Parallel Port") ó "puerto paralelo estándar". Es el estándar con que se identificó al puerto paralelo inicialmente, es el mas compatible y actualmente este modo hay que activarlo desde el BIOS-SETUP de la computadora para que el sistema reconozca impresoras antiguas. Permite una velocidad de transferencia entre 150KiloBytes/segundo (KB/s) a 500 KB/s.

b) Modo EPP: significa ("Enhanced Parallel Port") ó su traducción al español es puerto paralelo mejorado. Se diseñó para leer y escribir a la velocidad del bus ISA alcanzando velocidades de transferencia de hasta 1 MB/s. Permite la comunicación bi-direccional entre la computadora y el dispositivo (IEEE1284) y es compatible con SPP. Permite una velocidad de transferencia entre 500 KiloBytes/segundo (KB/s) a 2 MegaBytes/segundo (MB/s).

c) Modo ECP: significa ("Enhanced Capabilities Port") ó su traducción al español es puerto de capacidad mejorada. Posee capacidad DMA (Direct Memory Access) ó capacidad directa para envío de datos hacia

David Montiel Ramirez 20

la memoria RAM, lo que reduce el tiempo de respuesta; supera la transferencia de 1 MegaByte/segundo (MB/s) y permiten la emulación de otros modos cuando sea necesario. Permite la comunicación bi-direccional entre la computadora y el dispositivo  (IEEE1284), además es compatible con SPP y EPP.

4.5 Programación híbrida

La programación hibrida es utilizada en los casos en donde el código en ensamblador dificulta la estructuración del programa. La programación híbrida proporciona un mecanismo por medio del cual podemos aprovechar las ventajas del lenguaje ensamblador y los lenguajes de alto nivel, todo esto con el fin escribir programas más rápidos y eficientes.

Las directivas de programación hibrida son aquellas que nos permiten ejecutar los comandos de ensamblador en un lenguaje de alto nivel.

La programación híbrida proporciona un mecanismo por medio del cual podemos aprovechar las ventajas del lenguaje ensamblador y los lenguajes de alto nivel, todo esto con el fin de escribir programas más rápidos y eficientes.

Directivas para compilación híbrida: La compilación hibrida es utilizada en lo que es conocida como programación hibrida (válgase la redundancia). La programación hibrida es utilizada en los casos en donde el código en ensamblador dificulta la estructuración del programa. La programación híbrida proporciona un mecanismo por medio del cual podemos aprovechar las ventajas del lenguaje ensamblador y los lenguajes de alto nivel, todo esto con el fin escribir programas más rápidos y eficientes.

Ejemplo: la red es el siguiente donde utilizamos código en ensamblador y código pascal. El siguiente código sirve para limpiar pantalla, está escrito en ensamblador dentro de una función en pascal, lo que es lo mismo a la función ClrScr en pascal.

En fin podemos mezclar el código ensamblador con el código de cualquier otro lenguaje que admita este procedimiento. En pascal antes de escribir el código en ensamblador ay que poner Asm y al final de nuestro código End.

David Montiel Ramirez 21

4.5.1 Operadores

Operadores Aritméticos: Pueden emplearse libremente (+), (-), (*) y (/). En este último caso la división es siempre entera. También se admiten los operadores MOD (resto de la división) y SHL/SHR (desplazar a la izquierda/derecha cierto número de bits).

Operadores Lógicos:

Pueden ser el AND, OR, XOR y NOT. Realizan las operaciones lógicas en las expresiones.

Operadores relacionales:

Devuelven condiciones de cierto (0FFFFh o 0FFh) o falso (0) evaluando una expresión. Pueden ser: EQ (igual), NE (no igual), LT (menor que), GT (mayor que), LE (menor o igual que), GE (mayor o igual que).

Operadores de retorno de valores:

Operador SEG: devuelve el valor del segmento de la variable o etiqueta, silo se puede emplear en programas de tipo EXE:

Operador OFFSET: devuelve el desplazamiento de la variable o etiqueta en su segmento:

Si se desea obtener el offset de una variable respecto al grupo (directiva GROUP) de segmentos en que está definida y no respecto al segmento

concreto en que está definida:

Operador .TYPE: Devuelve el modo de la expresión indicada en un byte. El bit 0 indica modo «relativo al código» y el 1 modo «relativo a datos», si ambos bits están inactivos significa modo absoluto. El bit 5 indica si la expresión es local (0 si está definida externamente o indefinida); el bit 7 indica si la expresión contiene una referencia externa. El TASM utiliza también el bit 3 para indicar algo que desconozco. Este operador es útil sobre todo en las macros para determinar el tipo de los parámetros:

David Montiel Ramirez 22

Operador TYPE: devuelve el tamaño (bytes) de la variable indicada. No valido en variables DUP:

Operadores MASK y WIDTH: Informan de los campos de un registro de bits (base RECORD).

Operadores de Atributos:

Operador PTR: redefine el atributo de tipo (BYTE, WORD, DWORD, QWORD, TBYTE) o el de distancia

(NEAR o FAR) de un operando de memoria.

Por ejemplo, si se tiene una tabla definida de la siguiente manera:

Para colocar en AL el primer byte de la misma, la instrucción MOV AL, tabla es incorrecta, ya que tabla (una cadena 10 palabras) no cabe en el registro AL. Lo

que desea el programador es indicárselo en este caso explícitamente al ensamblador de la siguiente manera:

Trabajando con varios segmentos, PTR puede redefinir una etiqueta NEAR de uno de ellos para convertirla en FAR desde el otro, con objeto de poder llamarla.

Operadores CS:, DS:, ES: y SS:

El ensamblador genera un prefijo de un byte que indica al microprocesador el segmento que debe emplear para acceder a los datos en memoria. Por defecto, se supone DS para los registros BX, DI o SI (o sin registros de base o índice) y SS para SP y BP. Si al acceder a un dato este no se encuentra en el segmento por defecto, el ensamblador añadir el byte adicional de manera automática. Sin embargo, el programador puede forzar también esta circunstancia:

David Montiel Ramirez 23

4.6 Programación de puerto USBUSB viene de frase en Ingles “Universal Serial Bus” que se utiliza para describir un tipo de puerto en la computadora personal en donde se conectan distintos periféricos tales como máquinas de imprimir, cámaras fotográficas, teclados de computadoras e infinidad de productos de uso generalizado.

Un puerto es una localización en la computadora en donde conectamos los periféricos. Estos pueden enviar información a la computadora, recibir información de la misma o hacer ambas cosas.

La computadora personal moderna tiene dos puertos típicos de conexión:

a) El puerto USB descrito anteriormenteb) El puerto Ethernet usado para conectar la computadora personal a la

Internet

También incluye internamente otros puertos nombrados PCI etc. para usos en aplicaciones que requieran mayores velocidades de transferencia de información los cuales no fueron objeto de investigación en este trabajo. Nos concentramos específicamente en el puerto USB.

David Montiel Ramirez 24

Bibliografíahttp://www.abreojosensamblador.net/Productos/AOE/html/Pags/Cap08.html

http://expo.itch.edu.mx/view.php?f=asm_31

http://www.itescam.edu.mx/principal/sylabus/fpdb/recursos/r86275.PDF

Ensamblador del 80/86.Facultad de informática. Universidad de Murcia. Apuntes realizados por Juan Fernández Peinador.

http://arcaicos-pr.com/uploads/3/0/4/9/3049639/uso_del_puerto_usbuniversal_serial_bus_de_la_pc_nov_09_2011.pdf

http://es.scribd.com/doc/44098211/programacion-hibrida

David Montiel Ramirez 25