• No se han encontrado resultados

COMO PROGRAMAR EL PUERTO PARALELO

N/A
N/A
Protected

Academic year: 2021

Share "COMO PROGRAMAR EL PUERTO PARALELO"

Copied!
12
0
0

Texto completo

(1)

COMO PROGRAMAR

COMO PROGRAMAR

COMO PROGRAMAR

COMO PROGRAMAR

EL PUERTO

EL PUERTO

EL PUERTO

EL PUERTO

PARALELO

PARALELO

PARALELO

PARALELO

Ing. Jose Antonio Ruiz Laureano

El presente documento es una breve recopilación de datos referentes a como se programa el puerto paralelo para su utilización en automatismos, circuitos electronicos controlados por computadora y en demostraciones didacticas de cómo un sistema operativo, como lo es Windows, controla el puerto para la muestra de datos.

Este articulo esta referenciado en datos obtenidos en diferentes paginas de Internet, ante lo cual agradezco de antemano a sus diferentes autores que esa informacion sea de carácter abierto. Para poder entender algunos aspectos de la programación, se recomienda tener algunos conocimientos basicos en el lenguaje de programación C y de la electronica de control, mas que nada en lo que respecta a la comprensión de conceptos como lo son librerias de instrucciones, instrucciones basicas, el concepto de palabra reservada y programa principal.

Espero este trabajo sea de su agrado y realmente le sirva como un apoyo en la enseñanza de la programación de sistemas para la comunicación hardware-software, agradezco su atención de antemano y disfruten de este trabajo.

Ing. Jose Antonio Ruiz Laureano Ingeniero Electronico en Computación

(2)

Esta primera unidad se enfocara básicamente a dar algunos aspectos de la programación en C/C++ que son necesarios para programar el puerto.

Cabe mencionar que no se pretende enseñar el lenguaje en esta unidad, solo describe de manera muy general las sentencias y palabras que se requieren en la programación del puerto, si se requiere conocer mas sobre el lenguaje se recomiendan varios cursos para conocer este lenguaje tan poderoso.

Primeramente se dara una descripción muy general de lo que es el lenguaje C/C++ y su estructura.

El lenguaje C/C++ se conoce como un lenguaje compilado. Existen dos tipos de lenguaje: interpretados y compilados. Los interpretados son aquellos que necesitan del código fuente para funcionar (P.ej: Basic). Los compilados convierten el código fuente en un fichero objeto y éste en un fichero ejecutable. Este es el caso del lenguaje C/C++.

Podemos decir que el lenguaje C/C++ es un lenguaje de nivel medio, ya que combina elementos de lenguaje de alto nivel con la funcionalidad del lenguaje ensamblador. Es un lenguaje estructurado, ya que permite crear procedimientos en bloques dentro de otros procedimientos. Hay que destacar que el C es un lenguaje portable, ya que permite utilizar el mismo código en diferentes equipos y sistemas informáticos: el lenguaje es independiente de la arquitectura de cualquier máquina en particular.

Estructura de un programa en C/C++

Todo programa en C/C++ consta de una o más funciones, una de las cuales se llama main. El programa comienza en la función

UNIDAD 1

ALGUNOS ASPECTOS

DE PROGRAMACION

main, desde la cual es posible llamar a otras funciones. Cada función estará formada por la cabecera de la función, compuesta por el nombre de la misma y la lista de argumentos (si los hubiese), la declaración de las variables a utilizar y la secuencia de sentencias a ejecutar. Ejemplo: declaraciones globales main( ) { variables locales bloque } funcion1( ) { variables locales bloque } Los comentarios

A la hora de programar es conveniente añadir comentarios (cuantos más mejor) para poder saber que función tiene cada parte del código, en caso de que no lo utilicemos durante algún tiempo. Además facilitaremos el trabajo a otros programadores que puedan utilizar nuestro archivo fuente.

Para poner comentarios en un programa escrito en C usamos los símbolos /* y */:

/* Este es un ejemplo de comentario */ /* Un comentario también puede estar escrito en varias líneas */

