4 el puerto serie usart v2 (1)

39
1 El Puerto Serie USART

Upload: andy-cruz

Post on 13-Aug-2015

42 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 4 El Puerto Serie USART V2 (1)

1

El Puerto Serie USART

Page 2: 4 El Puerto Serie USART V2 (1)

2

1. El Puerto Serie USART

1.1. Introducción La USART (Universal Synchronous Asynchronous Receiver Transmitter) es uno de los dos periféricos contenidos en el PIC que le permiten realizar comunicación en serie. El otro es el MSSP (Master Synchronous Serial Port). La USART, también conocida como SCI (Serial Communications Interface) puede configurarse como una unidad de comunicación en serie para la transmisión de datos asíncrona con dispositivos tales como terminales de computadora o computadoras personales, o bien para comunicación síncrona con dispositivos tales como convertidores A/D o D/A, circuitos integrados o memorias EEPROM con comunicación serie, etc. La gran mayoría de los sistemas de comunicación de datos digitales actuales utilizan la comunicación en serie, debido a las grandes ventajas que representa esta manera de comunicar los datos: • Económica. Utiliza pocas líneas de transmisión inclusive puede usar sólo una línea. • Confiable. Los estándares actuales permiten transmitir datos con bits de paridad y a niveles de

voltaje o corriente que los hacen poco sensibles a ruido externo. Además por tratarse de información digital, los cambios en amplitud de las señales (normalmente causados por ruido) afectan muy poco o nada a la información.

• Versátil. No está limitada a usar conductores eléctricos como medio de transmisión, pudiendo usarse también: fibra óptica, aire, vacío, etc. Además el tipo de energía utilizada puede ser diferente: luz visible, infrarroja, ultrasonido, pulsos eléctricos, radio frecuencia, microondas, etc.

Una gran cantidad de periféricos se comunican actualmente en serie con una microcomputadora: líneas telefónicas, terminales remotas, unidades de dispositivos magnéticos, ratón, teclados, etc. En general existen dos tipos de comunicación de información:

1. Comunicación en paralelo 2. Comunicación en Serie.

1. Comunicación en paralelo. En este caso se utiliza una línea física por cada bit del dato a

comunicar; además de posibles líneas para protocolo. Esquemáticamente en la siguiente figura se muestra como se transmitiría el dato de 8 bits 1001 0111= 97h.

Este tipo de comunicación se puede realizar mediante el PIC usando el puerto D como puerto de datos y las líneas del puerto E como líneas de protocolo.

Page 3: 4 El Puerto Serie USART V2 (1)

3

La principal ventaja de la comunicación paralela es la alta velocidad de transmisión, ya que se envían simultáneamente todos los bits de un dato. No obstante, si la distancia entre el transmisor y el receptor es grande, puede ser que el costo de las líneas sea tan alto que se vuelva incosteable este método de comunicación.

2. Comunicación en Serie. En cambio, la comunicación en serie sólo utiliza una línea para la

transmisión de datos, y opcionalmente alguna línea o líneas para protocolo. Por ejemplo, en la siguiente figura se muestra como se transmitiría en serie el mismo dato (97h):

La desventaja obvia de la comunicación serie es que los bits de un dato se envían de a uno por uno, de manera que mientras que la comunicación en paralelo envía en un ciclo un dato de 8 bits, a la comunicación serie le toma más de 8 ciclos (ya que además del dato en la comunicación serie se requiere agregar algunos bits de sincronización.

Sin embargo, debido a que la comunicación serie requiere sólo una línea para la transmisión esto abarata los costos en líneas de transmisión y no sólo esto, ya que este hecho también hace posible que los datos puedan ser enviados no necesariamente por un conductor eléctrico, sino inclusive por aire o por el vacío si en lugar de pulsos eléctricos se usan impulsos electromagnéticos, tales como: ondas de radio, microondas, pulsos luminosos, infrarrojo, ultrasonido, láser (a través de fibra óptica), etc.

1.2. Protocolo de comunicación serie A diferencia de la comunicación en paralelo, en la comunicación en serie se hace necesario establecer métodos de sincronización para evitar la interpretación errónea de los datos transmitidos. Para ilustrar esto consideremos la siguiente información en serie:

...0100110001001100100...

Esta información puede interpretarse de diversas maneras, (aún si se recibe a la velocidad adecuada) dependiendo del punto de inicio de separación de datos, por ejemplo, una posible interpretación sería como sigue:

Que interpretado como códigos ASCII corresponde a los caracteres ‘1’ y ‘2’. Sin embargo, otra posible interpretación es:

Que corresponde a los caracteres ‘b’ y ‘d’.

Page 4: 4 El Puerto Serie USART V2 (1)

4

Sincronización de bit. Una manera de resolver el problema anterior es la sincronización de bits que puede realizarse por varios métodos:

1) Enviar por una línea adicional una señal de reloj que indique el centro de las celdas de

bits en la línea de datos (datos no - auto reloj). 2) Enviar con cada bit y por la misma línea de datos información que permita extraer la

señal de reloj (datos auto reloj). 3) Lograr mediante alguna estrategia que los relojes de transmisión y de recepción se mantengan

en fase continuamente. Codificación no auto reloj. En la figura siguiente se muestran las tres codificaciones de una línea de datos:

RZ. Una celda de bit es 1 si contiene un impulso positivo y un 0 si no lo contiene. NRZ. La celda contiene un 1 o 0 de acuerdo al nivel de la señal (constante) en la celda. NRZI. La celda de bit contiene un 1 si hay una transición y un 0 si no la hay.

Como puede verse, en estos sistemas (RZ, NRZ y NRZI) las secuencias de ceros no contienen ninguna transición que permita ubicar la situación de las celdas de bit. De hecho, el formato NRZ no la contiene ni en los unos. Codificación auto reloj. Algunos métodos que contienen en la misma línea de datos información adicional para determinar la velocidad del reloj a costa de disminuir la cantidad de información útil a la mitad que los métodos no-auto reloj. En la siguiente figura se muestran los más utilizados, como son:

Page 5: 4 El Puerto Serie USART V2 (1)

5

PE. Codificación de fase. FSC. Codificación por cambio de frecuencia FM. Modulación de frecuencia. MFM y M2

FM. Modulación de frecuencia modificada. Los métodos auto reloj son muy útiles cuando la velocidad de transmisión no es constante, por ejemplo, cuando los datos han sido grabados en un medio magnético giratorio; discos, cintas magnéticas, etc. Sincronización de caracter. Algunos sistemas utilizan líneas adicionales que envían impulsos para indicar el inicio de un bloque de caracteres. Otros sistemas que no requieren líneas adicionales a la línea de datos son: 1. Método Asíncrono. Cada carácter va señalizado mediante dos bits: un bit de inicio y un bit de

paro, estos dos bits permiten al receptor reconocer el inicio y el final de cada carácter. La especificación RS404 de EIA (Electronic Industries Association) define las características del método asíncrono para transmisión en serie de acuerdo a las siguientes reglas:

1) Cuando no se envían datos la línea debe mantenerse en estado 1. 2) Cuando se va a mandar un carácter se envía primero un bit de inicio de valor 0. 3) A continuación se envían todos los bits del carácter a transmitir al ritmo marcado por el reloj

de transmisión. 4) Después del último bit del carácter enviado se envía un bit de paro de valor 1.

2. Método Síncrono. Cada mensaje o bloque de transmisión va precedido de unos caracteres

de sincronismo. Así, cuando el receptor identifica una configuración de bits igual a la de los caracteres de sincronismo da por detectado el inicio y el tamaño de los datos.

Observación: Para el usuario de un microcontrolador que posee una USART o sistema similar la manera detallada como el sistema logra establecer la comunicación resulta transparente a él, ya que sólo tiene que configurar el protocolo del transmisor y del receptor para que estos logren la comunicación adecuada, es decir, el usuario usualmente sólo debe configurar:

• Tipo de comunicación (síncrona o asíncrona) • Velocidad de transmisión en Baudios (bits por segundo) • Longitud de los datos • Bits de inicio y de paro, bits de paridad, etc.

1.3. La USART del PIC16F877

La USART del PIC puede ser configurada para operar en tres modos:

1. Modo Asíncrono (full duplex (transmisión y recepción simultáneas)) 2. Modo Síncrono – Maestro (half duplex) 3. Modo Síncrono – Esclavo (half duplex)

1.3.1. La Interfase RS232 Se prosigue con el estudio de conectar el PIC con el mundo externo analizando, ahora, cómo es posible dotar al PIC de una interfase RS232 para conectarlo al puerto serie del PC.

Page 6: 4 El Puerto Serie USART V2 (1)

6

1. La Norma RS232 La norma RS232 define una especificación para la transmisión serial de datos entre dos dispositivos denominados DTE (Data Terminal Equipment) y DCE (Data Communication Equipment). Como no se pueden comprender estas definiciones, el Data Communication Equipment es un dispositivo que se usa para manejar una comunicación de los datos mientras Data Terminal Equipment es un dispositivo que se usa para almacenar o recibir datos. En la práctica el RS232 se ha creado para conectar terminales de datos (en el caso del ejercicio a desarrollarse una computadora) con un módem para la transmisión de datos generados. Tener una conexión entre dos computadoras es por consiguiente disponer de cuatro dispositivos como se puede observar en la figura: una computadora (DTE) conectado a un módem (DCE) y otro módem (DCE) conectado a su computadora (DTE). De manera que cualquier dato de la primera computadora es transmitido a través de RS232 al módem relativo, luego transmitido de éste al módem remoto que a su vez vuelve a enviárselo a su computadora a través de RS232.

