CAPTULO 9 PROGRAMANDO LA INTERFAZ SERIAL
La programacin del puerto serial de E/S, la reconoce el DOS como COM1 y COM2. Esto se puede realizar de varias formas: Usando las funciones open, read , write y close, proporcionadas por el lenguaje C. Con las funciones de la interrupcin lgica 0x14 (int 14h) Programando los puertos de E/S en forma directa.
9.1. ACCESO DE LA LNEA SERIE USANDO FUNCIONES DE ARCHIVO
Esto consiste en abrir un archivo asociado al perifrico (COM1 o COM2). este mtodo tiene el inconveniente de que nada le indica al PC si el dato est disponible en la lnea serie. Si en el momento en que se efecta la operacin read hay un dato disponible, esta operacin no produce ningn retraso, pues se realiza inmediatamente. Si no existe dato disponible, es sistema permanecer en escucha, dejando de lado cualquier otra actividad. Ej 9.1 Acceso a la lnea serie.
#include<fcntl.h> #include<io.h> #include<stdlib.h> #include<stdio.h> #include<string.h> #include<conio.h> void main() { int fn; char c[100]; fn=open("COM1",O_BINARY|O_RDWR); if(fn==-1) exit(0); cprintf("Cual es su mensaje? :"); gets(c); write(fn,c,strlen(c)); read(fn,c,1); /* Quedar esperando respuesta */ }
9.2. NORMA DE COMUNICACIONES RS-232C Es una norma de comunicacin serial, utilizada para la comunicacin entre modems, terminales, impresoras, computadores. Fue definida como estndar por la Asociacin de Industrias Electrnicas (EIA).
76
Preparado por Juan Ignacio Huircn
El modem (Equipo de comunicacin de datos o DCE) dispone de un conector hembra y el terminal de un conector macho. De las veinte seales definidas generalmente se ocupan nueve y a menudo slo tres son las ms usadas, puesto que la norma establecida no especfica cuantas deben ser usadas. las seales de los pin 4, 5, 6, 8, 20, son dilogo, utilizadas entre el modem y el trminal, mientras que los pines 15,17 y 24 se utilizan para modem de alta velocidad. El pin 22 indica que el modem ha detectado una seal de llamada en la lnea telefnica y es utilizada por el sistema para responder automticamente. La norma define los niveles de tensin entre -3v y -15v para el estado lgico "1" y de +3v a +15v para el estado "0". Para compatibilizar estos niveles con TTL, es necesario utilizar circuitos integrados diseados para tal efecto, tal es el caso de los chip MAX232, MC1488 y MC1489. Respecto de las conexiones El conector para RS-232 tiene 25 terminales (pines), y se conoce como DB25. En la siguiente tabla se describen la mayora de las patillas. Patilla
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
Abreviacin
TD RD RTS CTS DSR DCD
Descripcin Masa de proteccin Transmisin desde el terminal Recepcin desde el modem Peticin de envo Borrado de envo Dato preparado Masa de seal Detector de portadora Reservado Reservado Sin asignacin Detector secundario de portadora Borrado de envo secundario Transmisin de datos secundarios Reloj de transmisin desde el DCE Recepcin de datos secundario Reloj de recepcin Sin Asignacin Peticin de envo secundario Terminal de datos preparado Detector de calidad de seal Indicador de llamada Selector de velocidad de datos Sin asignacin
DTR
Tabla 9.1. Descripcin de Seales DB25.
Las seales ms utilizadas son las siguientes:
Apuntes de Herramientas de Programacin Seales
TX,
77 Descripcin Seal de salida de informacin serial desde el terminal (DTE). PIN 3 en modem (DCE). Seal de entrada de informacin serial en terminal (DTE). PIN 2 en modem. Indica que el modem ha recibido seal portadora del modem remoto. Seal desde el teminal al modem, que indica que el terminal de datos (DTE) est listo para enviar datos al modem (DCE). Seal desde el modem al terminal que indica que el modem est listo para la transferencia de informacin. Seal desde el terminal al modem que indica que el terminal quiere enviar datos al modem. Seal desde el modem al terminal que indica que el terminal puede enviar datos al modem.
transmisin (PIN 2)
RX,
recepcin (PIN 3)
Data Carrier Detect (DCD, PIN 8)
Terminal de datos preparado (DTR, PIN 20) Modem encedido y preparado (DSR, PIN 6) Peticin de envo (RTS, PIN 4)
Modem Preparado para Tx (CTS, PIN 5)
Tabla 9.2. Descripcin de Seales de control de modem.
El dilogo con el modem para la transmisin de caracteres desde el teminal ser esquematizado en los siguiente diagrama de flujo:
Inicio Activar DTR
SI NO NO
Inicio
Activar DTR
SI NO
DSR
SI
Wait
Tiempo
Error TX
NO
DSR
SI
Wait
Tiempo
Error TX
Fin Activar RTS
SI NO
SI NO NO
Fin
CARAC
NO
Wait
Tiempo
Error TX
CTS
SI
Wait
Tiempo
Error TX
SI
Fin
Fin
Leer caracter
TX dato
Desactivar DTR
Desactivar DTR, RTS
Fin
Fin
(a)
(b)
Figura 9.1. (a) Diagrama de flujo para TX. (b) Diagrama de flujo para RX.
78
Preparado por Juan Ignacio Huircn
Diagrama de conexiones Como la norma no establece el nmero de seales que deben utilizarse para la comunicacin, pueden existir diferentes formas de comunicacin entre los dispositivos. El caso ms general corresponde a la conexin de las ocho lineas ms utilizadas, en este caso la conexin debe ser directa, pues el terminal est configurado como DTE y el modem como DCE. PC
TX RX RTS CTS DSR GND DCD DTR 2 3 4 5 6 7 8 20 ________________ ________________ ________________ ________________ ________________ ________________ ________________ ________________
MODEM
2 3 4 5 6 7 8 20
Figura 9.2. Conexin PC-MODEM.
Es posible establecer una comunicacin entre dos DTE sin la intervencin de modems (distancias cortas), con lo cual la conexin puede hacerse de la siguiente forma: PC 1
TX RX GND RTS CTS DCD DSR DTR 2 3 7 4 5 8 6 20 _______________ _______________ _______________ __ __| __ __|
PC 2
RX TX GND RTS CTS DCD DSR DTR
3 2 7 4__ 5__| 8 __ 6 |__ 20
Figura 9.3. Conexin PC-PC.
Una conexin con tres terminales permitir intercambiar mensajes y archivos entre mquinas, contando con un programa de comunicaciones adecuado. Puede utilzar solamente los terminales 2, 3, 7. Dentro de los aspectos prcticos es necesario mencionar que existe un conector RS-232 de 9 pines (DB9). La equivalencia entre este conector y el de 25 pin es la siguiente: 9 PINS
1 2 3 4 5 6 7 8 9
25 PINS
8 3 2 20 7 6 4 5 22
Patilla
DCD RD TD DTR SG (SIGNAL GROUND) DSR RTS CTS RING INDICATOR
Tabla 9.3. Equivalencia de terminales entre el conecto DB9 y DB25
Apuntes de Herramientas de Programacin
79
Lo anterior puede no cumplirse, es conveniente revisar los manuales correspondientes en el caso de querer realizar alguna conexin.
9.3. ACCESO DE LA INTERFAZ SERIAL UTILIZANDO LA INT 14H
Tambin podemos utilizar el BIOS para tener un acceso cmodo al puerto de E/S serial, sin preocuparnos del harware. Para realizar esto usamos interrupcin 14h (int 0x14 ). esta proporciona cuatro funciones, las que pueden ser accesadas a travs de AH. AH
0
Funcin
Registros
Inicializa puerto Entrada: DX = # del puerto serie (0 1) de comunicaciones AL = Parmetros de Inicializacin. (ver siguiente tabla 9.6.)
Salida : AX Envia caracter Entrada: DX sobre la linea AL Salida : AH Bit 7 Leer caracter de Entrada: DX la lnea Salida: AL AH Si AH no es Leer palabra de Entrada: DX estado del puerto Salida : AX de comunicaciones AH
= Estado = # del puerto (0 1) = Caracter a enviar = Estado de la linea: =1, si caracter no tx = # del puerto (0 1) = Caracter leido = Estado de la linea 0 es que ha ocurrido error = Nmero puerto = Palabra de estado = Estado de la lnea
AL= Estado del modem
Tabla 9.4. Parmetros de inicializacin para int 14h.
Los parmetros de inicializacin son codificados en una palabra de 8 bits Bits
b7-b5
Contenido
Velocidad (baudios): 000=110 001=150 010=300 011=600 100=1200 101=2400 110=4800 111=9600
b4-b3
Paridad:
X0 = ninguna 01 = impar 11 = par
Tabla 9.5. Registro de inicializacin.
80
Preparado por Juan Ignacio Huircn
b2
b1-b0
Bits de stop: 0 = 1 bits 1 = 1.5 bits si el largo del caracter es 5 1 = 2 bits si el largo del caracter es 6, 7 u 8. largo del caracter: 00=5 01=6 10=7 11=8
Tabla 9.6. (Continuacin) Registro de inicializacin.
El estado se codifica de la siguiente forma: Bits de AH
b7 b6 b5 b4 b3 b2 b1 b0
Contenido
Tiempo excedido Registro desplazamiento vaco Registro TXvaco Interrupcin (BREAK) Error de formato (framimg) Error de paridad Error de Sobrecarga (Overrun) Dato preparado (Listo)
Bits de AL
b7 b6 b5 b4 b3 b2 b1 b0
Contenido
DCD (Data Carrier Detect) RI (Ring indicator) DSR (Data Set Ready) CTS ( Clear to Send) Delta DCD Delta RI Delta DSR Delta CTS
Tabla 9.7. Contenido de AX .
Ej 9.2 Programando la RS-232 para TX y RX utilizando la int 14h .
#include #include #include #include <dos.h> <stdio.h> <stdlib.h> <conio.h>
union REGS rent, rsal;
void ini_rs232() { rent.h.ah=0x00; /* Inicializacin */ rent.x.dx=0x00; /* COM1 */ /*1200 bps, sin par, 1 bit stop, 8 bit datos */ rent.h.al=0x83; int86(0x14,&rent,&rsal); }
Apuntes de Herramientas de Programacin
void escribe(char c) { /* Funcin escribir */ rent.h.ah=0x01; rent.x.dx=0x00; /* COM1 */ rent.h.al=c; /* Escribe caracter c */ int86(0x14,&rent,&rsal); } int test_rs() { /* Lee status de lnea */ rent.h.ah=0x03; rent.x.dx=0x00; /* COM1 */ int86(0x14,&rent,&rsal); /* Retorna bits menos significativo */ return(rsal.h.ah & 0x01); } char leer_rs() { /* Funcin Leer dato */ rent.h.ah=0x02; rent.x.dx=0x00; /* COM1 */ int86(0x14,&rent,&rsal); /* Retorna el dato en AL */ return(rsal.h.al); } void main() { int st; char c; /* Inicializacin RS-232 */ ini_rs232(); while(1) { st=test_rs(); /* Lee estado de la lnea */ if(st) { c=leer_rs(); /* Lee dato */ putch(c); } if(kbhit()) { c=getch(); if(c==0x1b) exit(0); /* Escribe Caracter */ escribe(c); } } } /* main */
81
Note que no se han declarado las funciones. Esto no es necesario cuando es escribe el main() al final.
82
Preparado por Juan Ignacio Huircn
9.4. PROGRAMANDO RUTINAS DE INTERRUPCIN PARA LA COMUNICACIN SERIAL
Si bien el BIOS del IBM-PC nos proporciona la ayuda para la transmisin y recepcin serial entre los dispositivos, esta tiene sus limitaciones:
### La velocidad mxima de transmisin es de 9600 bits/seg. Generalmente se cree que este es el valor mximo de
la interfaz de comunicacin, sin embargo es slo una limitacin del BIOS. Para aumentar le velocidad es necesario programar en forma directa del dispositivo de transmisin UART (Unidad Asincrnica De Transmisin Y Recepcin), a travs de sus puertos de programacin.
### La recepcin de caracteres debe hacerse por encuesta al registro de estado del dispositivo de recepcin
(UART) El BIOS al no disponer de servicios de interrupcin (hardware) para transmisin y recepcin de caracteres no justifica una velocidad de ms de 9600 bits/seg. Aun a esta velocidad se requiere de un programa pequeo y eficiente que permita rpidamente la lectura de los caracteres de la UART, antes de que llegue el prximo dato. Si se quieren mejorar las caractersticas de transmisin, por ejemplo su velocidad y tiempo de atencin (por interrupcin) necesariamente debemos programar en forma directa los registros del UART. Para realizarlo en lenguaje C se deben utilizar las instrucciones para manejo de los puertos de Entrada/Salida. El UART o 8250 posee las siguientes caractersticas:
Divisor programable de 16 bits. Programacin de todas las caractersticas de comunicacin serial (caracteres, bits de stop, paridad, etc). Programacin en modo loop (para test)
Una programacin de los parmetros habituales se efecta enviando una secuencia de bytes a los puertos correspondientes, los puertos asignados en el IBM-PC son los siguientes:
DLAB=0 2F8 3F8 DLAB=0 2F8 3F8 DLAB=0 2F9 3F9
REG ENABLE INT
INT RX DATO INT TX HL INT RX LIN INT ST MOD 0 0 0 0
COM2 COM1
BIT
0 1 2 3 4 5 6 7
2FA 3FA
REG ID
INT PEND INT ID INT ID 0 0 0 0 0
2FB 3FB
LINE CTRL
LARGO DATA LARGO DATA STOP BIT HABILITA PARIDAD TIPO PARIDAD FIJAR PARIDAD SET BREAK
DIV. LATCH ACCESS BIT (DLAB)
2FC 3FC
MODEM CTRL
LINEA DTR RTS OUT 1 OUT 2 LOOP 0 0 0
2FD 3FD
LINE STATUS
DATO LISTO ERROR OVERRUN ERROR PARIDAD ERROR TRAMA BREAK INT TX HOLD VACIO THSHT VACIO 0
2FE 3FE
MODEM STATUS
Delta CTS
Delta DSR Delta RING Delta RLSD CTS DSR RING RLSD
REG TX REG RX (WR only) (RD only)
D0 D1 D2 D3 D4 D5 D6 D7 D0 D1 D2 D3 D4 D5 D6 D7
Tabla 9.8. Descripcin de registros del puerto de comunicaciones.
Si el DLAB =1 (Divisor latch access bit), entonces es posible programar el divisor para la inicializacin de la velocidad. Para hacer el DLAB=1, debe poner en 1 el bit ms significativo del registro 0x3fb (o 0x2fb).
Apuntes de Herramientas de Programacin
COM2 2F8 2F9 COM1 3F8 3F9
D7 B7 B15 D6 B6 B14 D5 B5 B13 D4 B4 B12 D3 B3 B11 D2 B2 B10 D1 B1 B9 D0 B0 B8
83
DIV LS DIV MS
Tabla 9.9. Direcciones para la programacin del divisor.
Para la programacin de la velocidad adems de accesar el divisor (DLAB=1), se debe conocer el reloj externo que es aplicado al 8250. Existen dos posibilidades.
ck1=1.8432 ck2=3.072 MHz MHz
En las siguientes tablas se encuentra el divisor adecuado para cada una de las velocidades y reloj utilizado.
CLOCK = 1.8432MHz DESIRED BAUD RATE 110 150 300 600 1200 2400 4800 9600 19200 38400 56000 DIVISOR USED TO GENERATE 16XCLOCK 1047 768 384 192 96 48 24 12 6 3 2 CLOCK=3.072MHz DESIRED BAUD DIVISOR USED RATE TO GENERATE 16XCLOCK 110 1795 150 1280 300 6404 600 3202 1200 1606 2400 80 4800 40 9600 20 19200 10 38400 5 56000 3
Tabla 9.10.Constantes para programar la 8250.
Ej 9.3. Como utilizar la tabla 9.10. Para una velocidad de 1200 baudios, se debe calcular la frecuencia necesaria para generar 16 veces la frecuencia de la tasa de baudios. Usando un clock =1.8432, para una velocidad de 1200 baudios:
1. 8432 x10 6 = 96 1200 x16
La conexin del UART en el IBM-PC es:
84
Preparado por Juan Ignacio Huircn
OUT2
UART
8250 INT
IRQ3 IRQ4
CONTROL. INTERR.
8259
Figura 9.4. Conexin del UART al Controlador de Interrupciones.
Luego para que la UART interrumpa al PC debemos habilitar la seal de interrupcin a travs de la seal OUT2 y adems programar la interrupcin en el registro relativo #1(0x3f9 o 0x2f9 ) del UART. Otra consideracin especial es que se debe programar el controlador de interrupciones (8259) para habilitar la interrupcin ya sea por COM1 o COM2, adems de enviar un EOI (End Interrupt) al final de la RSI. De acuerdo a esto, se enva un byte de habilitacin de interrupcin al puerto 0x21, dicho byte tiene la siguiente estructura
B7 B6 B5 B4 B3 B2 B1 B0
IRQ7
IRQ6 IRQ5
IRQ4 COM1
IRQ3 COM2
IRQ2
IRQ1 IRQ0
Luego para habilitar cualquiera de las interrupciones, se debe hacer un SET o un RESET al bit correspondiente, es decir.
0: Para habilitar 1: Para deshabilitar
Ej 9.4. Programacin de un puerto de 8250. La programacin del chip para 8 bits de datos, 1 bits de stop, y paridad par, se debe enviar el valor 0x1B al puerto 0x3fb .
#include<dos.h> #define BASE 0x3f8 /* Para COM1 , 0x2f8 para COM2 */
void main() { outportb(BASE+3, 0x1b); }
/* Prog. el 0x3fb */
Ej 9.5. Habilitando y deshabilitando las interrupciones.
outportb(0x21,0x00); outportb(0x21,0xff); /* Habilita todas las interrupciones /* Deshabilita todas las interrupcione */ */
Si se desea mayor comprensin acerca del CHIP 8250, puede consultar la referencia tcnica .
Apuntes de Herramientas de Programacin Ej 9.6. El siguiente programa prepara el dispositivo serial para recibir datos va interrupcin:
#include <dos.h> #include <stdio.h> #include <conio.h> #define INT 0x0C /* Vector C, IRQ4 */
85
void interrupt (*ant_irq)(); /* Puntero a funcion */ void interrupt rx(); void prog_8250(); int flag=0; unsigned static int dato=0; void main(void) { clrscr(); outportb(0x21,0xff); /* Deshabilita todas las interrupciones */ prog_8250(); ant_irq=getvect(INT); setvect(INT,rx); outportb(0x21,0x00); /* Habilita todas las interrupciones */ enable(); do { if(flag==1) { printf("%d ",dato); flag=0; } if(kbhit()) break; } while(1); setvect(INT,ant_irq); /* Restaura el vector de interrupcin */ getch(); } void prog_8250() { outport(0x3fb,0x80); outport(0x3f8,0x06); outport(0x3f9,0x00); outport(0x3fb,0x07); outport(0x3fc,0x08); outport(0x3f9,0x01); } void interrupt rx() { flag=1; dato=inportb(0x3f8); outportb(0x20,0x20); }
/* /* /* /* /* /*
DLAB=1 */ divisor (Low) =0x06 vel 19200 baudios */ divisor (High)=0x00 vel 19200 baudios */ 8 bits ,2 stop, sin paridad */ out 2 = 1 */ Interrumpe cuando llega dato */
/* EOI */