El símbolo /* se coloca al principio del comentario y el símbolo */ al final. El comentario, contenido entre estos dos símbolos, no será tenido en cuenta por el compilador.

(3)

Palabras clave

Existen una serie de indicadores reservados, con una finalidad determinada, que no podemos utilizar como identificadores. A continuación vemos algunas de estas palabras clave:

char int float double if

else do while for switch short long extern

static default

continue break register sizeof typedef

Variable

Una variable es un tipo de dato, referenciado mediante un identificador (que es el nombre de la variable). Su contenido podrá ser modificado a lo largo del programa.

Una variable sólo puede pertenecer a un tipo de dato. Para poder utilizar una variable, primero tiene que ser declarada:

[calificador] <tipo> <nombre>

Es posible inicializar y declarar más de una variable del mismo tipo en la misma sentencia:

[calificador]<nombre1>,<nombre2>=<valor>,<nombre3>=<valor>

Constantes

Al contrario que las variables las constantes mantienen su valor a lo largo de todo el programa.

Para indicar al compilador que se trata de una constante, usaremos la directiva #define:

#define <identificador> <valor>

Observe que no se indica el punto y coma de final de sentencia ni tampoco el tipo de dato.

La directiva #define no sólo nos permite sustituir un nombre por un valor numérico, sinó también por una cadena de caracteres.

El valor de una constante no puede ser modificado de ninguna manera.

Secuencias de escape

Ciertos caracteres no representados gráficamente se pueden representar mediante lo que se conoce como secuencia de escape. A continuación vemos una tabla de las más significativas:

\n salto de línea \b retroceso \t tabulación horizontal \v tabulación vertical \\ contrabarra \f salto de página \' apóstrofe \" comillas dobles

\0 fin de una cadena de caracteres

Inclusión de librerias

En la programación en C es posible utilizar funciones que no esten incluídas en el propio programa. Para ello utilizamos la directiva #include, que nos permite añadir librerías o funciones que se encuentran en otros archivos a nuestro programa indicando que se encuentran en el directorio por defecto del compilador.

#include <misfunc.h>

Operadores

A continuación se explican los tipos de operadores (aritméticos y de asignación) que permiten realizar operaciones matemáticas en lenguaje C.

Existen dos tipos de operadores aritméticos: Los binarios:

(4)

+ Suma - Resta * Multiplicación / División % Módulo (resto) y los unarios: ++ Incremento (suma 1) - - Decremento (resta 1) - Cambio de signo Su sintaxis es: binarios: <variable1><operador><variable2> unarios: <variable><operador> <operador><variable>. Operadores de asignacion

La mayoría de los operadores aritméticos binarios explicados anteriormente tienen su correspondiente operador de asignación:

= Asignación simple += Suma -= Resta *= Multiplicación /= División %= Módulo (resto)

Con estos operadores se pueden escribir, de forma más breve, expresiones del tipo:

n=n+3 se puede escribir n+=3

k=k*(x-2) lo podemos sustituir por k*=x-2

Operadores relacionales

Los operadores relacionales se utilizan para comparar el contenido de dos variables. En C existen seis operadores relacionales básicos:

> Mayor que < Menor que

>= Mayor o igual que <= Menor o igual que == Igual que

!= Distinto que

El resultado que devuelven estos operadores es 1 para Verdadero y 0 para Falso.

Funcion de salida de datos en pantalla.

La rutina printf permite la aparición de valores numéricos, caracteres y cadenas de texto por pantalla. El prototipo de la sentencia printf es el siguiente:

printf(control,arg1,arg2...);

En la cadena de control indicamos la forma en que se mostrarán los argumentos posteriores. También podemos introducir una cadena de texto ( sin necesidad de argumentos ), o combinar ambas posibilidades, así como secuencias de escape. En el caso de que utilicemos argumentos deberemos indicar en la cadena de control tantos modificadores como argumentos vayamos a presentar.

Funcion de entrada de datos desde teclado

La rutina scanf permite entrar datos en la memoria del ordenador a través del teclado. El prototipo de la sentencia scanf es el siguiente:

(5)