Para usar la conexión RS232 entre dos computadoras cercanas sin interponer entre ellos algunos módems, se debe simular las conexiones del intermediario que de algún modo comprenden un cable NULL MODEM o un cable intermedio, de tal manera de conectar directamente los dos DTEs como si entre ellos existiera los DCEs de hecho. Para conectar el PC a un circuito se simula directamente un DCE que tiene al PC conectado a un módem. Antes de hacer esto se debe ver en detalle el principio de funcionamiento de la comunicación serial. 2. La comunicación serial asincrónica Para permitir la transmisión de datos entre el PC y el módem, la norma RS232 define una serie de especificaciones eléctricas y mecánicas. Una de estas preocupaciones es el tipo de comunicación serial que se quiere llevar a cabo, la que puede ser síncrono o asíncrono. Se analiza la más usada que es la comunicación serial asíncrono, ignorando completamente la síncrono en cuánto es más complejo y no está disponible en el PC normal. Una comunicación serial. Generalmente consiste en la transmisión y recepción de datos de un punto a otro sólo usando una línea eléctrica. En la práctica si se desea transmitir un byte entero se debe obtener un solo bit para luego enviarlos en secuencia en la misma línea eléctrica.

Page 7: 4 El Puerto Serie USART V2 (1)

7

La comunicación serial usando RS232 entre un par de PC’s, se hace de acuerdo a la siguiente figura, en donde se toma un par de hilos y se conecta entre los puertos seriales de las dos PC ( que se denominarán transmisor PC y receptor PC ), según lo mostrado en la figura:

La línea de transmisión de Datos (TXD) se presenta con el pin 3 del conector DB9 macho del PC, para ser conectado a la línea de recepción de datos(RXD) que se presenta en el pin 2 del segundo PC. Las masas (GND) se presentan en el pin 5 de ambos PC y se conectan entre ellos. Para observar las señales generadas del PC transmisor durante la transmisión serial, se conecta entre la línea TXD y la línea GND un osciloscopio y se ejecutan en ambos PC’s un programa de emulación terminal ( tipo Hyperterminal o similar ). La configuración del puerto serial entre dos PC’s. Se realiza para que la información del un PC se pueda transmitir inmediatamente a través del puerto serial al otro PC. Por ejemplo, la configuración del puerto serial de ambos PC’s podrían ser: 9600 baudios, 8 bits por dato, 1 bit de parada, ninguna paridad y se deshabilita el control de flujo (handshake ), como un hardware con xon/xoff. Además, se debe asegurar que el programa de selección de emulación terminal esté configurado para usar el puerto serial en el que se conecta oportunamente (COM1 o COM2). Cuando no hay ninguna transmisión en marcha la tensión en la línea TXD es de -12 voltios correspondientes a la condición 1 lógico. Para indicar al receptor PC que la transmisión ha empezando, el PC transmisor coloca la línea TXD a +12 voltios correspondientes a la condición 0 lógico, por un tiempo igual al inverso de la frecuencia de transmisión o al tiempo de transmisión de un sólo bit. Este 0 lógico se denomina bit de inicio ( START BIT ) y siempre está presente en la transmisión al principio de un solo byte. El bit de inicio se transmite en sucesión con los ocho bits componentes del código ASCII del carácter transmitido partiendo del bit menos significativo. Una vez transmitido el octavo bit ( bit 7 ), el PC agrega automáticamente un último bit con valor 1 lógico denominado STOP BIT ( bit de parada ); para indicar la transmisión del byte entero se ha realizado. La misma secuencia se repite para cada byte transmitido en la línea. Por ejemplo, al transmitir el carácter A minúscula desde un PC a otro PC usando RS232, con una configuración del puerto serial de ambos PC’s de: 9600 bits por segundo, 8 bits por dato, 1 bit de parada, ninguna paridad y la tensión de alimentación a +12 voltios, la secuencia de transmisión que se verá en el osciloscopio será la siguiente:

• Tiempo de transmisión de un sólo bit = 1 / 9600 = 0.104 ms • Valor binario de la letra A minúscula = 01000001

Page 8: 4 El Puerto Serie USART V2 (1)

8

Transmisión RS232 bidireccional. Para efectuar una transmisión RS232 bidireccional se agrega al cable serial una conexión entre el pin TXD ( pin 3 ) del PC receptor con el pin RXD ( pin 2 ) del PC transmisor. El cable que se consigue es el cable más simple NULL MODEM para poner en conexión entre los dos DTE.

3. Conexión a un circuito con PIC El circuito con PIC simula un dispositivo DCE, esto significa que el cable que se debe usar no debe ser de tipo NULL MODEM o INVERTENTE, pero debe ser DRITTO con los pines numerados igualmente conectados entre ellos. Este tipo de cable es idéntico a aquéllos que se usan para conectar un módem externo al PC. Dado que el dispositivo DTE siempre está dotado de conector DB9 macho, el circuito siendo un DCE, tendrá un conector DB9 hembra. El cable de conexión entre el PIC y el circuito debe estar a su vez seguido de un conector hembra de un lado, para poder realizar la transmisión serial del PIC, y un conector macho del otro para poder estar conectado al conector del circuito de prueba. Se tienen en la figura siguiente las conexiones internas al cable que se usa:

4. Funcionamiento del MAX232 Para la conexión entre el PC y el circuito con PIC se usa un driver RS232 (MAX232) o un integrado para convertir las señales a + / - 12 voltios típico del RS232 en señales a 0/5 voltios del puerto del PIC. Por lo tanto, la conexión entre el PC y el circuito con PIC se debe realizar que la señal de transmisión proveniente del PC entre del pin 3 del conector DB9 hembra en el pin 13 del driver. En el pin 12 del driver la señal estará presente a 0 voltios cuando en el pin 13 exista +12 voltios y 5 voltios cuando en el pin 13 exista -12 voltios. La señal presente en el pin 12 del driver es enviado por consiguiente a la línea RA1 del puerto A del PIC que en este caso hará de línea de recepción.

Page 9: 4 El Puerto Serie USART V2 (1)

9

En el pin 18 del PIC (RA1) tiene por lo tanto la siguiente correspondencia de la señal con la línea TXD del PC:

De igual forma en el pin 17 (RA0) del PIC se genera una señal para enviarla hacia el PC para nivelar en TTL que luego se convierte en señales RS232 del driver por medio del pin 11 ( entrada TTL ) y 14 ( salida RS232 ) y por consiguiente los enviados al PC a través del pin 2 del conector. En la siguiente Figura se muestra la conexión del MAX232 entre la PC y el PIC:

5. Modo Universal Synchronous Asynchronous Receiver Transmitter (USART)

El módulo transmisor (USART) es otro de los dos puertos serie de los que dispone esta familia de microcontroladores, USART también se conocen como Serial Communications o Interface (SCI). El USART puede configurarse como asíncrono full dúplex que puede comunique con los dispositivos periféricos como el terminales de CRT y los ordenadores personales, o puede configurarse como un sistema síncrono half duplex que puede comunicar con otros microcontroladores, con dispositivos periféricos como A/D o D/A circuitos integrados, EEPROMs serie etc.

El USART puede configurarse en los modos siguientes:

Page 10: 4 El Puerto Serie USART V2 (1)

10

• Asíncrono( Full duplex ) • Síncrono- Master (half duplex) • Síncrono- Slave (half duplex)

Poniendo a "1" bit SPEN (RCSTA <7>), y los bits TRISC <7:6>, se configura RC6/TX/CK y RC7/RX/DT como USART.

Como ya se ha dicho, en este modo de comunicaciones se emplea una configuración estándar de un bit de Start, ocho o nueve bits de datos, y un bit de Stop. Este modo de trabajo es detenido durante la función Sleep.

Aunque la USART tiene funciones independientes para la transmisión y recepción, los formatos de datos y de velocidad de transmisión son iguales para los dos casos. El generador de baudios produce siempre las señales de reloj x16 ó x64 (dependiendo de BRGH, TXSTA<2>) para el desplazamiento de los bits.

El bit de paridad no está soportado por el hardware, pero se puede implementar por software empleando para ello el noveno bit de datos.

En este modo la USART usa un formato estándar NRZ asíncrono, el cual para la sincronización usa: 1 bit de inicio (I), 8 o 9 bits de datos y 1 bit de paro (P). Mientras no se están transmitiendo datos la USART envía continuamente un bit de marca. El modo asíncrono se selecciona limpiando el bit SYNC del registro TXSTA (98H). El modo asíncrono es deshabilitado durante el modo SLEEP. Cada dato es transmitido y recibido comenzando por el LSB. El hardware no maneja bit de Paridad, pero el noveno bit puede ser usado para este fin y manejado por software.

El circuito de muestreo. El dato en la patita de recepción (RC7/RX/DT) es muestreado tres veces para poder decidir mediante un circuito de mayoría, si se trata de un nivel alto o un nivel bajo. El módulo Asíncrono de la USART consta de 3 módulos fundamentales:

a. El generador de frecuencia de transmisión (Baud Rate) b. El transmisor asíncrono c. El receptor asíncrono.

