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");}
}