	processor 16f877
	include <p16f887.inc>
	
CHAR EQU H'28'	;AUXILIAR PARA DATO

APUN EQU H'29'
D_MSJ EQU H'30'

U_1 equ h'20'	;UNO BINARIO
C_0 equ h'21'	;CERO BINARIO
CONT equ h'22'	;CONTADOR PARA BINARIO

;UNIDADES PARA LA CONVERSION A DECIMAL
C_CEN EQU H'24' ;CENTENAS
C_DEC EQU H'25' ;DECENAS
C_UNI EQU H'26' ;UNIDADES 
DATO EQU H'23'	;DATO A CONVERTIR

D_HEX EQU H'27'	;DATO PARA FUNCION HEXADECIMAL

	ORG 0
	GOTO INICIO
	ORG 5

INICIO:
	BSF STATUS,RP0		;CAMBIO AL BANCO 1
	BCF STATUS,RP1
;	MOVLW 0xFF
;	MOVWF TRISB
	BSF TXSTA,BRGH		;TASA ALTA
	MOVLW D'129'		;BAUD DE 9600		
	MOVWF SPBRG			
	BCF TXSTA,SYNC		;COMUNICACIÓN ASÍNCRONA
	BSF TXSTA,TXEN		;HABILITACIÓN DE TRANSMISIÓN
	BCF STATUS,RP0		;CAMBIO A BANCO 0
	BSF RCSTA,SPEN		;HABILITAR PUERTO SERIE


LOOP:
;	MOVF PORTB,0
	MOVLW 0xc3			;DATO ENVIADO
	MOVWF DATO			;COPIA DE DATO PARA CONVERSIÓN BINARIA
	MOVWF C_UNI			;COPIA DE DATO PARA CONVERSIÓN DECIMAL
	MOVWF D_HEX			;COPIA DE DATO PARA CONVERSIÓN HEXADECIMAL
	MOVWF CHAR			;COPIA DE DATO PARA CONVERSIÓN HEXADECIMAL
	
	MOVLW 0x0A
	CALL TRANSMITE
	MOVLW 0x0D
	CALL TRANSMITE
	
	CALL MSJ			;CABECERAS DE LA TABLA DE CONVERSIÓN

;----- ENVIO DE HEXADECIMAL --------
	SWAPF D_HEX,1		;SE TOMA LA PARTE ALTA DEL NÚMERO RECIBIDO
	CALL HEX_BCD		;SE LLAMA A LA FUNCIÓN DE CONVERSIÓN
	MOVF D_HEX,0		;SE MUEVE EL DATO RESULTANTE A W
	CALL TRANSMITE		;SE LLAMA FUNCIÓN PARA TRANSMITIR
	MOVF CHAR,0			;SE MUEVE EL DATO ORIGINAL A W
	MOVWF D_HEX			;SE MANDA A D_HEX
	CALL HEX_BCD		;SE LLAMA LA CONVERSIÓN
	MOVF D_HEX,0		;SE REGRESA EL RESULTADO DE CONVERSIÓN A W
	CALL TRANSMITE		;SE TRANSMITE DATO


	MOVLW 0x09
	CALL TRANSMITE
	
	
;------ ENVIO DE DECIMAL -------------
	CALL DEC_BCD		;LLAMA FUNCIÓN DE HEXA A DECIMAL
	MOVF C_CEN,0		;ENVÍA LAS CENTENAS A W
	MOVWF D_HEX			;SE MANDAN A D_HEX
	CALL HEX_BCD		;SE LLAMA A LA FUNCIÓN DE CONVERSIÓN
	MOVF D_HEX,0		;SE REGRESA EL RESULTADO A W
	CALL TRANSMITE		;SE TRANSMITE DATO
	
	MOVF C_DEC,0		;SE ENVÍA LAS DECENAS
	MOVWF D_HEX			;DECENAS A D_HEX
	CALL HEX_BCD		;LLAMAMOS A CONVERSIÓN
	MOVF D_HEX,0		;RESULTADO EN W
	CALL TRANSMITE		;SE TRANSMITE DATO

	MOVF C_UNI,0		;POR ÚLTIMO SE MANDAN UNIDADES
	MOVWF D_HEX			;SE PASAN A D_HEX
	CALL HEX_BCD		;SE LLAMA A LA CONVERSIÓN
	MOVF D_HEX,0		;RESULTADO EN W
	CALL TRANSMITE		;TRANSMITIR DATO


	MOVLW 0x09
	CALL TRANSMITE


;-------- ENVIO DE BINARIO ------------
	CALL BIN_BCD		;LLAMA A LA FUNCIÓN DE CONVERSIÓN DE HEXA A BIN

	MOVLW 0x0A
	CALL TRANSMITE
	MOVLW 0x0D
	CALL TRANSMITE	
	GOTO fin
	;GOTO LOOP

fin:
	goto $

;-------- ENVIO DE MENSAJE (CABECERAS DE TABLA) --------------------------------------
MSJ:
	CLRF APUN
CICLO:
	CALL TEXTO
	MOVWF D_MSJ	
	SUBLW "$"
	BTFSC STATUS,Z
	RETURN
	MOVF D_MSJ,0
	CALL TRANSMITE
	INCF APUN
	GOTO CICLO

TEXTO:
	MOVF APUN,W
	ADDWF PCL
	DT " HEX ",0x09," DEC ",0x09," BIN ",0x0A,0x0D,"$"

	