a. El Generador de Baud Rate (BRG) Este generador sirve tanto para el modo síncrono como el asíncrono y consiste de un contador/divisor de frecuencia de 8 bits controlado por el registro SPBRG (99H). De tal manera que la frecuencia de transmisión se calcula de acuerdo a la siguiente tabla:

SYNC BRGH=0 (baja velocidad) BRGH=1 (Alta velocidad)

0 (modo asíncrono) Baud rate=Fosc/(64(X+1)) Baud rate=Fosc/(16(X+1)) 1 (modo síncrono) Baud rate=Fosc/(4(X+1)) -

Page 11: 4 El Puerto Serie USART V2 (1)

11

En esta tabla X=valor de 8 bits en el registro del divisor, SPBRG. El bit BRGH corresponde a TXSTA<2>.

Debido a que el divisor es de 8 bits, no se puede tener cualquier velocidad de transmisión deseada, ya que X se deberá redondear al entero más cercano. En las dos tablas anteriores se muestran algunos valores baud estándares, el divisor necesario (X=SPBRG) bajo diferentes frecuencias Fosc y el error producido en porcentaje. Ejemplo:

Cálculo de la proporción del error de velocidad de transmisión para las siguientes condiciones:

- FOSC = 16 MHZ - Velocidad de transmisión deseada = 9600 baudios - BRGH = 0 - SYNC = 0

Page 12: 4 El Puerto Serie USART V2 (1)

12

Como puede apreciarse, el error no tiene ninguna importania para la mayoría de las aplicaciones, no obstante, se puede realizar los cálculos empleando el índice (BRGH=1) y sustituyendo la constante 64 por 16 (ver la tabla) y comprobar si el error se reduce.

Los datos de la patilla RC7/RX/DT son muestreados en tres tiempos para detectar y determinar mejor si el nivel presente en la patilla RX está a nivel alto o bajo.

• Si el bit BRGH (TXSTA<2>) está a cero, el muestreo se realiza en el séptimo, octavo, y noveno flanco de bajada de x1 6 de reloj.

• Si por el contrario, el bit BRGH está a uno, el muestreo tiene lugar en el tercer flanco de reloj precedido de la segunda subida de reloj y de la primera bajada de x4 de reloj.

Registros asociados al Generador de Baud Rate

Dirección Nombre Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Valor en

POR,BOR Valor en el

resto de Reset

98h TXSTA CSRC TX9 TXEN SYNC --- BRGH TRMT TX9D 0000 –010 0000 –010

18h RCSTA SPEN RX9 SREN CREN ADDEN FERR OERR RX9D 0000 000X 0000 000X

99h SPGBRG Registro generador de Baud Rate

Leyenda. x = desconocido u= sin cambios - = Sin implementar, se lee “0” b. El transmisor asíncrono En la siguiente figura se muestra el diagrama de bloques del transmisor de la USART. El corazón de este módulo es el registro de corrimiento (transmit shift register, TSR). La única manera de acceder al registro TSR es a través del registro TXREG (19H). Para transmitir un dato, el programa deberá ponerlo primero en el registro TXREG. En cuanto el TSR termina de enviar el dato que tenía (en cuanto transmite el bit de paro) lee el dato contenido en TXREG (si hay alguno) esto ocurre en un ciclo TCY. En cuanto el dato de TXREG es transferido al TSR el TXREG queda vacío esta condición es indicada mediante el bit bandera TXIF (que es el bit 4 del registro PIR1 (0Ch)), el cual se pone en alto. Este bit NO puede ser limpiado por software, sólo dura un instante en bajo cuando se escribe un nuevo dato a TXREG. Si se escribe un dato seguido de otro (back to back) a TXREG el primero se transfiere inmediatamente a TSR y el otro tiene que esperar hasta que el TSR termine de enviar el bit de Stop del primero. Durante esta espera TXIF permanece en bajo. Existe otro bit, llamado TRMT (TXSTA<1>), el cual muesta el estado del TSR. TRMT se pone en alto cuando TSR está vacío, y en bajo cuando TSR está transmitiendo un dato. Mientras que TXIF puede generar una interrupción TRMT no lo puede hacer, TRMT está pensado para ser consultado por “poleo” (sin usar interrupciones).

Page 13: 4 El Puerto Serie USART V2 (1)

13

Diagrama de bloques del transmisor de la USART

Para habilitar el módulo de transmisión es necesario poner en alto el bit TXEN (TXSTA<5>), mientras no se habilite el módulo, la patita de transmisión (RC6/TX/CK) se mantiene en alta impedancia. Si TXEN es deshabilitada a la mitad de una transmisión, está será abortada y el transmisor será reseteado. Si se está usando un noveno bit TX9 (TXSTA<6>), éste deberá ser escrito antes de escribir los 8 bits restantes a TXREG, ya que en cuanto se escribe un dato a este registro inmediatamente es transferido a TSR (si éste está vacío). Registro de Estado y Control TXSTA (Transmisor)

R/W-0 R/W-0 R/W-0 R/W-0 U-0 R/W-0 R/W-0 R/W-0 CSRC TX9 TXEN SYNC ---- BRGH TRMT TX9D Bit 7 Bit 0

bit 7: CSRC: Bit de selección de reloj Modo Asíncrono Sin importancia Modo Síncrono 1 = Modo master (reloj generado internamente para BRG (Generador de Baudios)) 0 = Modo esclavo (reloj externo) bit 6: TX9: Habilita transmisión de 9-8 bits 1 = Transmisión de 9 bits 0 = Transmisión de 8 bits bit 5: TXEN: Bit de habilitación del transmisor 1 = Habilita transmisión 0 = Deshabilita transmisión Nota: SREN/CREN anula TXEN en modo SYNC. bit 4: SYNC: Bit de selección del modo USART 1 = Modo Síncrono

Page 14: 4 El Puerto Serie USART V2 (1)

14

0 = Modo Asíncrono bit 3: Sin implementar: En lectura es'0' bit 2: BRGH: Bit de selección del rango de baudios alto Modo Asíncrono 1 = Alta velocidad 0 = Baja velocidad Modo Síncrono No se usa este modo bit 1: TRMT: Bit de estado del registro de desplazamiento del transmisor (TSR) 1 = TSR vacío 0 = TSR lleno bit 0: TX9D: Noveno bit de datos de transmisión. Se puede emplear como bit de paridad.

De acuerdo a lo anterior, la inicialización del módulo de transmisión consiste en los siguientes pasos:

1. Inicializar baud rate escribiendo al registro SPBRG el divisor adecuado y opcionalmente al bit BRGH .

2. Habilitar comunicación asíncrona limpiando el bit SYNC y poniendo el 1el bit SPEN. 3. Si se van a usar interrupciones, poner el bit TXIE (PIE<4>). 4. Poner el bit TX9 si se desea transmitir datos de 9 bits 5. Habilitar transmisión poniendo el bit TXEN, lo cual pondrá el bit TXIF. 6. Colocar el noveno bit del dato en TX9D si se están usando datos de 9 bits. 7. Cargar el dato al registro TXREG (inicia la transmisión).

Ejemplo 1

Transmisión asíncrona El siguiente programa envía de manera asíncrona a través de la USART una cadena de caracteres. Esta cadena puede ser recibida mediante el puerto serie RS232 de una PC usando un software de comunicación tal como la hiperterminal de windows y un cable de comunicación serie uno a uno (es decir, un cable sin intercambio interno de líneas).

;* Este programa envía repetidamente una cadena de caracteres a través ;* del puerto serie asíncrono USART, La cadena utiliza como terminador

;* un carácter "$". Se supone un oscilador a cristal Fosc=14.7456 Mhz

;************************************************************************

Include "p16f877.inc"

apun EQU 0x20

dato EQU 0x21

org 0x0000

trans BSF STATUS,RP0 ;banco 1

BCF TXSTA,BRGH ;pone bit BRGH=0 (velocidad baja)

MOVLW 0x17 ;valor para 9600 Bauds (Fosc=14.7456 Mhz)

MOVWF SPBRG ;configura 9600 Bauds BCF TXSTA,SYNC ;limpia bit SYNC (modo asíncrono)

BSF TXSTA,TXEN ;pone bit TXEN=1 (habilita transmisión) BCF STATUS,RP0 ;regresa al banco 0

Page 15: 4 El Puerto Serie USART V2 (1)

15

BSF RCSTA,SPEN ;pone bit SPEN=1 (habilita puerto serie)

rep CLRF apun ;inicializa apuntador

cic2 CALL letrero ;obtiene el siguiente carácter apuntado en W

MOVWF dato ;lo guarda en dato

SUBLW "$" ;Compara con el signo "$"

BTFSC STATUS,Z ;

GOTO rep ;si es, reinicia

CALL envia ;si no es "$" envía el dato

INCF apun,1 ;apunta al siguiente carácter

GOTO cic2 ;repite

;*************************************************

;Subrutina para enviar un dato por el puerto serie

;*************************************************

envia BSF STATUS,RP0 ;banco 1

esp BTFSS TXSTA,TRMT ;checa si el buffer de transmisión:

GOTO esp ;si está ocupado espera

BCF STATUS,RP0 ;regresa al banco 0

MOVF dato,W ;rescata dato a enviar

MOVWF TXREG ;lo envía

RETURN

letrero: MOVF apun,W ;carga apuntador en W

