Este documento describe un programa para un microcontrolador PIC16F877 que convierte un número hexadecimal recibido a sus equivalentes decimal, binario y hexadecimal. Inicializa los puertos de comunicación serial y variables de control. Luego, en bucles, transmite los resultados de las conversiones hexadecimal a decimal usando división, hexadecimal a binario usando rotación y complemento a 2, y hexadecimal a ASCII agregando valores.
1. 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
2. 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,"$"
3. ;---------------- 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
4. 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