;---------------- HEXADECIMAL A DECIMAL ----------------------------
DEC_BCD:
	CLRF C_DEC		;LIMPIA EL CONTADOR DE DECENAS
	CLRF C_CEN		;LIMPIA CONTADOR DE CENTENAS
	MOVLW 0x64		;SE CARGA 100 (CENTENA) A W
R_C:SUBWF C_UNI,1	;SE "DIVIDE" (RESTA 100) ENTRE 100 AL DATO
	BTFSS STATUS,C	;COMPARA CON EL BIT DE ACARREO (NEGATIVO) 
	GOTO DECENAS	;SI ES 0 SALTA A DECENAS 
	INCF C_CEN		;SI ES UNO, INCREMENTA EL CONTADOR DE CENTENAS
	GOTO R_C		;SE REPITE LA ACCIÓN

DECENAS:
	ADDWF C_UNI,1	;SE SUMA W CON DATO, PARA HACERLO POSITIVO
	MOVLW 0x0A		;SE CARGA UNA DECENA A W
R_D:SUBWF C_UNI,1	;SE "DIVIDE" (RESTA 10)
	BTFSS STATUS,C	;COMPARACION CON EL BIT DE ACARREO
	GOTO UNIDADES	;SI ES 0 SALTA A UNIDADES
	INCF C_DEC		;SI ES 1 INCREMENTA CONTADOR DE DECENAS
	GOTO R_D		;REPITE CICLO
	
UNIDADES:
	ADDWF C_UNI,1	;SE SUMA W CON DATO, Y EL RESULTANTE SON LAS UNIDADES
	RETURN			;REGRESA A INICIO
	
	
;----------------- BINARIO A ASCII --------------------------------	
BIN_BCD:
	MOVLW 0x09		;NUMERO DE VECES QUE REPETIRA EL CICLO
	MOVWF CONT		;VARIABLE CONTADOR
DEC:DECFSZ CONT		;DECREMENTO DE CONT=8 (NUMERO DE BITS)
	GOTO ROT		;CICLO QUE ROTA EL NUMERO
	RETURN			;REGRESO A INICIO

ROT:BCF STATUS,C	;MANDA 0 A C
	RLF DATO,1		;SE ROTA DATO Y SE GUARDA EN F
	BTFSS STATUS,C	;SE VERIFICA EL BIT DE ACARREO
	GOTO CERO		;SI ES CERO, MANDA A CERO
	GOTO UNO		;SI ES UNO, MANDA A UNO

	
UNO:MOVLW 0x01		;MUEVE 1 A W
	MOVWF D_HEX		;SE MUEVE 1 A D_HEX
	CALL HEX_BCD	;SE CONVIERTE
	MOVF D_HEX,0	;RESULTADO A W
	CALL TRANSMITE	;TRANSMITE DATO
	GOTO DEC		;REGRESA AL DECREMENTO
	
CERO:	
	MOVLW 0x00		;MUEVE 0 A W
	MOVWF D_HEX		;SE MANDA EL 0 A D_HEX
	CALL HEX_BCD	;SE CONVIERTE
	MOVF D_HEX,0	;RESULTADO DE CONVERSIÓN A W
	CALL TRANSMITE	;TRANSMITE DATO
	GOTO DEC		;REGRESA AL DECREMENTO 
	
	
;---------------- HEXADECIMAL A ASCII --------------------------------	

;LA CONVERSIÓN HEXADECIMAL ES LA MÁS SENCILLA, YA QUE EN ESTE FORMATO SE RECIBE
;EL DATO, Y SOLO BASTA SUMAR 30H O 37H, SEGÚN SEA EL CASO, PARA MANDARLO A LA 
;TERMINAL. POR ESTA RAZÓN SE USA ESTA FUNCIÓN PARA TRANSMITIR TODOS LOS RESULTADOS
;DE LAS CONVERSIONES
	
HEX_BCD:	
	MOVLW 0x0F		;SE MUEVE B'1111' A W
	ANDWF D_HEX,1	;SE HACE UNA MASCARA, PARA TENER SOLO 4 BITS
	MOVLW 0x0A		;SE MUEVE 10 A W
	SUBWF D_HEX,1	;AL RESULTADO DE LA MASCARA SE LE RESTA 10
	BTFSS STATUS,C	;SE PREGUNTA POR EL BIT DE ACARREO
	GOTO NUM		;SI ES 0 SE TRATA DE UN NUMERO
	GOTO LETRA		;SI ES 1 SE TRATA DE UNA LETRA

NUM:
	ADDWF D_HEX,1	;SE REGRESA AL NUMERO ORIGINAL
	MOVLW 0x30		;SE MUEVE 30H A W
	ADDWF D_HEX,1 	;SE SUMA 30H PARA PASARLO A ASCII
	RETURN			;REGRESO A INICIO
	
LETRA:		
	ADDWF D_HEX,1	;SE REGRESA AL NUMERO ANTERIOR
	MOVLW 0x37		;SE MUEVE 37H A W
	ADDWF D_HEX,1	;SE SUMA W A D_HEX, PARA PASARLO A LETRA ASCII
	RETURN			;REGRESO A INICIO


;----------------- TRANSMITE DATO -------------------------------------
TRANSMITE	
	MOVWF TXREG
	BSF STATUS,RP0
	
ESPERA:	
	BTFSS TXSTA,TRMT
	GOTO ESPERA 
	BCF STATUS,RP0
	RETURN
	
	
END