Está en la página 1de 8

E.P.S.

de Ingeniería de Gijón Prácticas Sistemas Electrónicos Digitales


Curso 2003-2004 curso 3º Ingeniería de Telecomunicación
Práctica 3 – Entorno MPLAB v6.xx: Subprogramas matemáticos

Fechas: 5 y 12 de Diciembre de 2003

El objetivo de la práctica es habituar a los alumnos al entorno MPLAB v6.xx,


para que procedan a dar los pasos correspondientes al diseño, prueba y
evaluación de fragmentos de programa escritos en ensamblador.

Se analizarán y simularán dos subprogramas matemáticos: uno que convierte


números representados en Binario a su formato BCD y otro que convierte
números representados en BCD a Binario.

Estos subprogramas serán utilizados con posterioridad en el desarrollo de


sucesivas prácticas que necesitan de estos tipos de conversión.

Los alumnos deberán completar la práctica mediante la implementación de


un pequeño programa que supone una modificación a uno de los
subprogramas y que se describirá más adelante.

Los subprogramas se incluyen en los siguientes ficheros:

BIN16BCD.ASM : Rutina que convierte un número binario expresado en 16


bits en su valor expresado en BCD (5 dígitos expresados como 5 semibytes
en 3 variables).

BCD2BIN.ASM : Rutina que convierte un número BCD de 2 dígitos en su


valor expresado en binario sobre un byte.

1
E.P.S. de Ingeniería de Gijón Prácticas Sistemas Electrónicos Digitales
Curso 2003-2004 curso 3º Ingeniería de Telecomunicación
Apartado a).- Conversión de Binario a BCD

Planteamiento: se dispone de un dato binario de 16 bits almacenado en 2


bytes consecutivos (BIN_ALTO – posición 0x3A de RAM y BIN_BAJO –
posición 0x3B de RAM) y se desean generar los 5 dígitos correspondientes
a su representación en BCD. Los 5 dígitos se almacenarán en las posiciones
correlativas siguientes: BCD2 – posición 0x3C, BCD1 – posición 0x3D y BCD0
– posición 0x3E.

ENTRADA:

BIN_ALTO (3Ah) BIN_BAJO (3Bh)


01100000 00000000 Valor decimal:
24576
Ej: 60h Ej: 00h

SALIDA:

BCD2 (3Ch) BCD1 (3Dh) BCD0 (3Eh)


00000010 01000101 01110110

Ej: 02h Ej: 45h Ej: 76h

El valor se calcula realizando la operación tal y como se haría una conversión


de binario a decimal: Número en binario -> b15 b14 b13 ... b2 b1 b0

Valor = b15*215 + b14*214 + b13*213 +……+ b2*22 + b1*21 + b0*20

También se puede expresar de otra forma, que coincide con la forma de


calcular que se realiza en el programa:

Valor = ((….(((b15*2 + b14)*2)+ b13)*2……+ b2)*2 + b1)*2 + b0

Las operaciones de multiplicación por 2 y suma de un bit se realizan de


manera elemental mediante desplazamiento a la izquierda y entrada del bit
a sumar por la derecha

Como se desea que el resultado final se exprese en BCD, debemos ajustar


en todo momento a BCD los dígitos resultantes tras cada operación. Para
realizar el ajuste de cada dígito se debe comprobar si éste excede de 9
(dígito BCD válido más alto) y en caso de que así sea, se le debe añadir 6

2
E.P.S. de Ingeniería de Gijón Prácticas Sistemas Electrónicos Digitales
Curso 2003-2004 curso 3º Ingeniería de Telecomunicación
(número de combinaciones que no utiliza el BCD) para incluirlo en el margen
de códigos BCD válidos.

El ajuste se realizará de la siguiente forma (se realiza mediante una rutina


denominada AJBCD): si en un resultado parcial algún dígito es mayor que 4
(100b) y no se han acabado las operaciones de desplazamiento, en la
siguiente operación de desplazamiento se va a salir del margen BCD (como
mínimo va a ser 5*2=10). En ese caso habrá que ajustarlo sumándole 6 o lo
que es igual, aprovechando que se va a realizar luego un desplazamiento a la
izquierda (multiplicación por 2) sumándole 3 y esperando a que el siguiente
desplazamiento a la izquierda haga el resto (la multiplicación por 2). Véase
la rutina AJBCD para másdetalles.

En nuestro ejemplo anterior: b15=0, b14=1, b13=1, b12=0, b11=0,....


Cuando llevemos realizada la operación ((((b15*2 + b14)*2)+ b13)*2)+ b12 el
resultado sería 6 (0110b)

Al realizar la siguiente iteración y multiplicar por 2 (desplazar a la


izquierda), el resultado sería 1100b, lo que no corresponde a un código BCD
válido.

Para arreglarlo, al 6 (que es mayor que 4) le sumamos 3, obteniendo 9


(1001b), que posteriormente multiplicaremos por 2 a la vez que le sumamos
b11(mediante un desplazamiento a la izquierda) con lo que el resultado final
sería: 1 0010b =12h que sí que se corresponde con dos dígitos BCD
coincidentes con el resultado a obtener.

