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 Pin DB-25 | Número de Pin 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