Notas sobre el Modo Asíncrono en la USART
de los PIC 16F87X
Por Marcelo Valdéz - Córdoba, Argentina
-
marzzelo@yahoo.com
| IMPORTANTE: Estas
notas han sido creadas como material de estudio y consulta para mi uso personal.
Recomiendo leer los manuales de usuario y notas técnicas oficiales
correspondientes paralelamente a estas notas. Pueden encontrar estos manuales
en www.microchip.com |
El módulo asíncrono consta de los siguientes cuatro
elementos:
-
Generador de Baud Rate
-
Circuito de Muestreo
-
Transmisor Asíncrono
-
Receptor Asíncrono
TRANSMISOR ASÍNCRONO:
-
El corazón del transmisor es el Registro de Desplazamiento
Serial de Transmisión (TSR). Este registro se encarga de
enviar al medio físico, uno a uno, los bits del byte de dato a
transmitir.
-
A la vez, este (TSR) recibe sus datos desde el Buffer de
lectura/escritura de transmisión (TXREG)
-
El (TXREG) es cargado con datos desde el software:
DATOS --> [TXREG] --> [TSR] --> Nivel Físico
RS-232
^
-
El buffer (TXREG) queda vacío en cuanto transfiere sus
datos al (TSR), y la bandera TXIF es
seteada, indicando buffer vacío (esta bandera está ubicada
en el PIR1<4>)
-
Es posible generar una interrupción cada vez que el
(TXREG) esté libre (vacío). Para ello hay que setear
el bit TXIE que está situado en el registro
PIE<4>.
La bandera TXIF se activará siempre que
se vacíe el buffer, sin importar el estado del permiso de
interrupción TXIE.
IMPORTANTE: la bandera TXIF no puede
ser borrada por software; se borra automáticamente cuando un nuevo
dato es cargado por software en el buffer de lectura/escritura
(TXREG)
Además, cada vez que seteamos el bit TXEN
(habilitar transmisión) se activa la
TXIF, ya que el buffer se encuentra vacío,
o si tenia algún dato este se transfiere al registro de desplazamiento,
y se vacía inmediatamente.
-
Hay otro bit, que muestra el estado del registro de desplazamiento
(TSR), es el bit TRMT, que se activa
cuando el (TSR) está vacío. Se borra apenas se carga
el (TSR) desde el (TXREG), y queda reseteado hasta que se haya
terminado la transmisión. Este bit está ubicado en el registro
(TXSTA<1>). En el siguiente ejemplo, es este bit el que se muestrea
para saber cuando se puede escribir un dato en el buffer
(TXREG)
Resumen hasta aquí:
| Registro |
Función |
| (TSR) |
Registro de desplazamiento. Envía los bits en serie al
medio físico |
| (TXREG) |
Buffer de lectura/escritura. Recibe el dato a escribir y lo carga
en TSR. |
| (PIR1<TXIF>) |
Bandera de Buffer vacío. Sólo lectura! |
| (PIE1<TXIE>) |
Bit de habilitar interrupción cuando buffer
vacío |
| (TXSTA<TRMT>) |
Bandera de TSR vacío. Sólo lectura! |
Comienzo de la transmisión
-
La transmisión se habilita seteando el bit
TXEN ubicado en (TXSTA<5>). Pero
la transmisión no ocurre hasta que se cargue algún dato en
el buffer de transmisión.
-
TRANSMISION BACK-TO-BACK: Se puede cargar un
dato en el buffer de transmisión antes de setear el bit
TXEN. Entonces, al setear el permiso de
transmisión TXEN, el contenido de
(TXREG) se transfiere inmediatamente al (TSR), el buffer queda
vacío, y se le puede cargar un segundo dato antes de que la
transmisión del primero haya finalizado.
Pasos a seguir para transmitir un dato:
-
Inicializar el registro (SPBRG) y el bit BRGH según
el baud-rate elegido. (cómo hacer esto?)
-
Habilitar el puerto serial asíncrono, reseteando el bit
(TXSTA<SYNC>) y seteando el bit
(RCSTA<SPEN>)
-
Si se van a usar interrupciones, setear el bit
(PIE1<TXIE>)
-
Borrar el bit (TXSTA<TX9>) que sirve para transmisiones
de 9 bits
-
Habilitar la transmisión seteando el bit
(TXSTA<TXEN>).
-
Al hacer lo anterior, se setea automáticamente el bit
(PIR1<TXIF>) ya que el buffer está vacío.
-
Cargar un byte de datos en el buffer de transmisión,
(TXREG). Al hacer esto se comienza la transmisión serial.
-
Recordar que si se quieren usar interrupciones, deben habilitarse
los bits (INTCON<GIE>) e
(INTCON<PEIE>)
Cómo inicializar el registro
(SPBRG) y el bit
(TXSTA<BRGH>):
El registro (SPBRG) controla el periodo de un temporizador
interno de 8 bits, que se usa para llevar el bit-rate de la transmisión.
También hay un bit que controla esta temporización, el bit
(TXSTA<BRGH>). En el manual del
PIC hay tablas donde los valores que deben ir en este registro ya están
calculados. Es conveniente utilizar el BRGH=1,
aunque se usen velocidades bajas, ya que el error es menor (el error porcentual
también figura en las tablas)
Por ejemplo, para una velocidad de 9600 bps, con el
BRGH=1, para un cristal de 4MHz, hay
que setear el SPBRG=.25, y el error es del 0.16%.
Si en cambio se setea el BRGH=0, deberá
cargarse SPBRG=6, y el error resulta ser del 6,99%.
Este código funciona bien para setear la transmisión
asíncrona: (ver más abajo el código
para full duplex)
| bsf STATUS, RP0
|
|
| movlw B'11000000'
|
; RC7 como RX (input),
RC6 como TX (output) deben
; ser puestos a SET para que funcione correctamente la
USART |
| movwf TRISC^80
|
|
| bcf TXSTA
^80,
TX9
|
; 8 bits de
datos |
| bsf TXSTA
^80,
TXEN
|
; Habilitar transmision
serial |
| bcf TXSTA
^80,
SYNC
|
; Modo
asíncrono |
| bsf TXSTA
^80,
BRGH
|
; Velocidad
Alta |
| movlw .12 |
; 19,200
bps |
| movwf SPBRG ^80
|
|
| bcf STATUS, RP0
|
; bank
0 |
| bsf RCSTA,
SPEN
|
; Habilitar Puerto Serial
|
Y para mandar un byte
de datos, esta rutina funciona bien:
-
movwf _W
-
movf STATUS, w
-
movwf _STATUS
-
movf _W, w
-
Bank1
-
btfss TXSTA ^80,
TRMT
-
goto $ - 1
-
bcf STATUS, RP0
-
movwf TXREG
-
movf _STATUS, w
-
movwf STATUS
-
swapf _W, f
-
swapf _W, w
-
return
|
; Salvar el parámetro (dato a
tx) y el registro de estado.
; Recuperar el parámetro
; Banco 1
; Está vacio el buffer de transmisión?
; NO: esperar
; SI: pasar al banco 0,
; Sacar el dato por RS232-TX
; Recuperar STATUS
; Ahora se puede incluir un Delay si hay problemas...
; Recuperar el acumulador |
RECEPTOR ASÍNCRONO
COMPARACIÓN ENTRE REGISTROS Y FLAGS de TRANSMISIÓN
y RECEPCIÓN:
| TRANSMISIÓN |
RECEPCIÓN |
Función |
| TSR |
|
RSR |
|
Registro de desplazamiento (no accesible) |
| TXREG |
|
RCREG |
|
Buffer de datos (PILA FIFO para recepción) |
| TXSTA |
|
RCSTA |
|
Registro de estado |
| TXSTA |
<TXEN> |
RCSTA |
<CREN> |
Habilitación de transmisión/recepción |
| PIR1 |
<TXIF> |
PIR1 |
<RCIF> |
Bandera de fin de transmisión/recepción |
Pasos a seguir para recibir un dato:
-
Inicializar el registro SPBRG con el baud-rate apropiado
(¿cómo hacer esto?) (exactamente igual que
en transmisión)
-
Habilitar el modo ASINCRONO, borrando el bit
SYNC y seteando el bit
SPEN (igual que en transmisión)
-
Si se desea trabajar con interrupciones, setear el permiso RCIE
-
Borrar el bit RX9 si no se desea
recepción de 9 bits.
-
Habilitar la recepción, seteando el bit
CREN (¿por qué no se llama "RCEN"
:-O ? )
-
Cuando se complete la recepción, se setea el bit
RCIF automáticamente, y, eventualmente,
se genera la interrupción correspondiente, si se ha habilitado con
RCIE.
-
Leer el registro RCSTA para determinar si hubo algún
error en la recepción (OERR o
FERR)
-
Leer los 8 bits de datos, leyendo el registro RCREG.
-
Si hubo algún error, borrar el bit
CREN, y luego setearlo para continuar
recibiendo.
-
Asegurarse de setear GIE y PEIE del INTCON si se van a usar
interrupciones
Así quedaría el código SETUP para FULL
DUPLEX:
-
bsf STATUS, RP0
-
bsf TRISC^80, 7
-
bsf TRISC^80, 6
-
bsf TXSTA ^80, BRGH
-
movlw .12
-
movwf SPBRG ^80
-
bcf TXSTA ^80, SYNC
-
bcf TXSTA ^80, TX9
-
bsf TXSTA ^80,
TXEN
-
bcf STATUS, RP0
-
bsf RCSTA, SPEN
-
bcf RCSTA, RX9
-
bsf RCSTA, CREN
|
;Banco 1
;RC7 RX
;RC6 TX
;Velocidad Alta
;19,200 bps
;Modo asíncrono
;8 bits de datos
;Habilitar TX
;Banco 0
;Habilitar puerto
;8 bits de datos
;Habilitar Recepción |
RX
TX
RX/TX
RX/TX
RX/TX
TX
TX
RX/TX
RX
RX |
|
|
|
-
Observar que el bit SYNC y el bit
BRGH pertenecen al registro TXSTA^80,
pero se utilizan tanto para transmisión como para recepción.
De la misma forma, el bit SPEN pertenece al
registro RCSTA, pero se usa también para
transmisión.
Para RECIBIR un byte de datos, esta rutina funciona
bien:
-
movf STATUS, w
-
movwf _STATUS
-
Bank0
-
btfss PIR1,
RCIF
-
goto $ - 1
-
movf _STATUS, W
-
movwf STATUS
-
movf RCREG, w
-
return
|
; Salva STATUS (Bank)
; Pasa al Banco 0
; Ya llegó un dato y el bit de stop?
; todavía no, esperar
; SI: Recuperar STATUS
; Leer el buffer de recepción (con esto se borra la bandera
RCIF) |
Marcelo Valdéz -
marzzelo@yahoo.com
OTRAS NOTAS