;El módulo USART. Recepció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 el ejemplo se provoca una interrupción cada vez que se recibe un carácter vía serie. El
;programa de tratamiento visualiza, sobre los leds conectados a la Puerta B,
;el código binario del carácter recibido. Igualmente retransmite el carácter recibido, a 
;modo de ECO.

;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
;ENVIA Y RECIBE SERIAL, CONDICIONES DE RECEPCION SEGUN DATO RECIBIDO


      List   p=16F877A   ;Tipo de procesador
      include   "P16F877A.INC"   ;Definiciones de registros internos

CBLOCK 0X20
INCRE 
PDel0 
 PDel1 
 PDel2 
W_TEMP
STATUS_TEMP
ENDC
      
org   0x00      ;Vector de Reset
      goto   Inicio

      org   0x04      ;Vector de interrupción
      goto   Inter

;********************************************************************************************
;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		;Si
      	return         

;******************************************************************************************
;Tratamiento de la interrupción


Inter 	clrf PORTB

PUSH	MOVWF W_TEMP 		;SALVO REGISTROS
		SWAPF STATUS, W 
		MOVWF STATUS_TEMP    
		
		btfss   PIR1,RCIF   ;Ha sido interrupción en la recepción ??
      	GOTO POP         		;No, falsa interrupción
	
      	bcf   PIR1,RCIF   	;Si, restaurar el flag de interrupción
      	movf   RCREG,W      ;Lee el dato recibido
      
      	XORLW .5
      	BTFSS STATUS,Z
      	GOTO ESDIEZ
      	GOTO CONDI1
      	
ESDIEZ 	movf   RCREG,W
		XORLW .10
      	BTFSS STATUS,Z
      	GOTO MUESTRE
		GOTO CONDI2
      	
     
MUESTRE MOVF RCREG,W
      	
		movwf   PORTB      	;Lo saca por la puerta B
      ;	call   Tx_Dato      ;Lo retransmite a modo de eco
      
      	
  
POP 	SWAPF STATUS_TEMP,W    ;REPONGO LOS REGISTROS
		MOVWF STATUS
		SWAPF W_TEMP, F
		SWAPF W_TEMP, W 
		RETFIE
		
CONDI1	MOVLW 0XF0
		MOVWF PORTB
		CALL DEMORA
		;GOTO MUESTRE
		GOTO POP

CONDI2  MOVLW 0X0F
		MOVWF PORTB
		CALL DEMORA
	;	GOTO MUESTRE
		GOTO POP
;*******************************************************************************************
;Programa principal

Inicio  ;clrwdt
      	clrf   PORTC      
      	clrf   PORTB
      	bsf   STATUS,RP0   ;Selecciona banco 1
      	bcf STATUS,RP1
		clrf   PORTB      ;Puerta B salida
      	movlw   b'10111111'
      	movwf   TRISC      ;RC7/Rx entrada, RC6/Tx salida
      	;movlw   b'11001111'
      	;movwf   OPTION_REG   ;Preescaler de 128 asociado al WDT

      	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
      	bsf   PIE1,RCIE   ;Habilita interrupción en la recepción
      	bcf   STATUS,RP0   ;Selecciona banco 0
      
      	movlw   b'10010000'
      	movwf   RCSTA      ;USART en On, recepción contínua
      	bsf   INTCON,PEIE   ;Activa interrupción de periféricos
      	bsf   INTCON,GIE   ;Activa interrupciones
		clrf RCREG

;Loop   
     
;AQUI TU PROGRAMA
;para enviar datos sólo carga W con el valor a enviar y llama a la subrutina Tx_Dato
; Por ejemplo 
		
INI		INCF INCRE,1
		MOVF INCRE,W
		CALL TX_DATO
		CALL DEMORA
		goto INI



;Lo recibido te lo guarda automáticamente en el registro RCREG y te lo muestra por puerto B

;############################### 1 SEGUNDO #################################

DEMORA  movlw     .14       ; 1 set numero de repeticion  (C)
        movwf     PDel0     ; 1 |
PLoop0  movlw     .72       ; 1 set numero de repeticion  (B)
        movwf     PDel1     ; 1 |
PLoop1  movlw     .247      ; 1 set numero de repeticion  (A)
        movwf     PDel2     ; 1 |
PLoop2  clrwdt              ; 1 clear watchdog
        decfsz    PDel2, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop2    ; 2 no, loop
        decfsz    PDel1,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop1    ; 2 no, loop
        decfsz    PDel0,  1 ; 1 + (1) es el tiempo 0  ? (C)
        goto      PLoop0    ; 2 no, loop
PDelL1  goto PDelL2         ; 2 ciclos delay
PDelL2  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.

      end         ;Fin del programa fuente