ADDWF PCL,1 ;Salta W instrucciones adelante

DT "HOLA MUNDO 14.756 Mhz",0x0D,0x0A,"$"

end

Análisis del código

En primer lugar configuramos los registros: Registro TXSTA

CSRC TX9 TXEN SYNC ---- BRGH TRMT TX9D 1 0 0

Bit 7 Bit 0 TXEN = 1, Habilita la transición SYNC = 0, Comunicación asincrónica BRGH = 0, velocidad de baja transmisión Registro SPBRG = 0x17

0 0 0 1 0 1 1 1

Bit 7 Bit 0 De la fórmula:

Baud rate = Fosc / (64(X+1)) 9,6x103 = 14,241x106 / (64 (X+1 )) X = 14,241x106 / 9,6x103 x 64 - 1 X = 23D X = 17H = SPBRG

Registro RCSTA

SPEN RX9 SREN CREN ---- FERR OERR RX9D 1

Bit 7 Bit 0

Page 16: 4 El Puerto Serie USART V2 (1)

16

ESPEN = 1, Habilita el puerto serie Programa principal. Toma cada carácter del mensaje y envía al puerto serie, repitiendo indefinidamente el envío del mensaje, el carácter a enviar se almacena en el registro dato. Para el control del envío de caracteres se utiliza las siguientes sentencias:

MOVWF dato

SUBLW "$"

BTFSC STATUS,Z

que realizan la comparación mediante la resta del dato con el carácter "$", activándose la bandera Z de STATUS de acuerdo a lo siguiente:

- resultado = 0 si los caracteres son iguales a "$", entonces Z=1 - resultado = 1 si los caracteres son diferentes, entonces Z=0

Subrutinas. Son dos: envio y letrero: envio. Para evitar pérdida de datos se chequea la bandera TRMT del registro TXSTA, la cual se activa cuando se culmina la transmisión, inserta un tiempo de espera y permanece un tiempo en 1. Luego de esto se envía el carácter al puerto. letrero. El registro apun comienza con el valor de 0 y cada vez se incrementa en 1, para sumarle con el contador de programa PCL, lo que permitirá acceder a cada carácter del mensaje, de acuerdo a la siguiente tabla. Memoria de

programa

PCL → H

O

L

A

M

U

N

D

O

1

4

.

7

5

6

M

H

Z

0x0D Retorno de carro

0x0A Cambio de línea

$ Fin de mensaje

Porque la sentencia:

DT "HOLA MUNDO 14.756 Mhz",0x0D,0x0A ,"$"

define una tabla de caracteres dentro de la memoria de programa y al ejecutarse termina la subrutina, retornando en el registro W el valor que está apuntando el registro PCL.

Page 17: 4 El Puerto Serie USART V2 (1)

17

c. El receptor asíncrono El módulo de recepción es similar al de transmisión, en la siguiente figura se muestran los bloques que lo constituyen. Una vez que se ha seleccionado el modo asíncrono, la recepción se habilita poniendo en alto el bit CREN (RCSTA<4>) El dato es recibido mediante la línea RC7/RX/DT, la cual maneja un registro de corrimiento de alta velocidad (16 veces el Baud rate). El corazón del receptor es el registro de corrimiento RSR. Este registro no es acesabel por software, pero, cuando el dato recibido se ha completado (se ha recibido el bit de Stop) el dato de RSR es transferido automáticamente al registro RCREG (1Ah) si éste está vacío y al mismo tiempo es puesto en alto la bandera de recepción RCIF (PIR1<5>). La única manera de limpiar la bandera RCIF es leyendo el los datos del registro RCREG. El registro RCREG puede contener hasta dos datos, ya que es un buffer doble que funciona como un cola de dos posiciones. Si las dos posiciones del registro RCREG están llenas (no han sido leídas) y se detecta el bit de Stop de un tercer dato de recepción, lo cual ocasiona un transferencia automática del dato recibido a RCREG, esto destruirá el primer dato recibido y activará el indicador de sobreescritura OERR (RCSTA<1>). Para evitar esto, se deberán leer los dos datos en RSREG haciendo dos lecturas consecutivas. La única manera de limpiar el bit OERR una vez que ha sido activado es reseteando el módulo de recepción (limpiando CREN y volviéndolo a poner), si no se limpia OERR se bloquea la transferencia de datos de RSR a RCREG y no puede haber más recepción de datos.

Diagrama de bloques de recepción de la USART

Si se detecta un bit nivel bajo en la posición del bit de stop se pone el indicador de error de encuadre (frame error) FERR RCSTA<2>. Tanto este indicador como el noveno bit RX9D de los datos están en una cola de dos posiciones al igual que los datos recibidos, de manera que al leer RCREG se actualizan FERR y RX9D con nuevos valores, por lo cual estos bits deberán ser leídos antes de leer RCREG para no perder su información.

Page 18: 4 El Puerto Serie USART V2 (1)

18

Registro de estado y Control RCSTA (Receptor)

R/W-0 R/W-0 R/W-0 R/W-0 U-0 R/W-0 R/W-0 R/W-0 SPEN RX9 SREN CREN ---- FERR OERR RX9D Bit 7 Bit 0

bit 7: SPEN: Bit de habilitación del puerto serie 1 = Habilita puerto serie (configura patillas RC7/RX/DT y RC6/TX/CK para el puerto serie)

0 = Deshabilita puerto serie bit 6: RX9: Habilita recepción de 9-8 bits 1 = Selecciona 9 bits de recepción 0 = Selecciona 8 bits de recepción bit 5: SREN: Bit de habilitación de recepción única Modo asíncrono Este modo no se usa Modo Síncrono master 1 = Habilita una recepción única 0 = Deshabilita una recepción única Este bit se borra después de completar la recepción Modo Síncrono esclavo En este modo no se usa bit 4: CREN: Bit de habilitación de recepción continua Modo Asíncrono 1 = Habilita recepción continua 0 = Deshabilita recepción continua Modo Síncrono 1 = Habilita recepción continua hasta que el bit CREN sea borrado (CREN anula SREN) 0 = Deshabilita la recepción continua bit 3: Sin implementar: En lectura es '0' bit 2: FERR: Bit de error de empaquetamiento 1 = Error de empaquetamiento (Puede actualizarse al leer el registro RCREG y recibir el

siguiente byte) 0 = No hay error bit 1: OERR: Bit de error de desbordamiento 1 = Error de desbordamiento (puede ser borrado al borrar CREN) 0 = No hay desbordamiento bit 0: RXGD: Noveno bit de datos de recepción. Se puede emplear como bit de paridad

De acuerdo a lo anterior, la inicialización del módulo de recepción es como sigue:

1. Inicializar el baud rate escribiendo al registro SPBRG el divisor adecuado y

Page 19: 4 El Puerto Serie USART V2 (1)

19

opcionalmente al bit BRGH . 2. Habilitar el puerto serie asíncrono limpiando el bit SYNC y poniendo el bit SPEN. 3. Si se van a usar interrupciones, poner el bit RCIE (PIE<5>). 4. Si se desea recepción de datos de 9 bits se deberá poner el bit RX9 (RCSTA<0>). 5. Habilitar la recepción poniendo el bit CREN (RCSTA<4>) 6. El bit RCIF se pondrá cuando la recepción de un dato se complete y se generará una

interrupción si RCIE está puesto. 7. Leer el registro RCSTA para obtener el noveno bit (si se están recibiendo datos de 9 bits) o

para determinar si ha ocurrido un error de recepción. 8. Leer los 8 bits del dato recibido leyendo el registro RCREG. 9. Si ocurrió algún error este se limpia al limpiar el bit CREN, el cual deberá volver a ponerse si

se desea continuar la recepción. Para ilustrar este procedimiento se presenta a continuación un ejemplo de transmisión de datos en modo asíncrono a través de la USART.

Ejemplo 2

Recepción asíncrona El siguiente programa recibe datos de manera asíncrona a través del la USART. Los datos recibidos son interpretados por el programa como cadenas de caracteres con un carácter de terminación retorno de carro <CR> (elegido arbitrariamente) cuyo código ASCII es un 0Dh. Los datos pueden ser enviados mediante el puerto serie RS232 de una PC usando un software de comunicación como la hiperterminal de windows y un cable de comunicación serie uno a uno.

El programa recibe la cadena de caracteres y la compara con la palabra clave “enciende” (también elegida arbitrariamente), de manera que solamente cuando la cadena recibida coincide con la palabra clave encenderá un Led conectado a la línea RC0 del puerto C. De lo contrario, (cuando reciba cualquier otra cadena) apagará el LED. Observación: En realidad, por el diseño del programa, cuando se reciba alguna subcadena inicial de la palabra clave “enciende” (incluyendo la subcadena vacía) el Led no cambia de estado.

;* Este programa recibe datos a través del puerto serie asíncrono USART ;* La cadena de caracteres recibidos deberá terminar con un carácter <CR> ;* Si la cadena recibida es "enciende" se encenderá un led conectado a RC0 ;* si no, se apagará. Se supone un oscilador Fosc=14.7456 Mhz ;************************************************************************

Include "p16f877.inc" apun EQU 0x20 dato EQU 0x21

org 0x0000 trans BSF STATUS,RP0 ;banco 1

