Anda di halaman 1dari 9

/*

* Calculadora.asm
*
* Created: 10/01/2017 12:27:17
* Author: Javier
*/
.include "m164Pdef.inc"
.def aux=r16 ;Defino variables a usar en el programa
.def num1=r17
.def num2=r18
.def boton=r19
.def botonh=r20
.def ante=R24
.def numero=R22
.def conta=R23
.def tempo=r25
.def aux2=R26
.def multi=R29
.def suma=R28
.def resta=R27

.dseg

BINARIOL: .BYTE 1; espacio reservado para el numero binario en high y low


BINARIOH: .BYTE 1
BCD0: .BYTE 1 ; miles
BCD1: .BYTE 1 ; centenas
BCD2: .BYTE 1 ; decenas
BCD3: .BYTE 1 ; unidades
DIG0: .BYTE 1 ; equivalente en 7 seg de las decenas
DIG1: .BYTE 1 ;espacio reservado para cada digito en el display
DIG2: .BYTE 1
DIG3: .BYTE 1
tecla: .BYTE 1 ; La tecla presionada
.cseg
.org 0x00 ;donde empieza el programa en la direccion 0x00

inicio: ;etiqueta para conocer el inicio del programa o la base del mismo
ldi aux,0b011111111
out ddra,aux // Configuro el puerto A
com aux
out porta,aux
ldi aux,0b00000000
out ddrb,aux //puerto B como entrada
com aux
out portb,aux
ser aux // el resgitro r16 se cargo con ceros
out ddrc,aux //puerto C se configuro como salida PARA LOS CONTROLES
com aux
out portc,aux
ldi aux,0b00001111
out ddrd,aux // puerto D como entrada
com aux
out portd,aux
/*************GARANTIZO LOS PULL UPS***********/
in aux,mcucr
andi aux,0b11101111
out mcucr,aux
/*********************************************/
ldi aux,high(ramend)
out sph,aux ;inicializo el puntero de la ram high
ldi aux,low(ramend)
out spl,aux ; Inicializo el puntero de la ram low

clr boton ;se procede a limpiar los registros para que no exista ningun
contenido basura en los mismos
clr botonh
clr aux
clr num1
clr num2
otronum: ; etiqueta otronum
ldi ante,16 ;carga indirecta en aux
num:
sts BINARIOL,boton
sts binarioh,botonh
CALL BIN_BCD ; LLAMO A LA RUTINA QUE CONVIERTE DE BINARIO A BCD
CALL BCD_7SEGMENTOS ; LLAMO A LA RUTINA QUE CONVIERTE EL EQUIVALENTE EN 7
SEGMENTOS
CALL BARRIDO_DISPLAY ; LLAMO LA RUTINA QUE REALIZA EL BARRIDO
call teclado
lds aux,tecla
cpi aux,16 ;comparacion inmediata
breq otronum ; si no se presiona una tecla
cpi aux,10 ;comparacion inmediata
breq multiplicar ; si se presiona la tecla de multiplicar
cpi aux,13 ;comparacion inmediata
breq sumar ; si se presiona la tecla de sumar
cpi aux,14;comparacion inmediata
breq restar ; si se presiona la tecla de restar
cpi aux,12;comparacion inmediata
breq borrar ; si se presiona la tecla borrar
cpi aux,11;comparacion inmediata
breq respuesta ; si se presiona la tecla de igual
cpi aux,17;comparacion inmediata
brsh num ; cualquier numero mayor
cp aux,ante;comparacion entre registros aux y ante
brne diferente ; si es la primera vez que se presiona un nmero
rjmp num ;salto incondicional a num

borrar: ; se borra todo


clr boton
clr botonh
clr num1
clr num2
clr numero
rjmp num;salto incondicional a num

diferente: ; se guarda el nummero presionado


mov ante,aux
ldi aux,10
cpi numero,1
breq lazo2

mul num1,aux
add R0,ante
mov aux,R0
cpi aux,100
brsh num
mov boton,R0
mov num1,R0
rjmp num;salto incondicional a num

