;
;					EJEMPLO 3.10
;
;				Autor: Mikel Etxebarria
;			(c) Microsystems Engineering (Bilbao)
;
;Ejemplo para MicroPIC Trainer y Trainer PLUS. Comunicación serie gestionada por software.
;
;Haciendo uso de las rutinas incluidas en el fichero RS232LOW.INC, se trata de utilizar el
;canal RS232 de la Trainer PLUS para comunicar vía serie con diferentes periféricos. En los
;ejemplos aquí propuestos se utilizará un PC para que, con el software TERMINAL.EXE, actue
;como un simple terminal de comunicaciones. El usuario deberá preparar los cables de comuni-
;cación entre la Trainer PLUS y el PC, teniendo en cuenta de cruzar la señal de Transmisión
;(TxD) con la de recepción (RxD) y viceversa.
;
;Otro ejemplo de comunicaciones. Imaginemos que, desde un terminal, se desea comandar el mo-
;vimiento de una estructura móvil, según la siguiente tabla:
;
;	TECLA		MOVIMIENTO
;	-----		----------
;	  Q		Adelante
;	  A		Atras
;	  O		Izquierda
;	  P		Derecha
;	 SPC		Parada de emergencia
;
;La pulsación de cualquiera de ellas hace bascular el estado de las salidas RB3-RB0 que
;controlan los elementos motrices de la siguiente forma:
;
;	SALIDA		MOVIMIENTO
;	------		----------
;	RB0		Adelante
;	RB1		Atras
;	RB2		Izquierda
;	RB3		Derecha
;
;Finalmente, el PIC devuelve al terminal el tipo de movimiento que se está realizando

		List	p=16F84		;Tipo de procesador
		include	"P16F84.INC"	;Definiciones de registros internos

CLKIN		equ	.4000000	;Frecuencia de trabajo
BAUDIOS		equ	.9600		;Velocidad de comunicación
T_MODO		equ	1		;Transmite primero bit LSB
R_MODO		equ	1		;Recibir primero bit LSB
T_Nbit		equ	8		;Transmite caracteres de 8 bits
R_Nbit		equ	8		;Recibe caracteres de 8 bits
Sbit		equ	2		;Transmite 2 bits de stop
                 
Rs232_var	equ	0x0c		;Inicio de las variables para rutinas RS232
Contador	equ	0x11		;Variable contador de mensajes
Offset		equ	0x12		;Desplazamiento de los mensajes
Temporal_1	equ	0x13		;Variable temporal
Temporal_2	equ	0x14		;Variable temporal

		org	0x00		;Vector de reset
		goto	Inicio
		org	0x05		;Salvar el vector de interrupción	

Mens_0		equ	$
		dt	"Parada general    ",0x0d,0x00
Mens_1		equ	$
		dt	"Marcha adelante   ",0x0d,0x00
Mens_2		equ	$
		dt	"Marcha atras      ",0x0d,0x00
Mens_3		equ	$
		dt	"Situacion nula    ",0x0d,0x00
Mens_4		equ	$
		dt	"Mueve a izquierdas",0x0d,0x00
Mens_5		equ	$
		dt	"Adelante/izquierda",0x0d,0x00
Mens_6		equ	$
		dt	"Atras/izquierda   ",0x0d,0x00
Mens_7		equ	$
		dt	"Situacion nula    ",0x0d,0x00
Mens_8		equ	$
		dt	"Mueve a derechas  ",0x0d,0x00
Mens_9		equ	$
		dt	"Adelante/derecha  ",0x0d,0x00
Mens_10		equ	$
		dt	"Atras/derecha     ",0x0d,0x00

		include	"RS232LOW.INC"	;Incluir rutinas de comunicació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

;*************************************************************************************
;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    movwf	Txdreg
		call    TxD		;Transmite el carácter
                incf    Temporal_1,F    ;Siguiente caracter
                goto    Mensaje_1


Inicio:		clrf	PORTB		;Desconecta salidas
		bsf	STATUS,RP0	;Selecciona página 1 de datos
		movlw	b'10001111'	;Preescaler de 128 para el WDT. Pull_Up Off
		movwf	OPTION_REG	
		movlw	b'11100000'
		movwf	TRISB		;RB5 entrada y RB4-RB0 salidas		
		bcf	STATUS,RP0	;Selecciona página 0 de datos	
			
Loop		clrwdt
		call	RxD		;Espera recibir un carácter
		movlw	'Q'
		subwf	Rxdreg,W
		btfsc	STATUS,Z	;Es 'Q' ??
		goto	Adelante	;Si
		movlw	'A'
		subwf	Rxdreg,W
		btfsc	STATUS,Z	;Es 'A' ??
		goto	Atras		;Si
		movlw	'O'
		subwf	Rxdreg,W
		btfsc	STATUS,Z	;Es 'O' ??
		goto	Izquierda	;Si
		movlw	'P'
		subwf	Rxdreg,W
		btfsc	STATUS,Z	;Es 'P' ??
		goto	Derecha		;Si
		movlw	' '
		subwf	Rxdreg,W
		btfss	STATUS,Z	;Es ' ' ??
		goto	Loop		;No

Stop		bcf	PORTB,0
		bcf	PORTB,1
		bcf	PORTB,2
		bcf	PORTB,3		;Desconecta salidas
		goto	Test_Mens	;Determina el mensaje a sacar

Adelante	bcf	PORTB,1		;Desconecta RB1 (marcha atrás)
		movlw	b'00000001'
		xorwf	PORTB,F		;Bascula RB0
		goto	Test_Mens	;Determina el mensaje a sacar

Atras		bcf	PORTB,0		;Desconecta RB0 (marcha adelante)
		movlw	b'00000010'
		xorwf	PORTB,F		;Bascula RB1
		goto	Test_Mens	;Determina el mensaje a sacar

Izquierda	bcf	PORTB,3		;Desconecta RB3 (marcha derecha)
		movlw	b'00000100'
		xorwf	PORTB,F		;Bascula RB2
		goto	Test_Mens	;Determina el mensaje a sacar

Derecha		bcf	PORTB,2		;Desconecta RB2 (marcha izquierda)
		movlw	b'00001000'
		xorwf	PORTB,F		;Bascula RB3

;A continuación se procede a determinar el mensaje de salida por el terminal. Para ello, en
;base al contenido de la PUERTA B se calcula el offset del mensaje a sacar, teniendo en
;cuenta que los mensajes empiezan a partir de la dirección 0x05 y tienen una longitud fija de
;20 caracteres.
		
Test_Mens	movlw	0x0a
		movwf	Contador	;Inicia contador de mensajes
		movlw	Mens_10
		movwf	Offset		;Dirección del último de los mensajes
Mens_loop	movf	PORTB,W
		andlw	b'00001111'	;Lee valor actual de la PUERTA B
		subwf	Contador,W
		btfsc	STATUS,Z	;Se corresponde con el mensaje a sacar ??
		goto	Salida_mens	;Si
		movlw	.20
		subwf	Offset,F	;No, apunta al mensaje previo
		decf	Contador,F
		goto	Mens_loop
Salida_mens	movf	Offset,W
		call	Mensaje		;Salida del mensaje apropiado
		goto	Loop
		
		end			;Fin del programa fuente