Para comprobar si un número es mayor que 4 (0100b) o no, se le puede


restar 4 y comprobar el resultado con el acarreo o bien sumarle 3 (0011b) y
si alcanza un 1 en el bit 3 es que hemos obtenido un resultado de 8 (1000b)
o mayor que 8 y por lo tanto el número era 5 o mayor que 5. Además, esa
suma nos puede servir para preparar la necesaria corrección y ajuste a BCD
si fuera necesario sumarle 6.

3
E.P.S. de Ingeniería de Gijón Prácticas Sistemas Electrónicos Digitales
Curso 2003-2004 curso 3º Ingeniería de Telecomunicación
Un posible algoritmo sería:

Contador_desp =16

Puesta a 0 de los digitos


BCD

BCD2 BCD1 BCD0 BIN_ALT BIN_BAJ

Dec. Contador_desp

Si
CONTADOR =0
FIN

No
Ajusto BCDs

Un código fuente puede ser (fichero bin16bcd.asm):


;
; Programa que realiza la conversión de un dato binario de 16 bits a un
; formato BCD almacenándolo en 5 dígitos que ocupan medio byte cada uno
;
; El dato binario está almacenado en dos bytes contiguos: BIN_ALTO y BIN_BAJO
; y el resultado va a parar a 3 bytes también consecutivos que son de mayor
; a menor peso: BCD2, BCD1 y BCD0
; Estos almacenan los 5 dígitos, estando presente en los 4 bits más bajos de
; BCD2 únicamente el dígito más significativo
;
LIST p=16F877

CONSTANT BIN_ALTO=0x3A,BIN_BAJO=0x3B ;Definición posiciones del dato


CONSTANT BCD2=0x3C,BCD1=0x3D,BCD0=0x3E ;Posiciones del resultado final

CONTADOR EQU 0x3F ;Contador de desplazamientos


FSR EQU 4 ;Registro para direccionamiento indirecto
STATUS EQU 3 ;Registro de STATUS
CARRY EQU 0
TMP EQU 0x40 ;Posición temporal auxiliar
INDIR EQU 0 ;Registro para direccionamiento indirecto

ORG 0
CALL BINBCD ;Llamamos al subprograma

ESPERA GOTO ESPERA ;Tras retorno del subprograma quedamos aquí

;Inicio del subprograma

ORG 0x120

4
E.P.S. de Ingeniería de Gijón Prácticas Sistemas Electrónicos Digitales
Curso 2003-2004 curso 3º Ingeniería de Telecomunicación
BINBCD MOVLW 0x10 ;Cargamos 16 en el contador
MOVWF CONTADOR
CLRF BCD2 ;Puesta a cero
CLRF BCD1 ;inicial de las posiciones
CLRF BCD0 ;finales

DESPLAZ BCF STATUS,CARRY ;Ponemos a cero el carry antes de rotar


RLF BIN_BAJO ;Rotación total
RLF BIN_ALTO ;desde el byte bajo
RLF BCD0 ;hasta el byte más alto
RLF BCD1 ;de los datos finales
RLF BCD2 ;en BCD

DECFSZ CONTADOR ;Si el contador es cero


GOTO AJUSTE ;ya van 16 desplazamientos
RETURN ;y retornamos

AJUSTE MOVLW BCD0 ;Empleamos direccionamiento indirecto


MOVWF FSR ;para llamar al subprograma de ajuste
CALL AJBCD ;decimal de cada byte, primero con BCD0

MOVLW BCD1 ;Lo mismo con BCD1


MOVWF FSR
CALL AJBCD

MOVLW BCD2 ;Y lo mismo con BCD2


MOVWF FSR
CALL AJBCD

GOTO DESPLAZ ;Volvemos a las rotaciones

; Subprograma para ajuste BCD de cada byte

AJBCD MOVLW 3 ;Sumamos 3 a la posición a la que apunta FSR


ADDWF INDIR,W ;el contenido queda en W

MOVWF TMP ;Exploramos si en el primer dígito el


BTFSC TMP,3 ;resultado es mayor que 7
MOVWF INDIR ;si es así lo corregimos almacenando ese valor

MOVLW 30 ;Hacemos lo mismo con el dígito BCD superior


ADDWF INDIR,W

MOVWF TMP ;Exploramos sumando 30 al byte completo


BTFSC TMP,7 ;y si el dígito superior es mayor que 7
MOVWF INDIR ;lo almacenamos para corregir

RETURN ;Retorno desde el subprograma AJBCD

END
Para la simulación (comprobación del funcionamiento):

1. Creamos un fichero con el código fuente anterior


File > New para abrir el editor, se escribe y...
File > Save para salvar el código

2. Se define el proyecto correspondiente


Project > Project Wizard

5
E.P.S. de Ingeniería de Gijón Prácticas Sistemas Electrónicos Digitales
Curso 2003-2004 curso 3º Ingeniería de Telecomunicación
3. Se realiza el ensamblado
Project > Build All