lazo2: ; se guarda el segundo numero presionado


mul num2,aux
add R0,ante
mov aux,R0
cpi aux,100
brsh num
mov boton,R0
mov num2,boton
rjmp num;salto incondicional a num

multiplicar: ; se multiplican los dos nmeros ingresados


ldi numero,1
clr boton ; limpio varios registros para cumplir ciertas condiciones
clr tempo
ldi tempo,120
rjmp num ;salto incondicional a num

sumar: ; se suman los dos nmeros ingresados


ldi numero,1
clr boton; limpio varios registros para cumplir ciertas condiciones
clr tempo
ldi tempo,122
rjmp num;salto incondicional a num

restar: ; se suman los dos nmeros ingresados


ldi numero,1
clr boton; limpio varios registros para cumplir ciertas condiciones
clr tempo
ldi tempo,124
rjmp num ;salto incondicional a num

respuesta:; aqui comparamos los registros para continuar con la respectiva


operacion segun lo que se presione en nuestra calculadora
cpi tempo,120;comparamos inmediatamente
breq operacion;si es igual salta hacia operacion caso contrario continua con la
siguiente instruccion
cpi tempo,122; comparamos inmediatamente
breq operacion1;si es igual salta hacia operacion caso contrario continua con la
siguiente instruccion
cpi tempo,124;comparamos inmediatamente
breq operacion2;si es igual salta hacia operacion caso contrario continua con la
siguiente instruccion

operacion: ; Se muestra el resultado hasta presionar borrar


mov ante,aux;movemos los valores a otro registro
mul num1,num2 ;se multiplica los valores almacenados
igual1:
sts BINARIOL,R0
sts binarioh,R1
CALL BIN_BCD ; LLAMO A LA RUTINA QUE CONVIERTE DE BINARIO A BCD
CALL BCD_7SEGMENTOS ; LLAMO A LA RUTINA QUE CONVIERTE EL EQUIVALENTE EN 7
SEGMENTOS
CALL BARRIDO_DISPLAY ; LLAMO LA RUTINA QUE REALIZA EL BARRIDO
call teclado;llamo a la rutina del teclado
lds aux,tecla
cpi aux,12
breq borrar1
rjmp igual1

operacion1: ; Se muestra el resultado hasta presionar borrar


mov ante,aux;movemos los valores a otro registro
add num1,num2;sumamos los valores de los registros
clr num2;limpia el registro
mov R0,num1;mueve el registro para facilitar su transformacion
mov R1,num2;mueve el registro para facilitar su transformacion
igual2:
sts BINARIOL,R0
sts binarioh,R1
CALL BIN_BCD ; LLAMO A LA RUTINA QUE CONVIERTE DE BINARIO A BCD
CALL BCD_7SEGMENTOS ; LLAMO A LA RUTINA QUE CONVIERTE EL EQUIVALENTE EN 7
SEGMENTOS
CALL BARRIDO_DISPLAY ; LLAMO LA RUTINA QUE REALIZA EL BARRIDO
call teclado;llamo a la rutina del teclado
lds aux,tecla
cpi aux,12
breq borrar1
rjmp igual2

borrar1: rjmp borrar

operacion2:
mov ante,aux;movemos los valores a otro registro
sub num1,num2;resta ambos registros
clr num2;limpia el registro
mov R0,num1;mueve el registro para facilitar su transformacion
mov R1,num2;mueve el registro para facilitar su transformacion
igual3:
sts BINARIOL,R0
sts binarioh,R1
CALL BIN_BCD ; LLAMO A LA RUTINA QUE CONVIERTE DE BINARIO A BCD
CALL BCD_7SEGMENTOS ; LLAMO A LA RUTINA QUE CONVIERTE EL EQUIVALENTE EN 7
SEGMENTOS
CALL BARRIDO_DISPLAY ; LLAMO LA RUTINA QUE REALIZA EL BARRIDO
call teclado;llamo a la rutina del teclado
lds aux,tecla
cpi aux,12
breq borrar1
rjmp igual3

