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:


TRANSMISOR ASÍNCRONO:

DATOS --> [TXREG] --> [TSR] --> Nivel Físico RS-232
^

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

Pasos a seguir para transmitir un dato:

  1. Inicializar el registro (SPBRG) y el bit BRGH según el baud-rate elegido. (cómo hacer esto?)
  2. Habilitar el puerto serial asíncrono, reseteando el bit (TXSTA<SYNC>) y seteando el bit (RCSTA<SPEN>)
  3. Si se van a usar interrupciones, setear el bit (PIE1<TXIE>)
  4. Borrar el bit (TXSTA<TX9>) que sirve para transmisiones de 9 bits
  5. Habilitar la transmisión seteando el bit (TXSTA<TXEN>).
  6. Al hacer lo anterior, se setea automáticamente el bit (PIR1<TXIF>) ya que el buffer está vacío.
  7. Cargar un byte de datos en el buffer de transmisión, (TXREG). Al hacer esto se comienza la transmisión serial.
  8. 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:

  1. movwf _W
  2. movf STATUS, w
  3. movwf _STATUS
  4. movf _W, w
  5. Bank1
  6. btfss TXSTA ^80, TRMT
  7. goto $ - 1
  8. bcf STATUS, RP0
  9. movwf TXREG
  10. movf _STATUS, w
  11. movwf STATUS
  12. swapf _W, f
  13. swapf _W, w
  14. 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:

  1. Inicializar el registro SPBRG con el baud-rate apropiado (¿cómo hacer esto?) (exactamente igual que en transmisión)
  2. Habilitar el modo ASINCRONO, borrando el bit SYNC y seteando el bit SPEN (igual que en transmisión)
  3. Si se desea trabajar con interrupciones, setear el permiso RCIE
  4. Borrar el bit RX9 si no se desea recepción de 9 bits.
  5. Habilitar la recepción, seteando el bit CREN (¿por qué no se llama "RCEN" :-O ? )
  6. 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.
  7. Leer el registro RCSTA para determinar si hubo algún error en la recepción (OERR o FERR)
  8. Leer los 8 bits de datos, leyendo el registro RCREG.
  9. Si hubo algún error, borrar el bit CREN, y luego setearlo para continuar recibiendo.
  10. Asegurarse de setear GIE y PEIE del INTCON si se van a usar interrupciones


Así quedaría el código SETUP para FULL DUPLEX:

  1. bsf STATUS, RP0
  2. bsf TRISC^80, 7
  3. bsf TRISC^80, 6
  4. bsf TXSTA ^80, BRGH
  5. movlw .12
  6. movwf SPBRG ^80
  7. bcf TXSTA ^80, SYNC
  8. bcf TXSTA ^80, TX9
  9. bsf TXSTA ^80, TXEN
  10. bcf STATUS, RP0
  11. bsf RCSTA, SPEN
  12. bcf RCSTA, RX9
  13. 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

Para RECIBIR un byte de datos, esta rutina funciona bien:

  1. movf STATUS, w
  2. movwf _STATUS
  3. Bank0
  4. btfss PIR1, RCIF
  5. goto $ - 1
  6. movf _STATUS, W
  7. movwf STATUS
  8. movf RCREG, w
  9. 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