BCF TRISC,0 ;pone RC0 como salida BCF TXSTA,BRGH ;pone bit BRGH=0 (velocidad baja) MOVLW 0x17 ;valor para configurar 9600 Bauds MOVWF SPBRG ;configura 9600 Bauds BCF TXSTA,SYNC ;limpia bit SYNC (modo asíncrono) BCF STATUS,RP0 ;regresa al banco 0 BSF RCSTA,SPEN ;pone bit SPEN=1 (habilita puerto serie) BSF RCSTA,CREN ;Habilita recepción

ciclo CLRF apun ;inicializa apuntador

Page 20: 4 El Puerto Serie USART V2 (1)

20

sig CALL recibe ;recibe un caracter del puerto serie, ;(dato recibido está en el registro dato)

MOVLW 0x0D ;carga caracter de fin de cadena SUBWF dato,W ;compara

BTFSC STATUS,Z ;ya es fin de cadena?

GOTO longi ;si es, checa longitud de cadena recibida ;(Fin de la cadena ”enciende”)

CALL letrero ;si no es, obtiene un caracter a comparar SUBWF dato,W ;son iguales?

BTFSS STATUS,Z ;(caracteres iguales)

;si los caracteres son iguales o no

GOTO noes ;si no son iguales sale del ciclo INCF apun,1 ;si son iguales incrementa apuntador

GOTO sig ;repite para el siguiente carácter

longi MOVLW 0x08 ;carga longitud de la palabra clave SUBWF apun,W ;compara con número de caracteres iguales

BTFSC STATUS,Z ;(tamano de 8 caracteres)

BSF PORTC,0 ;si coincide Enciende Led GOTO ciclo ;si no reinicia ciclo

;solo si recibe toda la cadena del puerto

noes CALL recibe ;recibe un caracter del puerto serie MOVLW 0x0D ;carga caracter de fin de cadena SUBWF dato,W ;compara BTFSC STATUS,Z ;ya es fin de cadena? GOTO apaga ;si es, apaga led GOTO noes ;si no es, repite

apaga BCF PORTC,0 ;apaga el Led GOTO ciclo ;regresa a esperar nueva cadena

;************************************************** ;subrutina de recepción de un dato del puerto serie ;************************************************** recibe BTFSS PIR1,RCIF ;checa el buffer de recepción

GOTO recibe ;si no hay dato listo espera MOVF RCREG,W ;si hay dato, lo lee MOVWF dato ;lo almacena en dato RETURN

letrero: MOVF apun,W ;carga apuntador en W ADDWF PCL,1 ;Salta W instrucciones adelante DT "enciende" end

Análisis del código

En primer lugar configuramos los registros: El registro SPBRG es igual que en el ejemplo anterior de transmisión. Registro RCSTA

SPEN RX9 SREN CREN ---- FERR OERR RX9D 1 1

Bit 7 Bit 0

Page 21: 4 El Puerto Serie USART V2 (1)

21

ESPEN = 1, Habilita el puerto serie CREN = 1, Habilita la recepción contínua Programa principal. Este programa recibe un caracter del puerto serie con la subrutina recibe, el dato recibido está en el registro dato. Las siguientes sentencias determinan si ya es fin de cadena recibida del puerto serie, con el carácter 0x0D:

MOVLW 0x0D

SUBWF dato,W

BTFSC STATUS,Z

Si no es fin de cadena, obtiene un caracter a comparar ¿Si son iguales?,

CALL letrero

SUBWF dato,W

BTFSS STATUS,Z

Si los caracteres no son iguales sale del ciclo y si son iguales incrementa apuntador apun; repitiendo para el siguiente carácter. Si es fin de cadena, checa longitud de cadena recibida, es decir, fin de la cadena ”enciende”; carga longitud de la palabra clave y compara con número de caracteres iguales (tamano de 8 caracteres),

longi MOVLW 0x08

SUBWF apun,W

BTFSC STATUS,Z

Si coincide longitud de cadena, solo si recibe toda la cadena del puerto, enciende el Led , si no reinicia ciclo. Subrutinas. Son dos: recibe y letrero: recibe. Checa el buffer de recepción con la bandera RCIF del registro PIR1, si no hay dato listo espera, caso contrario, si hay dato lo lee; almacenándole en el registro dato. letrero. Es idéntico al ejemplo anterior de transmisión, con la única diferencia que el mensaje es “enciende”. Ejemplo 3. Transmisión / Recepción Simultánea El siguiente programa ilustra la capacidad full duplex que posee la USART del PIC que le permite realizar simultáneamente la transmisión y recepción de datos. La tarea que realiza el programa es muy simple, solamente hace el eco del carácter recibido, es decir, conforme recibe un carácter del puerto serie, lo regresa sin cambio por el mismo puerto. El proceso se detiene cuando el carácter recibido es un <Esc> o código ASCII 1Bh (elegido arbitrariamente)

;* Este programa recibe un carácter por el puerto serie asíncrono USART ;* y lo regresa tal cual por el mismo puerto, hasta recibir un <esc> ;* Se supone un oscilador a cristal Fosc=14.7456 Mhz ;************************************************************************

Include "p16f877.inc" dato EQU 0x20

Page 22: 4 El Puerto Serie USART V2 (1)

22

org 0x0000 trans BSF STATUS,RP0 ;banco 1

BCF TXSTA,BRGH ;pone bit BRGH=0 (velocidad baja) MOVLW 0x17 ;valor para 9600 Bauds (Fosc=14.7456 Mhz) MOVWF SPBRG ;configura 9600 Bauds BCF TXSTA,SYNC ;limpia bit SYNC (modo asíncrono) BSF TXSTA,TXEN ;pone bit TXEN=1 (habilita transmisión) BCF STATUS,RP0 ;regresa al banco 0 BSF RCSTA,SPEN ;pone bit SPEN=1 (habilita puerto serie) BSF RCSTA,CREN ;Habilita recepción

rep CALL recibe ;recibe dato

MOVLW 0x1B ;carga código ASCII de <escape> SUBWF dato,W ;es igual? BTFSC STATUS,Z ; GOTO fin ;si es igual termina CALL envia ;si n, retransmite el dato GOTO rep ;repite

fin GOTO fin ;ciclo infinito ;************************************************* ;Subrutina para enviar un dato por el puerto serie ;************************************************* envia BSF STATUS,RP0 ;banco 1 esp BTFSS TXSTA,TRMT ;checa si el buffer de transmisión

GOTO esp ;si está ocupado espera BCF STATUS,RP0 ;regresa al banco 0 MOVF dato,W ;rescata dato a enviar MOVWF TXREG ;lo envía RETURN

;************************************************** ;subrutina de recepción de un dato del puerto serie ;************************************************** recibe BTFSS PIR1,RCIF ;checa el buffer de recepción

GOTO recibe ;si no hay dato listo espera MOVF RCREG,W ;si hay dato, lo lee MOVWF dato ;lo almacena en dato RETURN end

Ejemplo 4

Ejemplo de aplicación El ejemplo de aplicación consiste en ver cómo recibir y transmitir datos por el PIC16F877, conectando el circuito al PC y el circuito provisto de alimentación. En el LCD aparecerá el cursor de destello arriba a la izquierda. A esto se lanza en ejecución un programa cualquiera de emulación terminal y se configura el puerto serial para que se conecte el circuito a 9600 baudios, 8 datos por bit, 1 bit de parada y ninguna paridad, asegurándose de que no se encuentre habilitado algún control de flujo de datos seriales en el hardware de xon/xoff. También, al pulsar alguna tecla en el teclado del PC los caracteres digitales también se visualizan en el LCD del circuito. Es decir, este circuito visualiza en el display los caracteres ASCII transmitidos desde la PC por uno de los puertos serie, a través de un emulador de terminal tipo Hyperterminal (Windows 95/98), Telix (MS DOS), o Minicon (Linux). Por último, pulsando las teclas CTRL-L se puede limpiar el LCD y visualizar nuevas escrituras.

Page 23: 4 El Puerto Serie USART V2 (1)

23

El circuito gestiona un LCD, al cual se agrega la RS232 que es el integrado MAX232, del conector DB9 para la conexión al puerto serie del PC y algunos componentes. El circuito descrito se presenta a continuación:

;**************************************************

;

; LCDTERM.ASM

;

;**************************************************

PROCESSOR 16F877

RADIX DEC

INCLUDE "P16F877.INC"

__CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF

ORG 20H

;**********************************************************************

; FILE REGISTER

;**********************************************************************

;Register used by LCD subroutines

tmpLcdRegister RES 2

;Register used by msDelay subroutine

msDelayCounter RES 2

;Register used by RS232 subroutines

dato RES 1 ;data register

Page 24: 4 El Puerto Serie USART V2 (1)

24

;Cursor location

xCurPos RES 1 yCurPos RES 1

putTempReg RES 1

;LCD Control lines

LCD_RS equ 2 ;Register Select

LCD_E equ 3 ;Enable

;LCD data line bus

LCD_DB4 equ 4 ;LCD data line DB4

LCD_DB5 equ 5 ;LCD data line DB5

LCD_DB6 equ 6 ;LCD data line DB6

LCD_DB7 equ 7 ;LCD data line DB7

;Reset Vector

;**********************************************************************

; RESET VECTOR

;**********************************************************************

; ORG 00H

Start

bsf STATUS,RP0 ;Swap to register bank 1

movlw 11111111B ;Sets the whole PORTB as input

movwf TRISB