En la cadena de control indicaremos, por regla general, los modificadores que harán referencia al tipo de dato de los argumentos. Al igual que en la sentencia printf los modificadores estarán formados por el caracter % seguido de un caracter de conversión. Los argumentos indicados serán, nuevamente, las variables.

La principal característica de la sentencia scanf es que necesita saber la posición de la memoria del ordenador en que se encuentra la variable para poder almacenar la información obtenida. Para indicarle esta posición utilizaremos el símbolo ampersand ( & ), que colocaremos delante del nombre de cada variable. ( Esto no será necesario en los arrays ).

Sentencias condicionales

Este tipo de sentencias permiten variar el flujo del programa en base a unas determinadas condiciones. Existen varias estructuras diferentes:

Estructura IF...ELSE

Sintaxis:

if (condición) sentencia;

La sentencia solo se ejecuta si se cumple la condición. En caso contrario el programa sigue su curso sin ejecutar la sentencia. Otro formato:

if (condición) sentencia1; else sentencia2;

Si se cumple la condición ejecutará la sentencia1, sinó ejecutará la sentencia2. En cualquier caso, el programa continuará a partir de la sentencia2. Sentencia FOR Su sintaxis es: for (inicialización;condición;incremento){ sentencia1; sentencia2; }

La inicialización indica una variable (variable de control) que condiciona la repetición del bucle. Si hay más, van separadas por comas: for (a=1,b=100;a!=b;a++,b- -){ Sentencia DO...WHILE Su sintaxis es: do{ sentencia1; sentencia2; }while (condición);

Con esta sentencia se controla la condición al final del bucle. Si ésta se cumple, el programa vuelve a ejecutar las sentencias del bucle.

Pues bien, una vez vistos estos aspectos (recordando que esta unidad no pretendia enseñar a programar en C, si no solo conocer los aspectos basicos del mismo para la programación del puerto) corresponde ahora solo practicarlos realizando programas de control hacia el puerto, relacionandolos con los datos necesarios que seran requeridos en su momento.

(6)

Una vez vistos los aspectos basicos de la programación en C, que sera requerida para controlar dispositivos con el puerto de la PC, ahora toca ver los aspectos relacionados al hardware, la estructura del puerto, como funciona este.

Los puertos de comunicación de la PC son de particular interés para el estudioso de la electrónica ya que le permiten utilizar una computadora personal para controlar todo tipo circuitos electrónicos utilizados, principalmente, en actividades de automatización de procesos, adquicisión de datos, tareas repetitivas y otras actividades que demandan precisión.

Existen dos métodos básicos para transmisión de datos en las computadoras modernas. En un formato de transmisión de datos en serie un dispositivo envía datos a otro a razón de un bit a la vez a través de un medio. Por otro lado, en un formato de transmisión de datos en paralelo un dispositivo envía datos a otro a una tasa de n número de bits a través de n número de medios a un tiempo. Sería fácil pensar que un sistema en paralelo es n veces más rápido que un sistema en serie, sin embargo ésto no se cumple, básicamente el impedimiento principal es el tipo de cable que se utiliza para interconectar los equipos.

Si bién un sistema de comunicación en paralelo puede utilizar cualquier número de cables para transmitir datos, la mayoría de los sistemas paralelos utilizan ocho líneas de datos para transmitir un byte a la vez.

Un típico sistema de comunicación en paralelo puede ser de una dirección (unidireccional) o de dos direcciones (bidireccional). Donde tambien distinguimos dos elementos: la parte transmisora y la parte receptora. La parte transmisora coloca la información en

UNIDAD 2

ESTRUCTURA DEL

PUERTO PARALELO

las líneas de datos e informa a la parte receptora que la información (los datos) están disponibles; entonces la parte receptora lee la información en las líneas de datos e informa a la parte transmisora que ha tomado la información (los datos).

Observe que ámbas partes sincronizan su respectivo acceso a las líneas de datos, la parte receptora no leerá las líneas de datos hasta que la parte transmisora se lo indique en tanto que la parte transmisora no colocará nueva información en las líneas de datos hasta que la parte receptora remueva la información y le indique a la parte transmisora que ya ha tomado los datos, a ésta coordinación de operaciones se le llama acuerdo ó entendimiento el cual es llamado handshaking.

Para implementar el handshaking se requieren dos líneas adicionales. La línea de strobe es la que utiliza la parte transmisora para indicarle a la parte receptora la disponibilidad de información. La línea de admisión (acknowledge) es la que utiliza la parte receptora para indicarle a la parte transmisora que ha tomado la información (los datos) y que está lista para recibir más datos.

El puerto paralelo provee de una tercera línea de handshaking llamada en inglés busy (ocupado), ésta la puede utilizar la parte receptora para indicarle a la parte transmisora que está ocupada y por lo tanto la parte transmisora no debe intentar colocar nueva información en las líneas de datos. Una típica sesión de transmisión de datos se parece a lo siguiente:

1. La parte transmisora checa la línea busy para ver si la parte receptora está ocupada. Si la línea busy está activa, la parte transmisora espera en un bucle hasta que la línea busy esté inactiva.

2. La parte transmisora coloca la información en las líneas de datos.

3. La parte transmisora activa la línea de strobe.

4. La parte transmisora espera en un bucle hasta que la línea acknowledge está activa.

5. La parte transmisora inactiva la línea de strobe.

6. La parte transmisora espera en un bucle hasta que la línea acknowledge esté inactiva.

(7)

7. La parte transmisora repite los pasos anteriores por cada byte a ser transmitido.

8. La parte receptora inactiva la línea busy (asumiendo que está lista para recibir información).

9. La parte receptora espera en un bucle hasta que la línea strobe esté activa.

10. La parte receptora lee la información de las líneas de datos (y si es necesario, procesa los datos).

11. La parte receptora activa la línea acknowledge.

12. La parte receptora espera en un bucle hasta que esté inactiva la línea de strobe.

13. La parte receptora inactiva la línea acknowledge.

14. La parte receptora repite los pasos anteriores por cada byte que debe recibir.

Se debe ser muy cuidadoso, tanto la parte transmisora como la receptora coordinan sus acciones de tal manera que la parte transmisora no intentará colocar varios bytes en las líneas de datos, en tanto que la parte receptora no debe leer más datos que los que le envíe la parte transmisora, un byte a la vez.

Estructura del puerto paralelo

El puerto paralelo de una típica PC utiliza un conector hembra de tipo D de 25 pines (DB-25). El orden de los pines del conector es éste:

La siguiente tabla describe la función de cada patita del conector 1284 tipo A:

Pin E/S Polaridad Descripción

1 Salida 0 Strobe

2 ~ 9 Salida - Líneas de datos (bit 0/patita 2, bit 7/patita 9) 10 Entrada 0

Línea acknowledge

(activa cuando el sistema remoto toma datos)

11 Entrada 0

Línea busy

(si está activa, el sistema remoto no acepta datos)

12 Entrada 1

Línea Falta de papel

(si está activa, falta papel en la impresora)

13 Entrada 1

Línea Select

(si está activa, la impresora se ha seleccionado)

14 Salida 0

Línea Autofeed

(si está activa, la impresora inserta una nueva

línea por cada retorno de carro) 15 Entrada 0

Línea Error

(si está activa, hay un error en la impresora)

16 Salida 0

Línea Init

(Si se mantiene activa por al menos 50 micro-segundos, ésta señal

autoinicializa la impresora) 17 Salida 0

Línea Select input

(Cuando está inactiva, obliga a la impresora a salir de línea)

18 ~

25 - - Tierra eléctrica

Observe que el puerto paralelo tiene 12 líneas de salida (8 líneas de datos, strobe, autofeed, init, y select input) y 5 de entrada (acknowledge, busy, falta de papel, select y error).

(8)

Hay tres direcciones de E/S asociadas con un puerto paralelo de la PC, éstas direcciones pertenecen al registro de datos, el registro de estado y el registro de control.

El registro de datos es un puerto de lectura-escritura de ocho bits. Leer el registro de datos (en la modalidad unidireccional) retorna el último valor escrito en el registro de datos.

Los registros de control y estado proveen la interface a las otras líneas de E/S. La distribución de las diferentes señales para cada uno de los tres registros de un puerto paralelo esta dada en las siguientes tablas:

Dirección Nombre Lectura/Escritura Bit

# Propiedades Bit 7 Dato 7 Bit 6 Dato 6 Bit 5 Dato 5 Bit 4 Dato 4 Bit 3 Dato 3 Bit 2 Dato 2 Bit 1 Dato 1 Base + 0 Puerto de datos Escritura Bit 0 Dato 0 Tabla 1: Registro de datos

Dirección Nombre Lectura/Escritura Bit

# Propiedades Bit 7 Busy Bit 6 Acknowledge Bit 5 Falta de papel Bit 4 Select In Base + 1 Puerto de estado Sólo Lectura Bit 3 Error

Bit 2 IRQ (Not) Bit 1 Reservado Bit 0 Reservado Tabla 2: Registro de estado

Dirección Nombre Lectura/Escritura Bit

# Propiedades Bit 7 No usado Bit 6 No usado Bit 5 Permite puerto bidireccional Bit 4 Permite IRQ a través de la línea acknowledge Bit 3 Selecciona impresora Bit 2 Inicializa impresora Bit 1 Nueva línea

automática Base + 2 Puerto de

control

Lectura/Escritura

Bit 0 Strobe Tabla 3: Registro de control

Una PC soporta hasta tres puertos paralelo separados, por tanto puede haber hasta tres juegos de registros en un sistema en un momento dado. Existen tres direcciones base para el puerto paralelo asociadas con tres posibles puertos paralelo: 0x3BCh, 0x378h y 0x278h, nos referimos a éstas como las direcciones base para el puerto LPT1, LPT2 y LPT3, respectivamente.

(9)

El registro de datos se localiza siempre en la dirección base de un puerto paralelo, el registro de estado aparece en la dirección base + 1, y el registro de control aparece en la dirección base + 2. Por ejemplo, para un puerto LPT2 localizado en 0x378h, ésta es la dirección del registro de datos, al registro de estado le corresponde la dirección 0x379h y su respectivo registro de control está en la dirección 0x37Ah.

Cuando la PC se enciende el BIOS ejecuta una rutina para determinar el número de puertos presentes en el sistema asignando la etiqueta LPT1 al primer puerto localizado, si existen más puertos entonces se asignarán consecutivamente las etiquetas LPT2 y LPT3.

Una vez vistos los aspectos basicos de la programación y como esta estructurado el puerto y como este funciona, ahora si en esta unidad se citara lo que realmente compete a este documento.

Primeramente, se dira que para poder visualizar el valor de los datos del puerto de datos, utilizaremos algunos dispositivos electronicos, llamados LED (diodo emisor de luz) apoyados por unos resistores que limitan la corriente y ayudan a que los LED no se quemen.

En lo que respecta a la planeacion de los datos que deseamos mostrar en el puerto, nos podemos, y es sugerencia, apoyar en tablas de estado de puerto (asi yo las llamo) que se veran en cada ejemplo.

Pues bien, ya una vez mencionados estos detalles, se describen a continuacion la estructura de los programas de entrada y salida de datos asi como ejemplos basicos de la programación del puerto (recordando que trabajo con valores binarios, las salidas o las entradas solo pueden tener 2 valores: 0 o 1)

MUESTRA DE INFORMACION EN EL PUERTO

La linea principal que permite mostrar datos en el puerto, es la linea que mas sera utilizada y varia según el tipo de compilador que se este utilizando.

Si estas utilizando un compilador de C/C++ version 3.0 de Borland o inferior la estructura es asi:

Librería requerida: dos.h

Linea a utilizar: outportb(dir_puerto, valor);

UNIDAD 3

PROGRAMACION DEL

PUERTO PARALELO

(10)

Si se trata de un compilador C/C++ 4.0 o superior de Borland o Microsoft:

Librería requerida: conio.h

Linea a utilizar: outp(dir_puerto, valor);

Donde: dir_puerto es la direccion de memoria base que ocupa el puerto por lo general es 0x378.

Y valor es el valor en numero decimal que se mostrara en el puerto en su equivalente visto en binario.

La tabla de trabajo del puerto es:

Pin 9 8 7 6 5 4 3 2

Valor 27 26 25 24 23 22 21 20

Dato D7 D6 D5 D4 D3 D2 D1 D0

CAPTURA DE DATOS EN EL REGISTRO DE ESTADO A traves del registro de estado es posible capturar datos, lo cual no indica que este funciona como entrada de datos al puerto, para poder capturar datos y poderlos utilizar como condicion para que la salida haga una tera especifica se requiere de la siguiente linea:

Si se trata de Borland C/C++ 3.0 o inferior: Librería: dos.h

Linea: inportb(dir_puerto+1);

Si es de Borland C/C++ 4.0 o superior o de Microsoft: Librería: conio.h

Linea: inp(dir_puerto+1);

La tabla de trabajo del registro de estado es:

Pin 11 10 12 13 15 NA NA NA

Dato /D7 D6 D5 D4 D3 D2 D1 D0

Se puede apreciar que los datos D0 a D2 no tienen un pin especifico de trabajo, por lo que asumen un valor binario de 1. Vemos tambien que el D7 contiene antecedido una diagonal indicando que es un valor negado, es decir que si la entrada es 1 el puerto lo lee como 0 y viceversa.

EJEMPLOS DE PROGRAMACION DEL PUERTO

Ejemplo 1: implementacion de una caminata o rotabit utilizando el puerto de datos.

#include<dos.h> void main() { int x; for(x=1; x<=128; x=x*2) { outportb(0x378,x); delay(1000); } for(x=128; x>=1; x=x/2) { outportb(0x378,x); delay(1000); } }

Ejemplo 2: Encender solo el led deseado utilizando los valores posicionales de 0 a 7 #include<dos.h> #include<stdio.h> #include<math.h> void main() { int x, y;

(11)

scanf(“%i”, &x); y=pow(2,x);

outportb(0x378,y); }

