;
;					EJEMPLO 39
;
;				Autor: Mikel Etxebarria
;			(c) Microsystems Engineering (Bilbao)
;
;Ejemplo para MicroPIC Trainer y Micro'PIC Trainer Plus
;
;El módulo USART. Transmisión asíncrona
;
;El módulo USART de los dispositivos PIC16F87X incorpora el hardware necesario para implemen-
;tar comunicación serie asíncrona full-duplex o sincrona half-duplex. En este último caso el
;USART se puede comportar como Master o Slave.
;
;En los ejemplos siguientes se propone utilizar un PC para que, con el software TERMINAL.EXE,
;actúe como un simple terminal de comunicaciones. EL usuario deberá preparar los cables de
;comunicación entre la Trainer PLUS y el PC, teniendo en cuenta de cruzar las señal de
;transmisión (TxD) con la de recepción (RxD) y viceversa.
;
;El ejemplo transmite un mensaje publicitario cada segundo.

		List	p=16F873	;Tipo de procesador
		include	"P16F873.INC"	;Definiciones de registros internos

Delay		equ	0x20		;variable de temporización
Temporal_1	equ	0x21
Temporal_2	equ	0x22		;Variables temporales de propósito general

		org	0x00		;Vector de Reset
		goto	Inicio

		org	0x05		;Salva vector de interrupción
	
;******************************************************************************************
;Según el valor contenido en el registro W, se devuelve el carácter a visualizar

Tabla_Mensajes	movwf	PCL		;Calcula el desplazamiento sobre la tabla

;***********************************************************************************
;La directiva dt genera tantas intsrucciones retlw como bytes o caracteres contenga

Mens_0		equ	$		;Mens_0 apunta al primer carácter del mensaje 0
		dt	"Microsystems Engineering",0x0d,0x0a,0x00

Mens_1		equ	$		;Mens_1 apunta al primer carácter del mensaje 1
		dt	"Gral. Concha 39 48012 Bilbao",0x0d,0x0a,0x00

Mens_2		equ	$		;Mens_2 apunta al primer carácter del mensaje 2
		dt	"Tfno./Fax 94 4223263",0x0d,0x0a,0x00

;*************************************************************************************
;Mensaje: Esta rutina envía vía serie RS232 el mensaje cuyo inicio está  indicado en
;el acumulador. El fin de un mensaje se determina mediante el código 0x00

Mensaje         movwf   Temporal_1      ;Salva posición de la tabla
Mensaje_1       movf    Temporal_1,W    ;Recupera posición de la tabla
                call    Tabla_Mensajes  ;Busca caracter de salida
                movwf   Temporal_2      ;Guarda el caracter
                movf    Temporal_2,F
                btfss   STATUS,Z        ;Mira si es el último
                goto    No_es_ultimo
                return
No_es_ultimo   	call    Tx_Dato		;Transmite el carácter
                incf    Temporal_1,F    ;Siguiente caracter
                goto    Mensaje_1

;********************************************************************************************
;Tx_Dato: Transmite vía serie el dato presente en el reg. W

Tx_Dato		bcf	PIR1,TXIF	;Restaura el flag del transmisor
		movwf	TXREG		;Almacena el byte a transmitir
		bsf	STATUS,RP0
Tx_Dato_Wait	btfss	TXSTA,TRMT	;Byte transmitido ??
		goto	Tx_Dato_Wait	;No, esperar
		bcf	STATUS,RP0
		return			;Si

;*******************************************************************************************
;Programa principal

Inicio	     	clrwdt
		clrf	PORTC		
		bsf	STATUS,RP0	;Selecciona banco 1
		movlw	b'10111111'
		movwf	TRISC		;RC7/Rx entrada, RC6/Tx salida
		movlw	b'11000111'
		movwf	OPTION_REG	;Preescaler de 256 asociado al TMR0

		movlw	b'00100100'	
		movwf	TXSTA		;TX en On, modo asíncrono con 8 bits y alta velocidad
		movlw	.25
		movwf	SPBRG		;9600 baudios con Fosc=4MHz

		bcf	STATUS,RP0	;Selecciona banco 0
		bsf	RCSTA,SPEN	;USART en On

;Trabajando a 4MHz y con un preescaler de 256, el TMR0 se carga con 195 para conseguir que
;rebase cada 50mS. Esto se repite tantas veces como indique la variable Delay para 
;obtener la temporización final deseada.
		
Loop		movlw	.20
		movwf	Delay		;Repetir 20 veces para obtener 1 seg.

Wait_2		bcf	INTCON,T0IF	;Restaura el flag del TMR0
		movlw	~.195
		movwf	TMR0		;Reponer el TMR0 para 50mS de temporización
Wait_1		clrwdt			;Refrescar el WDT
		btfss	INTCON,T0IF	;Han pasado 50 mS ??
		goto	Wait_1		;Todavía no
		decfsz	Delay,F		;Se han provocado 20 rebasamientos de 50mS (1s.) ?
		goto	Wait_2		;Todavía no

		movlw	Mens_0
		call	Mensaje		;Visualiza mensaje 0
		movlw	Mens_1
		call	Mensaje		;Visualiza mensaje 1
		movlw	Mens_2
		call	Mensaje		;Visualiza mensaje 3
		movlw	0x0a
		call	Tx_Dato		;Transmite avance de línea
		call	Tx_Dato		;Transmite avance de línea
		goto	Loop

		end			;Fin del programa fuente