bcf PORTB,LCD_DB4 ;Sets LCD data and control lines as ;output

bcf PORTB,LCD_DB5

bcf PORTB,LCD_DB6

bcf PORTB,LCD_DB7

bcf PORTB,LCD_E

bcf PORTB,LCD_RS

bcf STATUS,RP0 ;cambio a banco 0

;LCD inizialization

call LcdInit

;Put terminal cursor on 0,0 position

clrf xCurPos

clrf yCurPos

;Star Send and Receive on RS232

call IniTrans

MainLoop

call RxChar ;read the byte on receiving...

CheckFormFeed

movlw 12

xorwf dato,W

btfss STATUS,Z goto _CheckFormFeed

clrf xCurPos

clrf yCurPos

call LcdClear

goto MainLoop

_CheckFormFeed

movf dato,W

call putchar

goto MainLoop

Page 25: 4 El Puerto Serie USART V2 (1)

25

;**********************************************************************

; Delay subroutine

; ; W = Requested delay time in ms (clock = 4MHz)

;**********************************************************************

msDelay

movwf msDelayCounter+1

clrf msDelayCounter+0

; 1 ms (about) internal loop

msDelayLoop

nop

decfsz msDelayCounter+0,F

goto msDelayLoop

nop

decfsz msDelayCounter+1,F

goto msDelayLoop

return

;**********************************************************************

; Put a char to xCurPos, yCurPos position on LCD

;

; W = Char to show

; xCurPos = x position

; yCurPos = y position

; ; xCurPos and yCurPos will be increase automaticaly

;**********************************************************************

putchar

movwf putTempReg

swapf yCurPos,W

iorwf xCurPos,W

call LcdLocate

movf putTempReg,W

call LcdSendData

incf xCurPos,F

movlw 16

xorwf xCurPos,W

btfss STATUS,Z

goto moveLcdCursor

clrf xCurPos

incf yCurPos,F

movlw 2

xorwf yCurPos,W

btfss STATUS,Z

goto moveLcdCursor

clrf yCurPos

moveLcdCursor

swapf yCurPos,W

iorwf xCurPos,W

call LcdLocate

return

;**********************************************************************

; Init LCD

; This subroutine must be called before each other lcd subroutine

;**********************************************************************

Page 26: 4 El Puerto Serie USART V2 (1)

26

LcdInit

movlw 30 ;Wait 30 ms

call msDelay

;****************

; Reset sequence

;****************

bcf PORTB,LCD_RS ;Set LCD command mode

;Send a reset sequence to LCD

bsf PORTB,LCD_DB4

bsf PORTB,LCD_DB5

bcf PORTB,LCD_DB6

bcf PORTB,LCD_DB7

bsf PORTB,LCD_E ;Enables LCD

movlw 5 ;Wait 5 ms

call msDelay

bcf PORTB,LCD_E ;Disables LCD

movlw 1 ;Wait 1ms

call msDelay

bsf PORTB,LCD_E ;Enables LCD

movlw 1 ;Wait 1ms

call msDelay

bcf PORTB,LCD_E ;Disables LCD movlw 1 ;Wait 1ms

call msDelay

bsf PORTB,LCD_E ;Enables E

movlw 1 ;Wait 1ms

call msDelay

bcf PORTB,LCD_E ;Disables E

movlw 1 ;Wait 1ms

call msDelay

bcf PORTB,LCD_DB4

bsf PORTB,LCD_DB5

bcf PORTB,LCD_DB6

bcf PORTB,LCD_DB7

bsf PORTB,LCD_E ;Enables LCD

movlw 1 ;Wait 1ms

call msDelay

bcf PORTB,LCD_E ;Disabled LCD

movlw 1 ;Wait 1ms

call msDelay

;Set 4 bit data bus length

movlw 28H;

call LcdSendCommand

;Entry mode set, increment, no shift

movlw 06H;

call LcdSendCommand

;Display ON, Curson ON, Blink OFF

movlw 0EH

call LcdSendCommand

;Clear display

Page 27: 4 El Puerto Serie USART V2 (1)

27

call LcdClear

return

;**********************************************************************

; Clear LCD

;**********************************************************************

LcdClear

;Clear display

movlw 01H

call LcdSendCommand

movlw 2 ;Wait 2 ms

call msDelay

;DD RAM address set 1st digit

movlw 80H;

call LcdSendCommand

return

;**********************************************************************

; Locate cursor on LCD

; W = D7-D4 row, D3-D0 col

;**********************************************************************

LcdLocate movwf tmpLcdRegister+0

movlw 80H

movwf tmpLcdRegister+1

movf tmpLcdRegister+0,W

andlw 0FH

iorwf tmpLcdRegister+1,F

btfsc tmpLcdRegister+0,4

bsf tmpLcdRegister+1,6

movf tmpLcdRegister+1,W

call LcdSendCommand

return

;**********************************************************************

; Send a data to LCD

;**********************************************************************

LcdSendData

bsf PORTB,LCD_RS

call LcdSendByte

return

;********************************************************************** ; Send a command to LCD

;**********************************************************************

LcdSendCommand

bcf PORTB,LCD_RS

call LcdSendByte

return

;**********************************************************************

; Send a byte to LCD by 4 bit data bus

;**********************************************************************

LcdSendByte

;Save value to send

Page 28: 4 El Puerto Serie USART V2 (1)

28

movwf tmpLcdRegister

;Send highter four bits

bcf PORTB,LCD_DB4

bcf PORTB,LCD_DB5

bcf PORTB,LCD_DB6

bcf PORTB,LCD_DB7

btfsc tmpLcdRegister,4

bsf PORTB,LCD_DB4

btfsc tmpLcdRegister,5

bsf PORTB,LCD_DB5

btfsc tmpLcdRegister,6

bsf PORTB,LCD_DB6

btfsc tmpLcdRegister,7

bsf PORTB,LCD_DB7

bsf PORTB,LCD_E ;Enables LCD

movlw 1 ;Wait 1ms

call msDelay

bcf PORTB,LCD_E ;Disabled LCD

movlw 1 ;Wait 1ms

call msDelay

;Send lower four bits

bcf PORTB,LCD_DB4 bcf PORTB,LCD_DB5

bcf PORTB,LCD_DB6

bcf PORTB,LCD_DB7

btfsc tmpLcdRegister,0

bsf PORTB,LCD_DB4

btfsc tmpLcdRegister,1

bsf PORTB,LCD_DB5

btfsc tmpLcdRegister,2

bsf PORTB,LCD_DB6

btfsc tmpLcdRegister,3

bsf PORTB,LCD_DB7

bsf PORTB,LCD_E ;Enables LCD

movlw 1 ;Wait 1ms

call msDelay

bcf PORTB,LCD_E ;Disabled LCD

movlw 1 ;Wait 1ms

call msDelay

return

;**************************************************************************

; Star Send and Receive on RS232

; (9600 baud,8 data bit, 1 stop bit, No parity)

; ;**************************************************************************

IniTrans

BCF STATUS,RP1

BSF STATUS,RP0 ;banco 1

BSF TXSTA,BRGH ;pone bit BRGH=1 (velocidad alta)

MOVLW 0x19 ;valor para 9600 Bauds (Fosc=4 Mhz)

MOVWF SPBRG ;configura 9600 Bauds

BCF TXSTA,SYNC ;limpia bit SYNC (modo asíncrono)

BSF TXSTA,TXEN ;pone bit TXEN=1 (habilita transmisión)

BCF STATUS,RP0 ;regresa al banco 0

BSF RCSTA,SPEN ;pone bit SPEN=1 (habilita puerto serie)

BSF RCSTA,CREN ;Habilita recepción

Page 29: 4 El Puerto Serie USART V2 (1)

29

return

;************************************************************************** ; Receive a character from RS232

; (9600 baud,8 data bit, 1 stop bit, No parity)

;

; dato: Received character

;**************************************************************************

RxChar

recibe BTFSS PIR1,RCIF ;checa el buffer de recepción

GOTO recibe ;si no hay dato listo espera

MOVF RCREG,W ;si hay dato, lo lee

MOVWF dato ;lo almacena en dato

return

END

Análisis del código LCDTERM.ASM

Realmente en esta aplicación no viene aún usada la línea de transmisión en cuánto que el miniterminal es ahora capaz sólo para recibir caracteres. La subrutina de recepción de caracteres por medio de RS232 es RxChar. Esta subrutina pone en práctica la recepción de un byte en modo serial asíncrono a 9600 bps, 8 bits de datos, 1 bit de parada y cualquier paridad Para recibir caracteres. Solo se debe llamar a la rutina RxChar y el dato es recibido en el registro dato:

call RxChar

Una vez que leyó el byte proveniente del PC el programa de ejemplo verifica si el byte recibido es un carácter de mando o un carácter normal para visualizar en LCD. El único carácter de control implementado por el miniterminal es la Form Feed (FF) correspondiente al código ASCII 12 decimal. La transmisión de este carácter hacia una impresora determina el avance de una hoja de papel. En este caso limpia el contenido del LCD. La Form Feed puede transmitirse del simulador del terminal del PC pulsando la tecla CTRL seguido de la letra L. Ésta es la parte de código que maneja la recepción de un Form Feed: CheckFormFeed movlw 12

xorwf dato,W btfss STATUS,Z

goto _CheckFormFeed

clrf xCurPos

clrf yCurPos

call LcdClear