La interfaz electronica para comprobar los programas de los ejemplos anteriores es la siguiente:

Ejemplo 3: Se recibe un dato en el registro de estado a traves del pin 10, y deseamos que dicho pin haga que se genere un rotabit del pin 2 al 9 o llega un dato al pin 15 que genera un rotabit del pin 9 al 2.

Tabla 1.- Entrada en el pin 10

Pin 11 10 12 13 15 NA NA NA

Dato /D7 D6 D5 D4 D3 D2 D1 D0

Valor 0 1 0 0 0 1 1 1

Tabla 2.- Entrada en el pin 15

Pin 11 10 12 13 15 NA NA NA

Dato /D7 D6 D5 D4 D3 D2 D1 D0

Valor 0 0 0 0 1 1 1 1 Como se aprecia en las tablas tenemos los valores siguentes: Para el pin 10: el valor es 71.

Para el pin 15: el valor es 15.

#include<dos.h> void main() { int x, in; in=inportb(0x378+1); if (in==71) { for(x=1; x<=128; x=x*2) { outportb(0x378, x); delay(1000); } } if (in==15) { for(x=128; x>=1; x=x/2) { outportb(0x378, x); delay(1000); } } }

(12)

A MANERA DE CONCLUSION

Como se puede apreciar la programacion es bastante sencilla, pero requiere de tener conocimientos en programación en lenguaje C/C++ y algunos aspectos basicos de electronica para comprender sobre todo el circuito aquí expuesto, el resto dependera del interesado, pues como bien se sabe para programar solo bastan tres requisitos, conocer la estructura de un lenguaje de programación, ser buen investigador y tener imaginación para la solucion de problemas.

Como se pudo ver este documento trato en lo mayor posible de recopilar toda la información relacionada al tema y que permita a un estudiante de las areas de computación y electronica el poder programar el puerto con un minimo de dificultades.

Si desea conocer mas sobre el tema le recomiendo e siguiente link de Virgilio Negrete, al cual le agradezco que esta información este disponible a todos y del cual tome muchas referencias, ¡gracias Virgilio!:

Referencias

Documento similar