Descripción
El puerto serie RS-232C es el estándar en el que
se basa el puerto serie. El constituye la tercera revisión
de la antigua norma RS-232, propuesta por la EIA
(Asociación de Industrias Electrónicas),
realizándose posteriormente un versión
internacional por el CCITT, conocida como V.24.
Las diferencias entre ambas son mínimas, por lo
que a veces se habla indistintamente de V.24 y de RS-232C
(incluso sin el sufijo "C"), refiriéndose siempre al mismo
estándar.
El RS-232C define un conector tipo DB-25 de 25 pines,
aunque es normal encontrar la versión de 9 pines DB-9,
más barato e incluso más extendido para cierto tipo
de periféricos (como el ratón serie del PC). En
cualquier caso, los PCs no suelen emplear mas de 9 pines en el
conector DB-25. Las señales con las que trabaja este
puerto serie son digitales, de +15V (0 lógico) y -15V (1
lógico), para la entrada y salida de datos, y a la inversa
en las señales de control. El estado de reposo en la
entrada y salida de datos es -15V. Dependiendo de la velocidad de
transmisión empleada, es posible tener cables de hasta 15
metros.
Cada pin puede ser de entrada o de salida, teniendo una
función especifica cada uno de ellos. Las más
importantes son:
Pin | Función | |||
TXD | Transmitir Datos | |||
RXD | Recibir Datos | |||
DTR | Terminal de Datos Listo | |||
DSR | Equipo de Datos Listo | |||
RTS | Solicitud de Envío | |||
CTS | Libre para Envío | |||
DCD | Detección de Portadora |
Las señales TXD, DTR y RTS son de salida,
mientras que RXD, DSR, CTS y DCD son de entrada. La masa de
referencia para todas las señales es SG (Tierra de
Señal). Finalmente, existen otras señales como RI
(Indicador de Llamada), y otras poco comunes que no se suelen
utilizar.
Número de DB-25 | Número de DB-9 | Señal | Descripción | E/S | |||||||||
1 | 1 | – | Masa chasis | – | |||||||||
2 | 3 | TxD | Transmit Data | S | |||||||||
3 | 2 | RxD | Receive Data | E | |||||||||
4 | 7 | RTS | Request To Send | E | |||||||||
5 | 8 | CTS | Clear To Send | E | |||||||||
6 | 6 | DSR | Data Set Ready | E | |||||||||
7 | 5 | SG | Signal Ground | – | |||||||||
8 | 1 | CD/DCD | (Data)Carrier Detect | E | |||||||||
15 | – | TxC | Transmit Clock | S | |||||||||
17 | – | RxC | Receive Clock | E | |||||||||
20 | 4 | DTR | Data Terminal Ready | S | |||||||||
22 | 9 | RI | Ring Indicator | E | |||||||||
24 | – | RTxC | Transmit/Receive Clock | S |
Los conectores definidos en el estándar
son:
Cable DB25. Macho(superior)
Hembra(inferior)
Cable DB9. Macho(superior)
Hembra(inferior)
El ordenador controla el puerto serie mediante un
circuito integrado específico, llamado UART
(Transmisor-Receptor-Asíncrono Universal). Normalmente se
utilizan los siguientes modelos de este chip:
– 8250 (bastante antiguo, con fallos, sólo llega
a 9600 baudios)
– 16450 (versión corregida del 8250, llega hasta
115.200 baudios)
– 16550A (con buffers de E/S)
A partir de la gama Pentium, las UART de las placas base
son todas de alta velocidad, es decir UART 16550A. De hecho, la
mayoría de los módems conectables a puerto serie
necesitan dicho tipo de UART. Los portátiles suelen llevar
otros chips: 82510(con buffer especial, emula al 16450) o el 8251
(no es compatible). A veces los portátiles apuran mucho el
estándar, rebajando los niveles de tensión, lo cual
limita el alcance y puede hacer que el JDM Programmer del
Capítulo 2 no funcione correctamente.
Para controlar al puerto serie, la CPU emplea
direcciones de puertos de E/S y líneas de
interrupción (IRQ). En el AT-286 se eligieron las
direcciones 3F8h (o 0x3f8) e IRQ 4 para el COM1, y 2F8h e IRQ 3
para el COM2. El estándar del PC llega hasta aquí,
por lo que al añadir posteriormente otros puertos serie,
se eligieron las direcciones 3E8 y 2E8 para COM3-COM4, pero las
IRQ no están especificadas (COM3 suele tener IRQ4 y COM4
IRQ3) . Cada usuario debe elegirlas de acuerdo a las que tenga
libres o el uso que vaya a hacer de los puertos serie (por
ejemplo, no importa compartir una misma IRQ en dos puertos
siempre que no se usen conjuntamente).
Mediante los puertos de E/S se pueden intercambiar
datos, mientras que las IRQ producen una interrupción para
indicar a la CPU que ha ocurrido un evento (por ejemplo, que ha
llegado un dato, o que ha cambiado el estado de algunas
señales de entrada). La CPU debe responder a estas
interrupciones lo mas rápido posible, para que dé
tiempo a recoger el dato antes de que el siguiente lo
sobreescriba. Sin embargo, las UART 16550A incluyen unos buffers
de tipo FIFO, dos de 16 bytes (para recepción y
transmisión), donde se pueden guardar varios datos antes
de que la CPU los recoja. Esto también disminuye el
número de interrupciones por segundo generadas por el
puerto serie.
El RS-232 puede transmitir los datos en grupos de 5, 6,
7 u 8 bits, a unas velocidades determinadas (2400 bits por
segundo, 4800 bps, 9600 bps … ). Después de la
transmisión de los datos, le sigue un bit opcional de
paridad y después 1, 1.5 o 2 bits de Stop. Normalmente, el
protocolo utilizado ser 8N1 (que significa, 8 bits de datos, sin
paridad y con 1 bit de Stop).Una vez que ha comenzado la
transmisión de un dato, los bits tienen que llegar uno
detrás de otro a una velocidad constante y en determinados
instantes de tiempo. Por eso se dice que el RS-232 es
asíncrono por carácter y síncrono por bit.
DTR indica que el ordenador está encendido, DSR que el
aparato conectado a dicho puerto está encendido, RTS que
el ordenador puede recibir datos (porque no está ocupado),
CTS que el aparato conectado puede recibir datos, y DCD detecta
que existe una comunicación.
Tanto el aparato a conectar como el ordenador (o el
programa terminal) tienen que usar el mismo protocolo serie para
comunicarse entre si. Puesto que el estándar RS-232 no
permite indicar en que modo se esta trabajando, es el usuario
quien tiene que decidirlo y configurar ambas partes. Como ya se
ha visto, los parámetros que hay que configurar son:
protocolo serie (8N1), velocidad del puerto serie, y protocolo de
control de flujo. Este último puede ser por hardware
(RTS/CTS) o bien por software (XON/XOFF, el cual no es muy
recomendable ya que no se pueden realizar transferencias
binarias).
El handshake hardware más sencillo es el RTS/CTS.
Se usa cuando un periférico es más lento y tiene
menos capacidad de memoria que un PC. Una vez que el ordenador ha
pedido transmitir datos activando RTS, el dispositivo más
lento puede comenzar y parar el flujo de datos activando y
desactivando CTS.
Configuraciones típicas. Cables.
El estándar RS-232C define dos tipos de
equipos:
DTE. Data Terminal Equipment. El ordenador o
terminal.DCE. Data Comunication Equipment. Un módem o
el sistema de comunicaciones diseñado en este
proyecto.
Los cables para conectar dos equipos son:
DTE con DTE sin control de flujo hardware (p.ej. 2
ordenadores entre sí).
DTE<>DTE control de flujo:
NO
DTE con DTE con control de flujo
hardware.
DTE<>DTE control de flujo:
SI
DTE con DCE sin control de flujo
hardware.
DTE<>DCE control de flujo:
NO
DTE con DCE con control de flujo
hardware.
DTE<>DCE control de flujo:
SI
Nota: No es necesario conectar DCD, DSR y DTR
para control de flujo RTS/CTS.
El cable que hay que usar para el proyecto es este
último, aunque no es necesario conectar DCD, DSR y DTR. Si
se va a comprar, el cable módem estándar funciona
perfectamente. Si se va a fabricar entonces conviene rodear los
cables con malla metálica (soldar con el pin
1).
Software Windows.
Para programar el puerto serie en DOS se recomienda
consultar el documento incluido en el CD llamado: Interfacing the
PC. Explica como configurar todos y cada uno de los registros,
tanto de la UART como del controlador de interrupciones. Adjunta
un poco de código fuente de ejemplo en C.
En Windows cada lenguaje y compilador tiene sus propias
librerías de interfaz con el puerto serie, aunque las
llamadas inport() y outport() suelen ser comunmente
soportadas.
Para este proyecto se ha empleado para numerosas tareas
el programa Hyperterminal, que viene en el CD de
instalación de todos los Windows 9x.
El Hyperterminal permite:
Configurar el puerto serie o módem. Se puede
elegir velocidad, paridad, control de flujo (hardware,
software, ninguno), bits de stop y tamaño de las FIFOs
de entrada-salida. Permite configurar el juego de caracteres
ASCII.Emular un terminal: ANSI, VT100 … .
Transferir archivos de texto y transferir archivos
con protocolos : Kermit, XMODEM, ZMODEM … .
El HyperTerminal resultó de gran utilidad durante
las pruebas, y se usa en algunas de las aplicaciones descritas en
el Capítulo 7. La configuración del puerto serie
para el sistema desarrollado es la que se muestra a
continuación:
Configuración
Hyperterminal
El Hyperterminal tiene una peculiaridad en cuanto al
control de flujo hardware RTS/CTS. Desde el momento en que se
arranca el programa, Hyperterminal activa la señal RTS
indicando que está listo para recibir, dejando activada la
señal hasta la desconexión.
El equivalente en Linux del Hyperterminal es el
minicom, clónico a su vez del
telix.
Software Linux.
- Programar en Linux.
En Linux se accede a todos los dispositivos como si
fuesen archivos. Así, para acceder al puerto serie
usaremos read() y write(), solo que el descriptor
de archivo (file descriptor) apuntará al puerto
serie:
fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY |
O_NONBLOCK);
En Linux el puerto COM1 es el archivo dev/ttyS0, el COM2
es dev/ttyS1 .
Para leer usaremos: read(fd,buffer,NUM) siendo
buffer el puntero al array que recibirá los datos y NUM el
número de datos a leer.
Para escribir : write(fd,buffer,NUM) siendo
buffer el puntero al array que contiene los datos a enviar y NUM
el número de datos a escribir.
Se puede configurar Linux de forma que cada vez que se
reciba un carácter se produzca una señal (una
interrupción software).
Para ver en detalle como se usa el puerto serie y como
se instalan las señales consultar en el CD el documento:
Serial_Programming_HOWTO, en la sección de
transmisión asíncrona , además de las
páginas de MAN de sigaction, fcntl, tcgetattr,
tcsetattr, read y write.
Es importante que, si se desea usar control de flujo
hardware se configure el puerto (usando tcsetattr() ) con
los flags CLOCAL (ignorar líneas módem), CREAD
(activa recepción) y CRTSCTS (control de flujo
hardware).
Una utilidad que no viene descrita en la
documentación estándar nos permite modificar las
líneas del puerto serie de forma directa:
int datos;
ioctl(fd,TIOCMGET,datos);
*datos ^=TIOCM_RTS; /* Activamos RTS */
ioctl(fd,TIOCMSET,datos);
Si en vez de TIOCM_RTS ponemos TIOCM_DTR se
activará la señal Data Terminal Ready, y así
con las demás señales.
- Terminal vía puerto serie.
Una de las aplicaciones de este proyecto es la de
controlar un sistema Unix de forma remota pero como si se
estuviese conectado directamente por el puerto serie. Para ello
hay que configurar Linux (información extraída del
documento Terminales-COMO.pdf incluido en el CD).
Entrando como superusuario, modificar el
/etc/inittab de la siguiente manera:
Buscar la sección #Serial lines y añadir
una línea como la siguiente:
s2:45:respawn:/sbin/agetty -L 38400
ttyS1
En la que habrá que cambiar algunas cosas
dependiendo del puerto serie del PC-Linux en donde esté el
terminal conectado:
Si el terminal está en el COM1:
s1:45:respawn:/sbin/agetty -L 2400
ttyS0
Si el terminal está en el COM2:
s2:45:respawn:/sbin/agetty -L 2400
ttyS1
Una vez insertada esa línea en /etc/inittab, hay
que hacer que el proceso init relea el fichero inittab, y para
ello ejecutar :
init q
También se puede activar el protocolo de hardware
RTS/CTS. Para activar el protocolo por hardware
CTS/RTS hay que pasar el parámetro -h a
agetty:
s2:45:respawn:/sbin/agetty -hL 2400
ttyS0
- Conexión PPP.
Otra de las aplicaciones del proyecto es establecer una
conexión Punto a Punto remota pero como si fuese a
través de un cable serie con control de flujo. Para ello
consultar el documento PPP-COMO.pdf incluido en el CD.
La USART del 16F87X.
Descripción.
La USART (Universal Synchronous Asynchronous Receiver
Transmitter) es un módulo de entrada /salida. Se puede
configurar para que opere en modo:
Asíncrono. Full-Duplex. Para comunicar el
micro con ordenadores y terminales.Síncrono. Maestro. Half-Duplex. Para
comunicar con periféricos serie (EEPROMs serie,
conversores A/D…).Síncrono. Esclavo. Half-Duplex.
La descripción detallada de la USART se encuentra
en el documento 16F87X.pdf del CD. En esta sección se
explicará brevemente la configuración
asíncrona de la USART.
En modo asíncrono la USART usa el modo
estándar NRZ (non return to zero), con un bit de start, 8
o 9 bits de datos y un bit de parada. La USART no tiene
implementada la paridad, pero puede generarse y comprobarse por
software, usando el noveno bit para ello.
Esquema de como generar la paridad por
software.
La USART consta de cuatro partes:
– Generador de Baud Rate. A partir de la frecuencia del
reloj deriva las frecuencias estándar de
transmisión serie.
– Circuito de Muestreo.
– Transmisor Asíncrono.
– Receptor Asíncrono.
Configuración.
Generador de Baud Rate: Para generar un baud rate de
2400 bps con un reloj de 4 MHz hay que poner el valor decimal 25
en SPBRG, con el flag BRGH=0. Se comete un error de sólo
el 0.17 %, que no dará problema alguno. Para baud rates
más grandes se llegan a cometer errores de hasta el 10
%.
Para configurar la transmisión
asíncrona:
1. Inicializar SPBRG con el baud rate
deseado.2. Habilitar el puerto serie asíncrono
poniendo a 0 el bit SYNC y a 1 el bit SPEN.3. Si se desean interrupciones poner el bit
TXIE a 1.4. Poner a 1 TX9 para transmitir 9
bits.5. Permitir la transmisión poniendo TXEN
a 1.6. Cargar el bit 9 (si lo hay) en
TX9D.7. Cargar datos en el registro TXREG (comienza
la transmisión).
Para enviar un byte tras otro:
1. Poner byte en TXREG.
2. Esperar hasta que TXIF esté a 1
(polling o interrupción).3. Ir a 1.
Para configurar la recepción
asíncrona:
1. Inicializar SPBRG con el baud rate
deseado.2. Habilitar el puerto serie asíncrono
poniendo a 0 el bit SYNC y a 1 el bit SPEN.3. Si se desean interrupciones poner el bit
RCIE a 1.4. Poner a 1 RX9 para recibir 9
bits.5. Permitir la recepción poniendo CREN a
1.6. El flag RCIF se pondrá a 1 cuando se
haya completado la recepción, generando una
interrupción si así se ha
configurado.7. Leer el bit 9 (si lo hay) en RCSTA y
determinar si hubo algún error en la
transmisión (OERR->Overrun;
FERR->Framing).8. Leer los datos en el registro RXREG (es una
FIFO de 2 bytes).9. Si ocurrió un error poner a 0 el bit
CREN.
Por último, si se ha elegido usar interrupciones
(de recepción o transmisión), habilitar el bit GIE
(Global Interrupt Enable).
Emulando la USART con el PIC16F84.
Como el PIC16F84 no tiene USART, hay que
emularla.
Para recibir datos hay que usar una pata que pueda
generar interrupciones (RB0 por ejemplo). Cuando se detecte un
flanco de bajada 1->0 entonces empieza la recepción de
un byte (el estado por defecto es 1 y el bit de start es 0). Se
muestrea entonces a intervalos regulares de forma que coincida
más o menos en el centro de cada bit. Si el puerto
está a uno se pone un uno en el registro usado para
recibir (inicializado a 0x00) y los rotaremos una posición
(se recibe el LSB primero). Comprobaremos que el bit de stop es
correcto, y así tendremos en un registro el byte recibido.
Para tener una buena temporización se puede optar por un
generador de baud rate externo o bien podemos "contar
instrucciones" que sabemos que se ejecutan a fosc/4. En vez de
muestrear solo una vez cada bit sería recomendable hacerlo
tres veces si el canal es ruidoso.
Para transmitir es muy sencillo. Se elige una pata. Se
configura como salida y se pone a '1' como valor por defecto.
Para empezar a transmitir se pone a cero la salida. Se espera el
tiempo de un bit (416us para 2400bps) y se procede igual con el
resto de bits empezando por el LSB. Por último poner la
salida a 1 (bit de stop). Si no se quiere transmitir más
dejar entonces la salida a '1'. Si se quiere transmitir
más, entonces hay que dejar la salida a '1' el tiempo de
un bit (stop bit) y comenzar otra vez con el start bit
.
Ver código fuente en el CD adjunto
(codigo.zip).
Consultar también la Application Note de
Microchip: AN555 incluida en el CD.
Interfaz Microcontrolador-PC. El MAX232.
Para poder conectar el microcontrolador con el puerto
serie necesitamos un circuito que nos cambie los niveles de 0V(5V
a -15V(15V. El MAX232 es el integrado más típico,
aunque no el único, que realiza esta función. Usa
la técnica de conmutar rápidamente los
condensadores para, a partir de una sola tensión de
alimentación de 5 V, generar dos tensiones
simétricas de -15 V y 15 V. Se pueden consultar las
características eléctricas del MAX232 en el
documento max232.pdf incluido en el CD. El MAX232 puede alcanzar
velocidades de hasta 120 Kbps y el MAX232A de 200
Kbps.
Para conectar el 16F873 usaremos el siguiente esquema
:
Interfaz del PIC16F873 con el puerto
serie.
RC7 es también la pata RX de la USART. RC6 es la
pata TX de la USART. Hay que configurar RC7 y RC5 como entradas y
RC6 y RC4 como salidas con valor por defecto '1'. Cuando RTS
esté a nivel bajo el PC está listo, así que
si se quiere recibir datos pondremos CTS a 0. Cuando se haya
agotado el espacio de almacenamiento pondremos CTS a 1, se
procesan los datos y se pone CTS de nuevo a 1.
Si se quiere conectar el 16F84:
Interfaz del PIC16F84 con el puerto
serie.
RB0 será la pata RX, se configurará como
entrada y se activará la interrupción asociada en
flanco de bajada. RB1 será TX (salida con valor por
defecto '1' ), RB2 será RTS (entrada) y RB3 será
CTS (salida con valor por defecto '1' ). En vez de RB1, RB2 y RB3
se podrían elegir otras patas, pero la elección de
RB0 como RX es crítica.
Enviado por:
Pablo Turmero