goto MainLoop _CheckFormFeed

en la práctica se verifica si el valor recibido por la subrutina RxChar es igual a 12. En caso afirmativo se restauran el registro xCurPos y yCurPos que mantienen los valor X,Y del carácter del cursor del

Page 30: 4 El Puerto Serie USART V2 (1)

30

display LCD. En este momento se hace una llamada a la subrutina LcdClear que se ocupa de enviar el comando correcto al display LCD para desplegar su contenido. En el caso que no haya sido transmito un FF del PC, el carácter recibido se envía desnudo y crudo al display con el siguiente código:

movf dato,W call putchar

y por consiguiente se toma se repite para recibir el próximo carácter, con la siguiente instrucción:

goto MainLoop

La subrutina putchar en práctica envía el valor contenido en el registro W al display LCD en la posición en la que se encuentra el cursor del carácter (xCurPos y yCurPos), por consiguiente se ocupa de enviar al cursor una cabecera si se alcanza la línea de la meta o para traer la primera línea si se alcanza el display. En todos los casos los registros xCurPos y yCurPos se aplazan a la próxima posición para que sea capaz de escribir el siguiente carácter enviado por el PC.

Ejercicio 5

Otro ejemplo de aplicación con la interfase RS232

En este caso, se realiza un circuito que a través de la subrutina TxChar, también pueda transmitir datos.

Se trata de un circuito con cuatro LED’s y cuatro switches, dotado de la interfaz RS232 para poder comandar los LED’s y leer desde la PC, el estado de los switches.

El circuito a ser realizado se presenta a continuación:

Page 31: 4 El Puerto Serie USART V2 (1)

31

1. Protocolo de comunicación con la PC

El circuito está dotado de 4 LED’s denominados LED1, LED2, LED3, LED4 y cuatro pulsadores denominados SWITCH1, SWITCH2, SWITCH3, Y SWITCH4.

A través de un simple protocolo se puede decidir cuál de los LED’s encender o leer el estado de cualquiera de los pulsadores.

El protocolo consiste en una serie de códigos de control que la PC puede transmitir al circuito por el puerto serie. La velocidad de transferencia es 9600 baud, 8 bit de datos, 1 stop bit, sin paridad.

2. Comandos de encendido de los LED

Se puede encender un LED cada vez, enviando desde la PC los siguientes comandos:

00h Enciende LED 1

01h Enciende LED 2

Page 32: 4 El Puerto Serie USART V2 (1)

32

02h Enciende LED 3

03h Enciende LED4

3. Comandos para el apagado de los LED

Se puede apagar los LED’s enviando desde la PC los siguientes comandos:

04h Apaga LED 1

05h Apaga LED 2

06h Apaga LED 3

07h Apaga LED 4

4. Lectura del estado de los pulsadores

Para leer el estado de los cuatro pulsadores basta enviar un único comando:

08h Lectura del estado de los pulsadores

Cuando la PC recibe este comando lee el estado de los bit’s RB4, RB5, RB6 y RB7 y envía un único código al PC que refleja el estado de los cuatro pulsadores. De este código, solo los bit’s 0, 1, 2, y 3 indican:

BIT 0 SWITCH1 = 0 sin presionar, SWITCH1= 1 oprimido

BIT 1 SWITCH2 = 0 sin presionar, SWITCH2= 1 oprimido

BIT 2 SWITCH3 = 0 sin presionar, SWITCH3= 1 oprimido

BIT 3 SWITCH4 = 0 sin presionar, SWITCH4= 1 oprimido

Por ejemplo, si es oprimido solo el pulsador 1, el código de respuesta será 01h (00000001 binario). Si resultan oprimidos el 2 y el 4, el código será 0Ah (00001010 binario)

5. Programa de prueba

Para quienes no disponen del compilador MPASM, con el programa de prueba RS232IO.EXE de

Microchip (o cualquier otro) permitirá probar el circuito inmediatamente. El programa funciona en ambiente DOS o promt MS/DOS bajo Win 95/98.

Supóngase haber conectado el circuito al COM2, para encender el LED1, será suficiente digitar:

RS232IO /COM2 /LED1=ON

Si ahora, se quiere apagar el LED 1 y encender el 4, se digita:

RS232IO /COM2 /LED1=OFF /LED4=ON

Si se quiere encender el LED3 sin modificar el estado de los otros, se hace:

Page 33: 4 El Puerto Serie USART V2 (1)

33

RS232IO /COM2 /LED3=ON

Para leer el estado de los switches:

RS232IO /COM2 /SWITCH

Para leer el estado de los switches:

Switch 1: off

Switch 2: off

Switch 3: ---> Active

Switch 4: off

Indicando que solamente el switch 3 está pulsado.

El código de este ejemplo está disponible en RS232IO.ASM y se muestra a continuación:

;**************************************************

;

; RS232IO.ASM

;

;**************************************************

PROCESSOR 16F877

RADIX DEC

INCLUDE "P16F877.INC"

__CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF

ORG 20H

;**********************************************************************

; FILE REGISTER

;**********************************************************************

;Register used by msDelay subroutine

msDelayCounter res 2

;Register used by RS232 subroutines

dato res 1 ;dato register

;I/O lines on PORTB

LED1 equ 0

LED2 equ 1

LED3 equ 2

LED4 equ 3

SWITCH1 equ 4

SWITCH2 equ 5 SWITCH3 equ 6

SWITCH4 equ 7

;Command code from PC

LED1_ON equ 00h

LED2_ON equ 01h

LED3_ON equ 02h

LED4_ON equ 03h

LED1_OFF equ 04h

LED2_OFF equ 05h

LED3_OFF equ 06h

LED4_OFF equ 07h

GET_SWITCH equ 08h

Page 34: 4 El Puerto Serie USART V2 (1)

34

;**********************************************************************

; RESET VECTOR ;**********************************************************************

; ORG 00H

Start

bsf STATUS,RP0 ;Swap to register bank 1

movlw 11110000B ;Sets the whole PORTB as input y output

movwf TRISB

bcf STATUS,RP0 ;Swap to register bank 0

bcf PORTB,LED1 ;Turn off each leds

bcf PORTB,LED2

bcf PORTB,LED3

bcf PORTB,LED4

;Star Send and Receive on RS232

CALL IniTrans ;inicializa el puerto serie para transmisión

MainLoop

call RxChar ;read the byte on receiving...

movlw 0x30 ;valor del ASCII de '0'

subwf dato,1 ;cambia el dato de ASCII a número

;*********************** ; Check for PC commands

;***********************

;***********************

; LED1_ON

;***********************

Led1On

movlw LED1_ON

xorwf dato,W

btfss STATUS,Z

goto _Led1On

bsf PORTB,LED1

goto MainLoop

_Led1On

;***********************

; LED2_ON

;***********************

Led2On

movlw LED2_ON

xorwf dato,W

btfss STATUS,Z

goto _Led2On

bsf PORTB,LED2

goto MainLoop

_Led2On

;***********************

; LED3_ON

;***********************

Led3On

movlw LED3_ON

xorwf dato,W

btfss STATUS,Z

goto _Led3On

Page 35: 4 El Puerto Serie USART V2 (1)

35

bsf PORTB,LED3

goto MainLoop

_Led3On

;***********************

; LED4_ON

;***********************

Led4On

movlw LED4_ON

xorwf dato,W

btfss STATUS,Z

goto _Led4On

bsf PORTB,LED4

goto MainLoop

_Led4On

;***********************

; LED1_OFF

;***********************

Led1Off

movlw LED1_OFF

xorwf dato,W

btfss STATUS,Z

goto _Led1Off

bcf PORTB,LED1

goto MainLoop

_Led1Off

;***********************

; LED2_OFF

;***********************

Led2Off

movlw LED2_OFF

xorwf dato,W

btfss STATUS,Z

goto _Led2Off

bcf PORTB,LED2

goto MainLoop

_Led2Off

;***********************

; LED3_OFF

;***********************

Led3Off

movlw LED3_OFF

xorwf dato,W btfss STATUS,Z

goto _Led3Off

bcf PORTB,LED3

goto MainLoop

_Led3Off

;***********************

; LED4_OFF

;***********************

Led4Off

movlw LED4_OFF

Page 36: 4 El Puerto Serie USART V2 (1)

36

xorwf dato,W

btfss STATUS,Z

goto _Led4Off

bcf PORTB,LED4

goto MainLoop

_Led4Off

;***********************

; GET_SWITCH

;***********************

GetSwitch

movlw GET_SWITCH

xorwf dato,W

btfss STATUS,Z

goto _GetSwitch

swapf PORTB,W ;Read the switch state and send

movwf dato

movlw 0x0F ;mascara 00001111

andwf dato,1

call TxChar ;envía el código de switches

MOVLW 0x0D ;carga carácter <CR>

CALL envia ;lo envía

MOVLW 0x0A ;carga carácter <LF>

CALL envia ;lo envía

goto MainLoop

_GetSwitch

goto MainLoop

;****************************************************************

;Subrutina para inicializar el puerto serie USART como transmisor

;a 9600 Bauds, considerando un cristal de reloj de 14.7456 MHZ

;****************************************************************

IniTrans:

BCF STATUS,RP1

BSF STATUS,RP0 ;banco 1

BSF TXSTA,BRGH ;pone bit BRGH=1 (velocidad alta)