4. Activamos el simulador
Debugger > Select Tool >MPLAB Sim

5. Añadimos las variables a ver durante la simulación.


View > Watch

y seleccionamos las siguientes variables de interés:


BIN_ALTO (en binario o hexadecimal)
BIN_BAJO (en binario o hexadecimal)
BCD0 (en hexadecimal)
BCD1 (en hexadecimal)
BCD2 (en hexadecimal)
CONTADOR (en decimal)

6. Colocamos valores iniciales a las variables BIN_ALTO y BIN_BAJO.


Les damos unos valores de prueba y al resto valores aleatorios.

7. Realizamos la ejecución que permita comprobar el funcionamiento:


ejecución continua, con animación o paso a paso
Debugger > Run / Animate / Step

6
E.P.S. de Ingeniería de Gijón Prácticas Sistemas Electrónicos Digitales
Curso 2003-2004 curso 3º Ingeniería de Telecomunicación
Apartado b).- Conversión de BCD a Binario

Se dispone de 2 dígitos BCD almacenados cada uno en un semi-byte de una


variable de 8 bits denominada DATOBCD (0x30) y se desea obtener el valor
binario equivalente en la variable Binario (0x31).

ENTRADA: Ejemplo:

BCDH BCDL 0101 0001

DATOBCD (30h) DATOBCD (30h) = 51

SALIDA: Ejemplo:

b7b6b5b4 b3b2b1b0 0011 0011

BINARIO (31h) BINARIO (31h) = 33h = 51d

Para realizar esta operación, operamos de la siguiente forma:


Binario = 10 x DIGH + DIGL

Debemos operar en binario, pero como no hay instrucción de multiplicación,


buscamos los productos por 2 que consisten en desplazamientos:
Binario= (8+2) x DIGH + DIGL = 8 x DIGH + 2 x DIGH + DIGL
Extraemos DIGL

Binario = DIGL

P. alta: DIGH * 2 4

Rotamos dcha.: DIGH * 2 3

3
Binario = Binario + DIGH * 2

3
Rotamos 2 veces dcha. DIGH*2 y
obtenemos DIGH * 2

Binario = Binario + DIGH * 2

7
E.P.S. de Ingeniería de Gijón Prácticas Sistemas Electrónicos Digitales
Curso 2003-2004 curso 3º Ingeniería de Telecomunicación
Y un posible código fuente (fichero bcd2bin.asm):
;
; Subprograma para la conversión de dos dígitos BCD almacenados en un byte
; en un número binario equivalente, entra en 8 bits por tanto
;
; El dato de entrada se sitúa en la posición DATOBCD
; y el resultado va a parar a la posición BINARIO
;

LIST P=16F877

DATOBCD EQU 0x30 ;Posición donde se carga el dato con los dos dígitos BCD
BINARIO EQU 0x31 ;Posición final donde va a parar el resultado
TEMP EQU 0x32 ;Posición auxiliar de trasvase
MISMO EQU 1 ;Indicador de resultado sobre el registro
STATUS EQU 3 ;Registro de STATUS
CARRY EQU 0 ;Posición del bit de CARRY dentro de STATUS

ORG 0
CALL BCDBIN ;Llamada al subprograma de conversión
ESPERA GOTO ESPERA ;Nos quedamos esperando en este bucle tras retorno

ORG 100

BCDBIN MOVLW 0x0F ;Extraemos dígito BCD inferior y


ANDWF DATOBCD,W ;lo dejamos en W
MOVWF BINARIO ;Lo guardamos ahora en la posición final

MOVLW 0xF0 ;Extraemos ahora dígito BCD superior y


ANDWF DATOBCD,MISMO ;lo dejamos en el dato, tenemos pues el BCD
;superior multiplicado por 16

BCF STATUS,CARRY ;Ponemos a cero el carry para desplazamientos


RRF DATOBCD ;Como divido por 2 ahora tengo
MOVF DATOBCD,W ;dígito superior multiplicado por 8
ADDWF BINARIO,MISMO ;y se lo sumo al dígito inferior

RRF DATOBCD ;Divido por 2: dígito sup. x 4


RRF DATOBCD ;Divido por 2: dígito sup. x 2
MOVF DATOBCD,W ;Ahora lo sumo con el parcial previo
ADDWF BINARIO,MISMO ;en la posición binario
RETURN ;retorno del subprograma

END

Para la simulación se procederá de manera similar al apartado a)

Trabajo Adicional para los Alumnos:

Se debe realizar un subprograma que tomando 4 dígitos BCD almacenados


en las posiciones BCD_ALTO (0x20) y BCD_BAJO (0x21) nos proporcione el
valor binario asociado (máximo 0x270F = 9999 en decimal) y lo almacene en
dos bytes denominados BIN_HIGH (0x22 para la parte alta) y BIN_LOW
(0x23 para la parte baja).

El fragmento de programa se escribirá para un microcontrolador PIC16F877


Se detallará el algoritmo empleado, se escribirá el correspondiente código
fuente y se comprobará su funcionamiento

También podría gustarte