/**********PROGRAMA QUE CONVIERTE UN NUMERO BINARIO EN BCD Y LO ALMACENA EN LA


SRAM***************/
;EN NUMERO TIENE QUE ESTAR GUARDADO EN BINARIOL Y BINARIOH
;LOS DIGITOS SE GUARDARN DESDE BCD0 HASTA BCD3
BIN_BCD:
push r16
push r17
push r18
push r19
push r20
push r21
push xl
push xh
push zl
push zh ;Se guradan los registros en el stack
lds r16,binariol
lds r17,binarioh ; Se carga el numero que se encuentra en la SRAM
ldi r18,3 ; contador para las iteraciones
ldi xl,low(bcd0)
ldi xh,high(bcd0) ; Direccion del primer nmero
ldi zl,low(constantes<<1)
ldi zh,high(constantes<<1) ; Direccion de la tabla de constantes
bin_bcd0:
lpm r19,z+
lpm r20,z+ ; Para alternar entre 1000,100,10
bin_bcd1:
sub r16,r19
sbc r17,r20
brcs bin_bcd2
inc r21
rjmp bin_bcd1
bin_bcd2:
add r16,r19
adc r17,r20
st x+,r21
clr r21
dec r18
brne bin_bcd0
st x,r16
pop zh
pop zl
pop xh
pop xl
pop r21
pop r20
pop r19
pop r18
pop r17
pop r16
ret
constantes:
.dw 1000, 100, 10

/************PROGRAMA PARA ENCONTRAR EL EQUIVALENTE EN 7 SEGMENTOS****/

BCD_7SEGMENTOS:
PUSH R16
PUSH R17
/*******************PARA LAS UNIDADES********/
LDI XL,LOW(BCD0)
LDI XH,HIGH(BCD0)
LD R16,X // BUSCO EL EQUIVALENTE DE LAS UNIDADES

ldi zh,high(tabla<<1) // apunto a la direccion alta de la tabla


ldi zl,low(tabla<<1) // apunto a la direccion baja de la tabal
add zl,R16 // ubico el numero buscado
clr R16 // dejo vacio el registro
lpm R16,z // copio el valor de la tabla en el registro
/* AHORA DEBO ENVIAR A LA SRAM*/
LDI XL,LOW(DIG0)
LDI XH,HIGH(DIG0)
ST X,R16
/**************************************************/
/*******************PARA LAS DECENAS********/
LDI XL,LOW(BCD1)
LDI XH,HIGH(BCD1)
LD R16,X // BUSCO EL EQUIVALENTE DE LAS DECENAS

ldi zh,high(tabla<<1) // apunto a la direccion alta de la tabla


ldi zl,low(tabla<<1) // apunto a la direccion baja de la tabal
add zl,R16 // ubico el numero buscado
clr R16 // dejo vacio el registro
lpm R16,z // copio el valor de la tabla en el registro
/* AHORA DEBO ENVIAR A LA SRAM*/
LDI XL,LOW(DIG1)
LDI XH,HIGH(DIG1)
ST X,R16
/**************************************************/

/*******************PARA LAS CENTENAS********/


LDI XL,LOW(BCD2)
LDI XH,HIGH(BCD2)
LD R16,X // BUSCO EL EQUIVALENTE DE LAS CENTENAS

ldi zh,high(tabla<<1) // apunto a la direccion alta de la tabla


ldi zl,low(tabla<<1) // apunto a la direccion baja de la tabal
add zl,R16 // ubico el numero buscado
clr R16 // dejo vacio el registro
lpm R16,z // copio el valor de la tabla en el registro
/* AHORA DEBO ENVIAR A LA SRAM*/
LDI XL,LOW(DIG2)
LDI XH,HIGH(DIG2)
ST X,R16
/**************************************************/

/*******************PARA LOS MILES********/


LDI XL,LOW(BCD3)
LDI XH,HIGH(BCD3)
LD R16,X // BUSCO EL EQUIVALENTE DE LOS MILES