MOVLW 0x19 ;valor para 9600 Bauds (Fosc=14.7456 Mhz)

MOVWF SPBRG ;configura 9600 Bauds

BCF TXSTA,SYNC ;limpia bit SYNC (modo asíncrono)

BSF TXSTA,TXEN ;pone bit TXEN=1 (habilita transmisión)

BCF STATUS,RP0 ;regresa al banco 0

BSF RCSTA,SPEN ;pone bit SPEN=1 (habilita puerto serie)

BSF RCSTA,CREN ;Habilita recepción

RETURN

;**************************************************************************

; Send a character from RS232 ; (9600 baud,8 data bit, 1 stop bit, No parity)

; Separado en los códigos ASCII de sus dos nibbles hexadecimales

; dato: Send character

;**************************************************************************

msnib EQU 0x24

lsnib EQU 0x25

TxChar:

MOVF dato,W

MOVWF msnib ;pone byte en msnib

MOVWF lsnib ;y una copia en lsnib

SWAPF msnib,1 ;intercambia nibbles en lsnib

MOVLW 0x0F ;máscara para limpiar el nibble alto

ANDWF msnib,1 ;limpia parte alta de msnib

Page 37: 4 El Puerto Serie USART V2 (1)

37

ANDWF lsnib,1 ;limpia parte alta de lsnib

MOVF msnib,W ;carga msnib en W

CALL asc ;obtiene código ASCII equivalente CALL envia ;lo envía por el puerto serie

MOVF lsnib,W ;carga lsnib en W

CALL asc ;obtiene código ASCII equivalente

CALL envia ;lo envía por el puerto serie

RETURN

Asc ADDWF PCL,1 ;Calcula el código a retornar

;Saltando W instrucciones adelante

DT "0123456789ABCDEF"

;***************************************************************

;Subrutina para enviar el byte guardado en W por el puerto serie

;***************************************************************

envia BSF STATUS,RP0 ;banco 1

esp BTFSS TXSTA,TRMT ;checa si el buffer de transmisión

GOTO esp ;si está ocupado espera

BCF STATUS,RP0 ;regresa al banco 0

MOVWF TXREG ;envía dato guardado en W

RETURN

;**************************************************************************

; Receive a character from RS232

; (9600 baud,8 data bit, 1 stop bit, No parity) ;

; dato: Received character

;**************************************************************************

RxChar

recibe BTFSS PIR1,RCIF ;checa el buffer de recepción

GOTO recibe ;si no hay dato listo espera

MOVF RCREG,W ;si hay dato, lo lee

MOVWF dato ;lo almacena en dato

return

END

Análisis del código RS232IO.ASM

Las subrutinas de transmisión y recepción de caracteres por medio de RS232 son: TxChar y RxChar. Estas dos subrutinas ponen en práctica la transmisión y recepción de un byte en modo serial asíncrono a 9600 bps, 8 bits de datos, 1 bit de parada y cualquier paridad Para transmitir un carácter en la línea TX. Basta ingresar en el registro W el valor para transmitir y efectuar una llamada a la subrutina TxChar. Suponiendo que para querer transmitir el carácter 'A' al PC nosotros debemos insertar el código siguiente:

movlw 'A' movwf dato call TxChar

Para recibir caracteres. Solo se debe llamar a la rutina RxChar y el dato es recibido en el registro dato:

call RxChar

El programa funciona de acuerdo al enunciado.

Page 38: 4 El Puerto Serie USART V2 (1)

38

1.3.2. Modo síncrono Este modo de trabajo tiene dos posibles formas de configuración, como master y como esclavo. En el modo master la transmisión y recepción no tienen lugar al mismo tiempo, cuando se transmite un dato, la recepción es inhibida y viceversa. En la transmisión el registro de desplazamiento, TSR

(Transmit Shift Register), obtiene los datos del registro de lectura/escritura TXREG, pero éste no se carga hasta que el último bit de la anterior carga no haya sido transmitido; cuando esto suceda el TSR se vuelve a cargar con el nuevo dato del registro TXREG (si está disponible) éste se vacía y se genera una interrupción (si está habilitada por el bit TXIE, PIE1<4>. La transmisión se habilita por el bit TXEN del registro TXSTA<5>, si se borra durante una transmisión, ésta será abortada y reseteado el transmisor. Para iniciar una transmisión es necesario seguir los siguientes pasos:

1. Inicializar el registro SPBRG con el valor apropiado calculado. 2. Habilitar el puerto master asíncrono colocando a uno los bits SYN, SPEN y CSRC. 3. Si se desea emplear la interrupción, habilitarla poniendo a uno el bit TXIE. 4. Si se desea una transmisión de nueve bits, el noveno se cargar en el bit TX9. 5. Habilitar la transmisión poniendo a uno el bit TXEN. 6. Si se ha habilitado la transmisión de 9 bits, el noveno se cargar en el registro TX9D. 7. La transmisión se iniciar al cargar los datos en el registro TXREG.

Para seleccionar el modo receptor master hay que poner a uno el bit SREN (RCSTA<5> o habilitar el CREN (RCSTA<4>). El dato es tomado de la patilla RC7/WDT por cada flanco de caída del reloj , si el bit SREN está a uno, sólo se recibir una palabra, pero si se borra el bit CREN la recepción ser continua. Después del último impulso de reloj, el dato recibido en el registro de desplazamiento RSR será transferido al RCREG (si está vacío). Una vez haya terminado la recepción se originar una interrupción si ésta está habilitada, RCIE (PIE1 <5>). Los pasos a seguir para iniciar la recepción en modo master son las siguientes:

1. Inicializar el registro SPBRG con el valor apropiado de baudios. 2. Habilitar el puerto master asíncrono colocando a uno los bits SYN, SPEN y CSRC. 3. Asegurarse de que los bits CREN y SREN están borrados. 4. Si se desea emplear la interrupción habilitarla poniendo a uno el bit RCIE. 5. Si se desean nueve bits poner a uno el bit RX9. 6. Si sólo se desea una recepción única, poner a uno el bit SREN; para recepción continua poner a

uno el bit CREN. 7. El flag de interrupción RCIF se pone a uno cuando la recepción haya finalizado si está

habilitada por el bit RCIE. 8. Leer el registro RCSTA y cargar el noveno bit (si está habilitado) y comprobar si ha ocurrido

un error durante la recepción. 9. Leer el octavo bit recibido y dar lectura al registro RCREG. 10. Si ha ocurrido un error borrarlo poniendo a cero el bit CREN.

Registros de Sincronización en modo master en transmisión

Dirección Nombre Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Valor en

POR,BOR Valor en el

resto de Reset

Page 39: 4 El Puerto Serie USART V2 (1)

39

0Ch PIR1 PSPIF(1) ADIF RCIF TXIF SSPIF CCP1IF TMREIF TMR1IF 0000 0000 0000 0000

18h RCSTA SPEN RX9 SREN CREN ADDEN FERR OERR RX9D 0000 000X 0000 000X

1Ah RCGEG Registro Receptor USAR 0000 0000 0000 0000

8Ch PIE1 PSPIE ADIE RCIE TXIE SSPIE CCP1IE TMR2IE TMR1IE 0000 0000 0000 0000

98h TXSTA CSRC TX9 TXEN SYNC --- BRGH TRMT TX9D 0000 –010 0000 –010

99h SPGBRG Registro generador de Baud Rate

Leyenda. x = desconocido u= sin cambios - = Sin implementar, se lee “0” 1.3.3. Modo esclavo síncrono Este modo de trabajo difiere del modo master, pues la señal de reloj de desplazamientos es proporcionada externamente por la patilla RC6/TX/CK en lugar de ser generada internamente, esto permite que se puedan transferir o recibir datos cuando el dispositivo está en el modo Sleep. Las operaciones de transmisión son idénticas al modo master, excepto en el caso del modo Sleep. Si se escriben dos palabras en el registro TXREG y después se ejecuta la instrucción Sleep, ocurrir lo siguiente:

1. La primera palabra será inmediatamente transferida al registro TSR y transmitida. 2. La segunda palabra permanecer en el registro TXREG. 3. El bit TXIF no se pondrá a uno. 4. Cuando la primera palabra haya salido del registro TSR, la segunda palabra, que permanece en

el registro TXREG, se enviar al TSR y el bit bandera TXIF subir a uno. 5. Si está habilitado el bit TXIF la interrupción despertar al microcontrolador de Sleep y el

programa saltar a la dirección del vector de interrupciones (0004 hex.).

Registros de Sincronización en modo master en recepción Dirección Nombre Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Valor en

POR,BOR Valor en el

resto de Reset

0Ch PIR1 PSPIF(1) ADIF RCIF TXIF SSPIF CCP1IF TMREIF TMR1IF 0000 0000 0000 0000

18h RCSTA SPEN RX9 SREN CREN ADDEN FERR OERR RX9D 0000 000X 0000 000X

1Ah RCGEG Registro Receptor USAR 0000 0000 0000 0000

8Ch PIE1 PSPIE ADIE RCIE TXIE SSPIE CCP1IE TMR2IE TMR1IE 0000 0000 0000 0000

98h TXSTA CSRC TX9 TXEN SYNC --- BRGH TRMT TX9D 0000 –010 0000 –010

99h SPGBRG Registro generador de Baud Rate

Leyenda. x = desconocido u= sin cambios - = Sin implementar, se lee “0”