La transmisión de datos en serie es una de las más comunes para aquellas aplicaciones en las que
la velocidad no es demasiado importante, o no es posible conseguirla (por ejemplo, vía red telefónica). Para
simplificar el proceso de enviar los bits uno por uno han surgido circuitos integrados que realizan la función,
teniendo en cuenta todos los tiempos necesarios para lograr una correcta comunicación y aliviando a la CPU
de esta pesada tarea. El circuito que estudiaremos es el 8250 de National, fabricado también por Intel,
aunque las diferencias respecto al 16550 serán brevemente señaladas. Esta última UART es más reciente y
mucho más potente -aunque solo sea por unos pequeños detalles- y cada vez está más extendida, en particular
en las actuales placas base.
La línea que transmite los datos en serie está inicialmente en estado alto. Al comenzar la
transferencia, se envía un bit a 0 ó bit de inicio. Tras él irán los 8 bits de datos a transmitir (en ocasiones
son 7, 6 ó 5): estos bits están espaciados con un intervalo temporal fijo y preciso, ligado a la velocidad de
transmisión que se esté empleando. Tras ellos podría venir o no un bit de paridad generado automáticamente
por la UART. Al final, aparecerá un bit (a veces un bit y medio ó dos bits) a 1, que son los bits de parada
o bits de stop. Lo de medio bit significa que la señal correspondiente en el tiempo a un bit dura la mitad;
realmente, en comunicaciones se utiliza el término baudio para hacer referencia a las velocidades, y
normalmente un baudio equivale a un bit. La presencia de bits de inicio y parada permite sincronizar la
estación emisora con la receptora, haciendo que los relojes de ambas vayan a la par. A la hora de transmitir
los bytes de datos unos tras otros, existe flexibilidad en los tiempos, de ahí que este tipo de comunicaciones
se consideren asíncronas. La transmisión de los 8 bits de datos de un byte realmente es síncrona, pero las
comunicaciones en serie siempre han sido consideradas asíncronas.
Para una transmisión en serie básica bastan tres hilos. Sin embargo, el software que controla el
puerto serie a través de la interfaz RS-232-C podría requerir más señales de control para establecer la
comunicación, al igual que para controlar un modem telefónico pueden hacer falta más líneas (de control,
no telefónicas...). Bromas aparte, sobre comunicaciones en serie existe todo un mundo; acerca de este tema
se han escrito muchos libros completos. Lógicamente, aquí no vamos a dar ningún curso de comunicaciones
en serie. Sin embargo, los menos introducidos en la materia no deben temer: ¿qué mejor manera de aprender
sobre las comunicaciones en serie que examinar cómo funciona un chip que las soporta?. Desde luego,
también se podría partir desde el punto de vista contrario, pero como entendido en sistemas digitales, el
lector puede que tenga menos problemas con este interesante enfoque.
12.9.1. - DESCRIPCIÓN DEL INTEGRADO.
El ACE 8250 (Asynchronous Communication Element) integra en
un solo chip una UART (Universal Asynchronous Receiver/Transmitter)
y un BRG (Baud Rate Generator). Soporta velocidades de hasta 625000
baudios con relojes de hasta 10 MHz. El BRG incorporado divide la
frecuencia base para conseguir las velocidades estándar de la RS-232-C.
SIGNIFICADO DE LAS LÍNEAS DEL 8250
referencia MSR(4)-. Un cambio en el estado de -CTS desde la última lectura del MSR provoca que se active DCTS (bit MSR(0)). Cuando -CTS está activo (a 0) el modem indica que el dato en SOUT puede ser transmitido. -CTS no afecta al modo lazo (LOOP) del 8250. | |
El 8250 dispone de 11 registros (uno más el 16550) pero sólo 3 líneas de dirección para
seleccionarlos. Lo que permita distinguir unos de otros será, aparte de las líneas de direcciones, el sentido
del acceso (en lectura o escritura) y el valor de un bit de uno de los registros: el bit DLAB del registro LCR,
que es el bit 7 de dicho registro. La notación para hacer referencia a un bit de un registro se escribe REG(i);
en este ejemplo, el bit DLAB sería LCR(7). Realmente, DLAB se emplea sólo puntualmente para poder
acceder y programar los registros que almacenan el divisor de velocidad; el resto del tiempo, DLAB estará
a 0 para acceder a otros registros más importantes.
A2 | A1 | A0 | DLAB | MODO | NOMBRE | SIGNIFICADO |
0 | 0 | 0 | 0 | R | RBR | Receiver Buffer Register (Registro buffer de recepción) |
0 | 0 | 0 | 1 | R/W | DLL | Divisor Latch LSB (Divisor de velocidad, parte baja |
0 | 0 | 0 | 0 | W | THR | Transmitter Holding Register (Registro de retención de transmisión |
0 | 0 | 1 | 0 | R/W | IER | Interrupt Enable Register (Registro de habilitación de interrupciones) |
0 | 0 | 1 | 1 | R/W | DLM | Divisor latch MSB (Divisor de velocidad, parte alta) |
0 | 1 | 0 | X | R | IIR | Interrupt Identification Register (Registro de identificación de interrupciones) |
0 | 1 | 0 | X | W | FCR | FIFO Control Register (Registro de control FIFO) - SOLO 16550 - |
0 | 1 | 1 | X | R/W | LCR | Line Control Register (Registro de control de línea) ¡¡EL BIT 7 ES DLAB!! |
1 | 0 | 0 | X | R/W | MCR | Modem Control Register (Registro de control del modem) |
1 | 0 | 1 | X | R/W | LSR | Line Status Register (Registro de estado de la línea) |
1 | 1 | 0 | X | R/W | MSR | Modem Status Register (Registro de estado del modem) |
1 | 1 | 1 | X | R/W | SCR | Scratch Register (Registro residual) |
Los bits WLS seleccionan el tamaño del dato empleado. STB indica el número de bits de stop, que
pueden ser 1 (STB=0) ó 2 (STB=1), al trabajar con datos de 5 bits STB=1 implica 1.5 bits de stop. PEN
(Parity Enable) permite habilitar o no la generación de bit de paridad, EPS (Even Parity Select) selecciona
paridad par si está a 1 (o impar en caso contrario). Stick Parity permite forzar el bit de paridad a un estado
conocido según el valor de EPS. Cuando Break Control es puesto a 1, la salida SOUT se pone en estado
espacio (a 0), sólo afecta a SOUT y no a la lógica de transmisión. Esto permite a la CPU alertar a un
terminal del sistema sin transmitir caracteres erróneos o extraños si se siguen estas fases: 1) cargar un carácter
0 en respuesta a THRE, 2) activar Break Control en respuesta al próximo THRE, 3) esperar a que el
transmisor esté inactivo (TEMT=1) y bajar Break Control. Durante el Break, el transmisor puede usarse como
un preciso temporizador de carácter.
El bit DLAB (Divisor Latch Access Bit) puesto a 1 permite acceder a los Latches divisores DLL y
DLM del BRG en lectura y escritura. Para acceder al RBR, THR y al IER debe ser puesto a 0.
2) LSR (Line Status Register). Este suele ser el primer registro consultado tras una interrupción.
DR está activo cuando hay un carácter listo en el RBR y es puesto a 0 cuando se lee el RBR. Los
bits 1 al 4 de este registro (OE, PE, FE y BI) son puestos a 0 al consultarlos -cuando se lee el LSR- y al
activarse pueden generar una interrupción de prioridad 1 si ésta interrupción está habilitada. OE se activa para
indicar que el dato en el RBR no ha sido leído por la CPU y acaba de llegar otro que lo ha sobreescrito. PE
indica si hay un error de paridad. FE indica si el carácter recibido no tiene los bit de stop correctos. BI se
activa cuando la entrada de datos es mantenida en espacio (a 0) durante un tiempo superior al de transmisión
de un carácter (bit de inicio + bits de datos + bit de paridad + bit de parada).
THRE indica que el 8250 puede aceptar un nuevo carácter para la transmisión: este bit se activa
cuando el THR queda libre y se desactiva escribiendo un nuevo carácter en el THR. Se puede producir, si
está habilitada; la interrupción THRE (prioridad 3); INTRPT se borra leyendo el IIR. El 8250 emplea un
registro interno para ir desplazando los bit y mandarles en serie (el Transmitter Shift Register), dicho registro
se carga desde el THR. Cuando ambos registros (THR y el Transmitter Shift) están vacíos, TEMT se activa;
volverá a desactivarse cuando se deje otro dato en el THR hasta que el último bit salga por SOUT.
3) MCR (Modem Control Register). Controla el interface con el modem.
Las líneas de salida -DTR, -RTS, -OUT1 y -OUT2 están directamente controladas por estos bits;
como se activan a nivel bajo, son puestas a 0 escribiendo un 1 en estos bits y viceversa. Estas líneas sirven
para establecer diversos protocolos de comunicaciones.
El bit LOOP introduce el 8250 en un modo lazo (o bucle) de autodiagnóstico. Con LOOP activo,
SOUT pasa a estado de marca (a 1) y la entrada SIN es desconectada. Los registros de desplazamiento
empleados en la transmisión y la recepción son conectados entre sí. Las cuatro entradas de control del modem
(-CTS, -DSR, DC y -RI) son desconectadas y en su lugar son internamente conectadas las cuatro salidas de
control del modem (-DTR, -RTS, -OUT1 y -OUT2) cuyos pines son puestos en estado inactivo (alto). En
esta modalidad de operación (modo lazo o bucle), los datos transmitidos son inmediatamente recibidos, lo
que permite comprobar el correcto funcionamiento del integrado. Las interrupciones son completamente
operativas en este modo, pero la fuente de estas interrupciones son ahora los 4 bits bajos del MCR en lugar
de las cuatro entradas de control. Estas interrupciones están aún controladas por el IER.
4) MSR (Modem Status Register).
Además de la información de estado del modem, los 4 bits bajos (DDCD, TERI, DDSR, DCTS)
indican si la línea correspondiente, en los 4 bits superiores, ha cambiado de estado desde la última lectura
del MSR; en el caso de TERI sólo indica transiciones bajo-<alto en -RI (y no las de sentido contrario). La
línea CTS del modem indica si está listo para recibir datos del 8250 a través de SOUT (en el modo lazo este
bit equivale al bit RTS del MCR). La línea DSR del modem indica que está listo para dar datos al 8250 (en
el modo lazo -o LOOP- equivale al bit DTR del MCR). RI y DCD indican el estado de ambas líneas (en el
modo lazo se corresponden con OUT1 y OUT2 respectivamente). Al leer el MSR, se borran los 4 bits
inferiores (que en una lectura posterior estarían a 0) pero no los bits de estado (los 4 más significativos).
Los bits de estado (DCD, RI, DSR y CTS) reflejan siempre la situación de los pines físicos
respectivos (estado del modem). Si DDCD, TERI, DDSR ó DCTS están a 1 y se produce un cambio de
estado durante la lectura, dicho cambio no será reflejado en el MSR; pero si están a 0 el cambio será
reflejado después de la lectura. Tanto en el LSR como en el MSR, la asignación de bits de estado está
inhibida durante la lectura del registro: si se produce un cambio de estado durante la lectura, el bit
correspondiente será activado después de la misma; pero si el bit ya estaba activado y la misma condición
se produce, el bit será borrado tras la lectura en lugar de volver a ser activado.
5) y 6) BRSR (Baud Rate Select Register). Son los registros DLL (parte baja) y DLM (parte alta).
Estos dos registros de 8 bits constituyen un valor de 16 bits que será el divisor que se aplicará a la
frecuencia base para seleccionar la velocidad a emplear. Dicha frecuencia base (por ejemplo, 1.8432 MHz)
será dividida por 16 veces el valor almacenado aquí. Por ejemplo, para obtener 2400 baudios:
1843200 --------- = 48 -> DLL=48, DLM=0 16 * 2400
El circuito receptor del 8250 es programable para 5, 6, 7 u 8 bits de datos. En el caso de emplear
menos de 8, los bits superiores de este registro quedan a 0. Los datos entran en serie por SIN (comenzando
por el bit D0) en un registro de desplazamiento gobernado por el reloj de RCLK, sincronizado con el bit de
inicio. Cuando un carácter completa el registro de desplazamiento de recepción, sus bits son volcados al RBR
y el bit DR del LSR es activado para indicar a la CPU que puede leer el RBR. El diseño del 8250 permite
la recepción continua de datos sin pérdidas: el RBR almacena siempre el último carácter recibido dando
tiempo suficiente a la CPU para leerlo mientras simultáneamente está cargando el registro de desplazamiento
con el siguiente; si la CPU tarda demasiado un nuevo dato podría aparecer en el RBR antes de haber leído
el anterior (condición de overrun, bit OE del LSR).
8) THR (Transmitter Holding Register).
El registro de retención de transmisión almacena el siguiente carácter que va a ser transmitido en serie
mientras el registro de desplazamiento de transmisión está enviando el carácter actual. Cuando el registro de
desplazamiento se vacíe, será cargado desde el THR para transmitir el nuevo carácter. Al quedar vacío THR,
el bit THRE del LSR se activa. Cuando estén vacíos tanto el THR como el registro de desplazamiento de
transmisión, el bit TEMT del LSR se activa.
9) SCR (Scratchpad Register).
Este registro no es empleado por el 8250, y de hecho no existía en las primeras versiones del
integrado. Puede ser empleado por el programador como una celdilla de memoria.
10) IIR (Interrupt Identification Register).
Existen 4 niveles de prioridad en las interrupciones generables por el 8250, por este orden:
1) Estado de la línea de recepción.
2) Dato recibido disponible.
3) Registro de retención de transmisión vacío.
4) Estado del modem.
La información que indica que hay una interrupción pendiente y el tipo de la misma es almacenada
en el IIR. El IIR indica la interrupción de mayor prioridad pendiente. No serán reconocidas otras
interrupciones hasta que la CPU envíe la señal de reconocimiento apropiada. En el registro IIR, el bit 0 indica
si hay una interrupción pendiente (bit 0=0) o si no la hay (bit 0=1), esto permite tratar las interrupciones en
modo polled consultando este bit. Los bits 1 y 2 indican el tipo de interrupción. Los restantes están a 0 en
el 8250, pero el 16550 utiliza alguno más.
+-----------------------------------+-----------------------------------------------------------------+ | IDENTIFICACIÓN DE LA INTERRUPCIÓN | ACTIVACIÓN / RECONOCIMIENTO (RESET) DE LA INTERRUPCIÓN | +-------+-------+-------+-----------+------------------+---------------+------------------------------+ | Bit 2 | Bit 1 | Bit 0 | Prioridad | Flag | Fuente | Reconocimiento | +-------+-------+-------+-----------+------------------+---------------+------------------------------+ | X | X | 1 | | Ninguno | Ninguna | | | | | | | | | | +-------+-------+-------+-----------+------------------+---------------+------------------------------+ | 1 | 1 | 0 | Primera | Línea de estado | OE, PE, | Leer LSR | | | | | | del receptor | FE ó BI | | +-------+-------+-------+-----------+------------------+---------------+------------------------------+ | 1 | 0 | 0 | Segunda | Recibido dato | Recibido dato | Leer RBR | | | | | | disponible | disponible | | +-------+-------+-------+-----------+------------------+---------------+------------------------------+ | 0 | 1 | 0 | Tercera | THRE | THRE | Leer IIR si es la fuente de | | | | | | | | interrupción, o escribir THR | +-------+-------+-------+-----------+------------------+---------------+------------------------------+ | 0 | 0 | 0 | Cuarta | Estado del modem | -CTS, -DSR | Leer MSR | | | | | | | -RI, -DCD | | +-------+-------+-------+-----------+------------------+---------------+------------------------------+
Este registro de escritura se utiliza para seleccionar qué interrupciones activan INTRPT y, por
consiguiente, van a ser solicitadas a la CPU. Deshabilitar el sistema de interrupciones inhibe el IIR y
desactiva la salida INTRPT.
El 16550 genera también una interrupción de TIMEOUT (prioridad 1) si hay datos en la cola FIFO
y no son leídos dentro del tiempo que dura la recepción de 4 bytes o si no se reciben datos durante el tiempo
que tomaría recibir 4 bytes.
12) FCR (FIFO Control Register). Sólo disponible en el 16550, no en el 8250.
El bit 0 debe estar a 1 para escribir los bits 1 ó 2. Cuando el bit 1 ó el 2 son activados, la cola
afectada es borrada y el bit es devuelto a 0. Los registros de desplazamiento de la transmisión y la recepción,
en cada caso, no resultan afectados.
LA TRANSMISIÓN Y LA RECEPCIÓN EN EL 8250
La sección de transmisión del 8250 consiste en el Registro de Retención de transmisión (THR), el
Registro de Desplazamiento de la Transmisión (TSR) y en la lógica de control asociada. Dos bits en el LSR
indican si está vacío el THR (bit THRE) o el TSR (bit TEMT). El carácter de 5-8 bits a ser transmitido es
escrito en el THR; la CPU debería realizar esta operación sólo si THRE está activo: este bit es activado
cuando el carácter es copiado del THR al TSR durante la transmisión del bit de inicio.
Cuando el transmisor está inactivo, tanto THRE como TEMT están activos. El primer carácter escrito
provoca que THRE baje; tras completarse la transferencia vuelve a subir aunque TEMT permanecerá bajo
mientras dure la transferencia en serie del carácter a través de TSR. Si un segundo carácter es escrito en
THR, THRE vuelve a bajar y permanecerá bajo hasta que el TSR termine la transmisión, porque no es
posible volcar el contenido de THR en TSR hasta que este último no acabe con el carácter que estaba
transmitiendo. Cuando el último carácter ha sido transmitido fuera del TSR, TEMT vuelve a activarse y
THRE también lo hará tras un cierto tiempo (el que tarda en escribirse THR en TSR).
En la recepción, los datos en serie asíncronos entran por la patilla SIN. El estado inactivo de la línea
se considera el '1' lógico. Un circuito de detección de bit de inicio está continuamente buscando una
transición alto-<bajo que interrumpa el estado inactivo. Cuando la detecta, se resetea un contador interno
y cuenta 7½ pulsos de reloj (tener en cuenta que la frecuencia base es dividida por 16), posicionándose en
el centro del bit de inicio. El bit de inicio se considera válido si SIN continúa aún bajo en ese momento. La
validación del bit de inicio evita que un ruido espúreo en la línea sea confundido con un nuevo carácter.
El LCR tiene toda la información necesaria para la recepción: tamaño del carácter (5-8 bits), número
de bits de stop, si hay paridad o no... la información de estado que se genere será depositada en el LSR.
Cuando un carácter es transmitido desde el Registro de Desplazamiento de la Recepción (RSR) al Registro
Buffer de Recepción (RBR), el bit DR del LSR se activa. La CPU lee entonces el RBR, lo que hace bajar
de nuevo DR. Si el carácter no es leído antes de que el siguiente carácter que se está formando pase del RSR
al RBR, el bit OE (overrun) del LSR se activa. También se puede activar PE en el LSR si hay un error de
paridad. Finalmente, la circuitería que chequea la validez del bit de stop podría activar el bit FE del LSR en
caso de error.
El centro del bit de inicio se define como 7½ pulsos de reloj; si los datos que entran por SIN
constituyen una onda cuadrada simétrica, el centro de las celdas que contienen los bits se desviará a lo sumo
un ±3.125% del centro real, lo que deja un margen de error del 46.875%; el bit de inicio puede comenzar,
como mucho, 1 ciclo de reloj (de los 16) antes de ser detectado.
EL B.R.G. (BAUD RATE GENERATOR)
El BRG genera las señales de reloj para el funcionamiento de la UART, permitiendo los ratios de
transferencia del estándar ANSI/CCITT. Se puede conectar un cristal a XTAL1 y XTAL2 ó una señal de reloj
a XTAL1. La salida -BAUDOUT puede excitar la línea XTAL1 de otro 8250.
La velocidad es determinada por los registros DLL y DLM almacenando un valor divisor de la
frecuencia del reloj conectado al 8250. El resultado debe ser 16 veces mayor que la frecuencia en baudios
deseada, ya que el 8250 utiliza 16 pulsos de reloj para cada bit. El siguiente cuadro resume los valores que
hay que asignar al divisor para lograr las frecuencias más usuales con los cristales más comunes.
RESET DEL 8250
Tras dar corriente al 8250 hay que tenerlo unos 500 ns con MR alto para resetearlo. Un nivel alto
en MR provoca:
Tras el reset (MR llevado a estado bajo) el 8250 permanece en estado inactivo hasta ser programado.
Un reset hardware activa THRE y TEMT: cuando las interrupciones sean habilitadas, THRE provocará una.
Por software se puede forzar al 8250 a retornar a un estado totalmente conocido. Dicho reset consiste
en escribir el LCR, DLL y DLM, así como MCR. LSR y RBR deberían ser leídos antes de habilitar las
interrupciones para borrar cualquier información residual (datos o estado) de las operaciones anteriores.
PROGRAMACIÓN DEL 8250
El 8250 se programa a través de los registros de control LCR, IER, DLL, DLM y MCR. Aunque los
registros de control pueden ser escritos en cualquier orden, IER debe ser escrito al final porque controla la
habilitación de las interrupciones. Una vez que el 8250 ha sido programado, los registros pueden ser
actualizados en cualquier momento en que el 8250 no se encuentre enviando o recibiendo datos.
12.9.2. - EL 8250 EN EL ORDENADOR.
Los ordenadores compatibles pueden tener conectados, de manera normal, hasta 4 puertos serie,
nombrados COM1-COM4. En el área de datos de la BIOS (segmento 40h) y justo al principio de la misma,
hay 4 palabras con la dirección de memoria base de los puertos serie. A esta dirección de memoria base habrá
que sumar el desplazamiento relativo del número de registro a ser accedido.
El principal problema reside en que sólo están previstas 2 interrupciones para los puertos serie. Ello
implica que generalmente sólo 2 de los puertos podrán emplear interrupciones a un tiempo, debido a la
arquitectura del bus ISA. Generalmente COM1 y COM3 compartirán la IRQ4 (INT 0Ch) y COM2/COM4
la IRQ3 (INT 0Bh). Estas asignaciones pueden ser cambiadas por el usuario actuando sobre los switches de
configuración de las tarjetas (que en ocasiones permiten incluso elegir la IRQ5). Por tanto, no está de más
tener cuidado en los programas y permitir un cierto grado de configuración en estas cuestiones.
OFFSET | DLAB | MODO | NOMBRE | SIGNIFICADO |
0 | 0 | R | RBR | Receiver Buffer Register (Registro buffer de recepción) |
0 | 1 | R/W | DLL | Divisor Latch LSB (Divisor de velocidad, parte baja |
0 | 0 | W | THR | Transmitter Holding Register (Registro de retención de transmisión) |
1 | 0 | R/W | IER | Interrupt Enable Register (Registro de habilitación de interrupciones) |
1 | 1 | R/W | DLM | Divisor latch MSB (Divisor de velocidad, parte alta) |
2 | X | R | IIR | Interrupt Identification Register (Registro de identificación de interrupciones) |
2 | X | W | FCR | FIFO Control Register (Registro de control FIFO) - SOLO 16550 - |
3 | X | R/W | LCR | Line Control Register (Registro de control de línea) ¡¡EL BIT 7 ES DLAB!! |
4 | X | R/W | MCR | Modem Control Register (Registro de control del modem) |
5 | X | R/W | LSR | Line Status Register (Registro de estado de la línea) |
6 | X | R/W | MSR | Modem Status Register (Registro de estado del modem) |
7 | X | R/W | SCR | Scratch Register (Registro residual) |
El cuadro superior muestra los desplazamientos (offsets) que hay que sumar a la dirección E/S base
del puerto serie para acceder a sus registros. COM1 suele estar en 3F8h, COM2 en 2F8h, COM3 en 3E8h
y COM4 en 2E8h. Sin embargo, es mejor acceder a las variables de la BIOS para obtener la dirección.
La INT 14h de la BIOS se encarga de controlar el puerto serie. El trabajo del DOS a través de los
dispositivos COM1: (conocido también como AUX:) al COM4: se realiza también apoyándose en esta
interrupción. El comando MODE del sistema permite inicializar el puerto serie a alto nivel. Sin embargo,
tanto el DOS como la BIOS no permiten exceder los 9600 baudios, velocidad excesivamente baja para la
transmisión de datos entre dos ordenadores cercanos o el trabajo con un modem.
El cristal que gobierna el 8250 oscila a
1.8432 MHz. Nosotros debemos considerar esta frecuencia dividida por 16 de
cara a calcular el valor para el divisor. Por tanto, la velocidad máxima que
puede alcanzar el puerto serie de los PC es de 1843200/16 = 115200 baudios.
Con datos de 8 bit se pueden empaquetar los bytes en 10 baudios (1
bit de inicio, 8 de datos, 1 de stop), lo que permite alcanzar 11520
bytes/seg (11.25 Kb/seg). Para distancias de pocos metros (no decenas ni
centenas) no habrá problemas, incluso para distancias algo mayores si los
cables se diseñan con cuidado. La programación del puerto serie en el PC a
nivel de hardware es necesaria a menudo por dos razones de mucho peso: poder
utilizar interrupciones y emplear velocidades superiores a 9600 baudios. Por
supuesto, en estas transferencias los paquetes deberían llevar algún control
de errores, aunque no precisamente basado en la paridad.
El siguiente programa de ejemplo coloca el 8250 en modo lazo (LOOP) y seguidamente comienza
a transmitir datos de 8 bits (desde 0 hasta 255) comprobando que le llegan los mismos datos que envía y sin
que se produzcan errores. Se permite elegir el puerto deseado así como la velocidad de transmisión.
/********************************************************************* * * * 8250T.C 1.0 - UTILIDAD DE AUTODIAGNOSTICO DEL 8250 EN TURBO C * * * * (c) 1993 Ciriaco García de Celis. * * * *********************************************************************/ #include <dos.h> #include <conio.h> #define LCR (base+3) /* registro de control de línea */ #define IER (base+1) /* registro de activación de interrupciones */ #define DLL (base+0) /* parte baja del divisor */ #define DLM (base+1) /* parte alta del divisor */ #define MCR (base+4) /* registro de control del modem */ #define LSR (base+5) /* registro de estado de línea */ #define RBR (base+0) /* registro buffer de recepción */ #define THR (base+0) /* registro de retención de transmisión */ #define DR 1 /* bit dato disponible del LSR */ #define OE 2 /* bit de error de overrun del LSR */ #define PE 4 /* bit de error de paridad del LSR */ #define FE 8 /* bit de error en bits de stop del LSR */ #define BI 0x10 /* bit de error de break en el LSR */ #define THRE 0x20 /* bit de THR vacío */ void error() { printf ("\r ¡¡Fallo del puerto serie!!\n"); exit (2); } void main() { unsigned com, base, divisor, dato, entrada, lsr; printf("\n8250 Test v1.0 - (c) 1993 Ciriaco García de Celis.\n"); printf("- Elige COM (1, 2, ...): "); scanf ("%d", &com); base=peek(0x40, (com-1)*2); if (base==0) { printf("\n ¡El COM elegido no existe para la BIOS!.\n"); exit (1); } printf("- Elige divisor (1-65535): "); scanf ("%d", &divisor); if (!divisor) divisor=1; printf("\nComprobando 8250 en %03Xh a %lu baudios.\nEspera...", base, 1843200L/divisor/16); outportb (LCR, 0x83); /* DLAB=1, 8 bits, 1 stop, sin paridad */ outportb (IER, 0); outportb (DLL, divisor % 256); outportb (DLM, divisor >> 8); outportb (MCR, 8+16); /* modo LOOP */ outportb (LCR, 0x03); /* DLAB=0, 8 bits, 1 stop, sin paridad */ for (dato=0; (dato<0x100) && !kbhit(); dato++) { do { /* esperar por THR vacío */ lsr=inportb(LSR); if (lsr & (OE|PE|FE|BI)) error(); } while (!(lsr & THRE)); outportb (THR, dato); /* enviar carácter */ do { /* esperar por RBR lleno */ lsr=inportb(LSR); if (lsr & (OE|PE|FE|BI)) error(); } while (!(lsr & DR)); entrada=inportb (RBR); /* recibir carácter */ if (dato!=entrada) error(); printf ("\rEnviado y recibido byte %d",dato); } if (!kbhit()) printf("\rAutodiagnóstico del 8250 en COM%d superado.\n", com); else { getch(); printf("\rTecla pulsada - prueba abortada.\n");} }