ldi zh,high(tabla<<1) // apunto a la direccion alta de la tabla


ldi zl,low(tabla<<1) // apunto a la direccion baja de la tabal
add zl,R16 // ubico el numero buscado
clr R16 // dejo vacio el registro
lpm R16,z // copio el valor de la tabla en el registro
/* AHORA DEBO ENVIAR A LA SRAM*/
LDI XL,LOW(DIG3)
LDI XH,HIGH(DIG3)
ST X,R16
/**************************************************/

POP R17
POP R16

RET
tabla: ;gfedcba gfedcba
.db 0b10111111,0b10000110 ;0,1
.db 0b11011011,0b11001111 ;2,3
.db 0b11100110,0b11101101 ;4,5
.db 0b11111101,0b10000111 ;6,7
.db 0b11111111,0b11101111 ;8,9

BARRIDO_DISPLAY:
PUSH R16
PUSH R17
PUSH R20
/***************ENVIO PRIMERO LAS UNIDADES*******/
LDI XL,LOW(DIG0)
LDI XH,HIGH(DIG0)
LD R16,X
OUT PORTA,R16
LDI R17,0B1111_0111
OUT PORTC,R17 ; ACTIVO EL PRIMER DISPLAY
CALL DELAY
SER R17
OUT PORTC,R17 ; APAGO TODOS LOS DISPLAYS
/******************************************************/
/***************ENVIO LAS DECENAS*******/
LDI XL,LOW(DIG1)
LDI XH,HIGH(DIG1)
LD R16,X
OUT PORTA,R16
LDI R17,0B1111_1011
OUT PORTC,R17 ; ACTIVO EL SEGUNDO DISPLAY
CALL DELAY
SER R17
OUT PORTC,R17 ; APAGO TODOS LOS DISPLAYS
/******************************************************/
/***************ENVIO LAS CENTENAS*******/
LDI XL,LOW(DIG2)
LDI XH,HIGH(DIG2)
LD R16,X
OUT PORTA,R16
LDI R17,0B1111_1101
OUT PORTC,R17 ; ACTIVO EL TERCER DISPLAY
CALL DELAY
SER R17
OUT PORTC,R17 ; APAGO TODOS LOS DISPLAYS
/******************************************************/

/***************ENVIO LOS MILES*******/


LDI XL,LOW(DIG3)
LDI XH,HIGH(DIG3)
LD R16,X
OUT PORTA,R16
LDI R17,0B1111_1110
OUT PORTC,R17 ; ACTIVO EL CUARTO DISPLAY
CALL DELAY
SER R17
OUT PORTC,R17 ; APAGO TODOS LOS DISPLAYS
/******************************************************/
POP R20
POP R17
POP R16

DELAY:
LDI R20,255
L1:
DEC R20
NOP
NOP
BRNE L1
RET

TECLADO:
push r16
in r16,sreg
push r16
push r17
ldi r17,16
ldi r16,0b11111110; tengo que correr un cero en el las filas para ver que
aplasto
out portd,r16
sbis pind,4; al aplastar si coinciden por el barrido se pone un cero en el
pin 4 si es
ldi r17,1
sbis pind,5
ldi r17,2
sbis pind,6
ldi r17,3
sbis pind,7
ldi r17,8

ldi r16,0b11111101
out portd,r16
sbis pind,4
ldi r17,4
sbis pind,5
ldi r17,5
sbis pind,6
ldi r17,6
sbis pind,7
ldi r17,10

ldi r16,0b1111011
out portd,r16
sbis pind,4
ldi r17,7
sbis pind,5
ldi r17,8
sbis pind,6
ldi r17,9
sbis pind,7
ldi r17,14

ldi r16,0b11110111
out portd,r16
sbis pind,4
ldi r17,12
sbis pind,5
ldi r17,0
sbis pind,6
ldi r17,11
sbis pind,7
ldi r17,13
sts tecla,r17
pop r17
pop r16
out sreg,r16
pop r16
ret

Anda mungkin juga menyukai