Calculadora pic16f887

HOLA QUE TAL, ESTOY TRATANDO DE HACER UNA CALCULADORA CON UN PIC16F887


LAS OPERACIONES Q QUIERO Q REALICE SON LAS BÁSICAS, ES DECIR SUMA,RESTA,MULTIPLICACIÓN Y DIVISIÓN, PERO TENGO CIERTOS PROBLEMAS CON MI CÓDIGO AL MOMENTO DE COMPILARLO, OJALA ME PUEDAN AYUDAR, AQUÍ LES DEJO EL CÓDIGO EN ARCHIVO .ASM QUE SEGUN YO, VOY DESARROLLANDO


GRACIAS.



;****************************************************************************
;* -CALCULADORA- *
;****************************************************************************

LIST P=PIC16F887
RADIX HEX


INCLUDE <P16F887.INC>
__CONFIG _CONFIG1,0x20C4
__CONFIG _CONFIG2,0x3EFF

estado equ 3
fsr equ 4
indf equ 0
ra equ 5
rb equ 6
ac equ 0
z equ 2
w equ 0
f equ 1

dato equ 0x20 ;registro utilizado para introducir los datos

regest equ 0x0f ;registro donde guardamos los signos de los operandos,
;el del resultado y tambien las operaciones a realizar

; 7 6 5 4 3 2 1 0
; ³SOP1 ³SOP2 ³SRES ³ ³RESTA³SUMA ³MULT ³ DIV ³



presul equ 0x16 ;³
sresul equ 0x17 ;registros para el resultado
tresul equ 0x18 ;³

cont1 equ 0x1c ;³
cont2 equ 0x1d ;contadores auxiliares
cont3 equ 0x1e ;³
cont4 equ 0x22 ;³
cont5 equ 0x2b ;³
cont6 equ 0x2c ;³

pbyte1 equ 0x10 ;³
sbyte1 equ 0x11 ;³ÄÄ>primer operando
tbyte1 equ 0x12 ;³

pbyte2 equ 0x13 ;³
sbyte2 equ 0x14 ;³ÄÄ>segundo operando
tbyte2 equ 0x15 ;³

rac equ 0x1f ;³
err equ 0x1a ;³
rr1 equ 0x2d ;³
clr equ 0x21 ;³
diez equ 0x1b ;³ÄÄ>registros auxiliares
r1 equ 0x0c ;³
r2 equ 0x0d ;³
r3 equ 0x0e ;³

d1 equ 0x23 ;³
d2 equ 0x24 ;³
d3 equ 0x25 ;³
d4 equ 0x26 ;³ÄÄ>registros donde se guarda el resultado ya preparado
d5 equ 0x27 ;³ para ser visualivado
d6 equ 0x28 ;³
d7 equ 0x29 ;³
d8 equ 0x2a ;³

org 0
goto inicio
org 4
goto inter
org 5
inicio call lcd1
call lcd_ini ;inicializa el lcd, con una linea y cursor off
call inicial ;configura los puertos
call b_todo
;call b_lcd ;borra el lcd
movlw '0'
call lcd_datos ;escribe en el lcd el contenido del acumulador
movlw 2
movwf rr1

BSF STATUS,RP0
CLRF OPTION_REG
MOVLW B'00111111' ;SELECCIONA EL FLANCO QUE PROVOCARA LAS INTERRUPCIONES Y ACTIVA LAS RESISTENCIAS DE PULL-UP
MOVWF OPTION_REG
MOVLW B'11110000' ;ACTIVA LAS RESISTENCIA PULL-UP 4 BITS MENOS SIGNIFICATIVOS
MOVWF WPUB
BCF STATUS,RP0
MOVLW B'10001000' ;HABILITA INTERUPCIONES GLOBALES
MOVWF INTCON
BSF STATUS,RP0 ;PASA AL BANCO UNO
MOVLW B'11110000'
MOVWF IOCB

movwf trisa ;puerto b <1:4>salida, <0>entrada
bcf estado,5 ;selecciona el banco cero
movlw 0xa8


movlw 0x52 ;³
movwf cont5 ;³contador de tres minutos con ayuda del
movlw 0x08 ;³prescaler
movwf cont6 ;³

bucle1 goto bucle1 ;programa principal espera las interupciones

inter btfsc intcon,0 ;mira si se ha pulsado una tecla
goto m_tecla ;salta a reconocer la tecla pulsada
btfsc intcon,2 ;mira si se ha desbordado el TMR0
goto dormir ;salta al modo apagado
call vuelta ;habilita interrupciones antes de volver al programa principal
retfie

dormir bcf intcon,2 ;deshabilita interrupciones
bcf intcon,7 ;deshabilita interrupciones
decfsz cont5,1 ;decrementa primer contador
goto hab ;salta para volver al programa principal
decfsz cont6,1 ;decrementa segundo contador
goto hab ;salta para volver al programa principal
goto dormir2 ;salta a dormir la calculadora
hab bsf intcon,7 ;habilita las interrupciones
call vuelta ;habilita interrupciones antes de volver al programa principal
retfie
dormir2 call lcd1 ;configura los puertos
call b_todo ;borra registros internos
call delay_5ms ;retardo de 5ms
movlw 0xa8
movwf intcon ;habilita las interrupciones
bsf estado,5 ;selecciona el banco uno
movlw 0xf0
movwf trisb ;configura el puerto b
bcf estado,5 ;selecciona el banco cero
sleep ;se pone a dormir
nop
call vuelta ;habilita interrupciones antes de volver al programa principal
retfie
;****************************************************************************
;* *
;* Se conecta el teclado al puerto b poniendo los 4 bits de menor *
;* peso como salidas y los otros 4 como entradas y ponemos en el *
;* puerto el valor f0h. *
;* El teclado cruza los 4 pines de menor peso con los 4 de mayor *
;* formando 16 conexiones que se cierran cuando pulsamos una tecla. *
;* Las conexiones para cada tecla son: *
;* * 1 -->el pin 7 con el pin 3 *
;* * 2 -->el pin 6 con el pin 3 *
;* * 3 -->el pin 5 con el pin 3 *
;* * 4 -->el pin 7 con el pin 2 *
;* * 5 -->el pin 6 con el pin 2 *
;* * 6 -->el pin 5 con el pin 2 *
;* * 7 -->el pin 7 con el pin 1 *
;* * 8 -->el pin 6 con el pin 1 *
;* * 9 -->el pin 5 con el pin 1 *
;* * 0 -->el pin 6 con el pin 0 *
;* * + -->el pin 4 con el pin 3 *
;* * - -->el pin 4 con el pin 2 *
;* * x -->el pin 4 con el pin 1 *
;* * / -->el pin 4 con el pin 0 *
;* * = -->el pin 5 con el pin 0 *
;* * C -->el pin 7 con el pin 0 *
;* *
;****************************************************************************

m_tecla ;bcf intcon,0
;bcf intcon,7
bsf estado,5 ;selecciona el banco uno
bsf option_reg,7 ;quita las pull-up
bcf estado,5 ;selecciona el banco cero
call deshab ;deshabilita las interrupciones

movlw 0x07 ;³
iorwf portb,1 ;³
btfss portb,7 ;³miramos si se ha pulsado las teclas
goto n1 ;³ 1,2,3 y suma
btfss portb,6 ;³
goto n2 ;³
btfss portb,5 ;³
goto n3 ;³
btfss portb,4 ;³
goto regsum ;³

bsf portb,3 ;³
bcf portb,2 ;³
btfss portb,7 ;³
goto n4 ;³
btfss portb,6 ;³miramos si se ha pulsado las teclas
goto n5 ;³ 4,5,6 y resta
btfss portb,5 ;³
goto n6 ;³
btfss portb,4 ;³
goto regres ;³

bsf portb,2 ;³
bcf portb,1 ;³
btfss portb,7 ;³
goto n7 ;³
btfss portb,6 ;³
goto n8 ;³miramos si se ha pulsado las teclas
btfss portb,5 ;³ 7,8,9 y multiplicacion
goto n9 ;³
btfss portb,4 ;³
goto regmult ;³

bsf portb,1 ;³
bcf portb,0 ;³
btfss portb,7 ;³miramos si se ha pulsado las teclas
goto clear2 ;³ clear,0, igual y division
btfss portb,6 ;³
goto n0 ;³
btfss portb,5 ;³
goto regigual ;³
btfss portb,4 ;³
goto regdiv ;³

call vuelta ;habilita interrupciones antes de volver al programa principal
retfie



habilitar movlw 0xa8
movwf intcon ;habilita las interrupciones
bsf estado,5 ;selecciona el banco uno
movlw 0xf0
movwf trisb ;configura el puerto b
bcf estado,5 ;selecciona el banco cero
return


;**********RESET DE LA CALCULADORA**********
; ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ

clear call lcd1 ;configura los puertos
call b_todo ;borra registros internos
movlw '0'
call lcd_datos ;escribe en el lcd el contenido del acumulador
movlw 1
movwf clr ;pone a uno el registro
movlw 2
movwf rr1
call vuelta ;habilita interrupciones antes de volver al programa principal
retfie

;----ponemos el numero introducido en el registro dato----

n0 bsf rb,0 ;manda un uno para quitar la interrupcion
decfsz rr1,w
;goto no_borrar0

call borrar
no_borrar0 movlw 0x0f ;miramos si se ha pulsado una operacion
andwf regest,w
btfss estado,z
goto seg_op
movf pbyte1,w ;³
btfss estado,2 ;³
goto escribir ;³
movf sbyte1,w ;³miramos si el 1§ operando es cero,
btfss estado,2 ;³si lo es no escribimos nada
goto escribir ;³
movf tbyte1,w ;³
btfsc estado,2 ;³
retfie
goto escribir

seg_op movf pbyte2,w ;³
btfss estado,2 ;³
goto escribir ;³miramos si el 2§ operando es cero,
movf sbyte2,w ;³si lo es no escribimos nada
btfss estado,2 ;³
goto escribir ;³
movf tbyte2,w ;³
btfsc estado,2 ;³
retfie

escribir call d_4seg
decfsz clr,0 ;decrementa el registro clr, si es cero salta
;y escribe el cero, si es distinto de cero
;borra todos los registros internos
call b_todo ;borra registros internos
call lcd1 ;configura los puertos
movlw '0'
call lcd_datos ;escribe en el lcd el contenido del acumulador
clrf dato ;ponemos un cero en el registro dato
goto ent ;saltamos a introducir el dato

n1 bsf rb,3 ;manda un uno para quitar la interrupcion
call d_4seg
decfsz rr1,w
;goto no_borrar1
call borrar
no_borrar1 decfsz clr,0 ;decrementa el registro clr, si es cero salta
;y escribe el cero, si es distinto de cero
;borra todos los registros internos
call b_todo ;borra registros internos
call lcd1 ;configura los puertos
movlw '1'
call lcd_datos ;escribe en el lcd el contenido del acumulador
movlw 0x01
movwf dato ;ponemos un uno en el registro dato
goto ent ;saltamos a introducir el dato

n2 bsf rb,3 ;manda un uno para quitar la interrupcion
call d_4seg
decfsz rr1,w
;goto no_borrar2
call borrar
no_borrar2 decfsz clr,0 ;decrementa el registro clr, si es cero salta
;y escribe el cero, si es distinto de cero
;borra todos los registros internos
call b_todo ;borra registros internos
call lcd1 ;configura los puertos
movlw '2'
call lcd_datos ;escribe en el lcd el contenido del acumulador
movlw 0x02
movwf dato ;ponemos un dos en el registro dato
goto ent ;saltamos a introducir el dato

n3 bsf rb,3 ;manda un uno para quitar la interrupcion
call d_4seg
decfsz rr1,w
;goto no_borrar3
call borrar
no_borrar3 decfsz clr,0 ;decrementa el registro clr, si es cero salta
;y escribe el cero, si es distinto de cero
;borra todos los registros internos
call b_todo ;borra registros internos
call lcd1 ;configura los puertos
movlw '3'
call lcd_datos ;escribe en el lcd el contenido del acumulador
movlw 0x03
movwf dato ;ponemos un tres en el registro dato
goto ent ;saltamos a introducir el dato

n4 bsf rb,2 ;manda un uno para quitar la interrupcion
call d_4seg
decfsz rr1,w
;goto no_borrar4
call borrar
no_borrar4 decfsz clr,0 ;decrementa el registro clr, si es cero salta
;y escribe el cero, si es distinto de cero
;borra todos los registros internos
call b_todo ;borra registros internos
call lcd1 ;configura los puertos
movlw '4'
nop
call lcd_datos ;escribe en el lcd el contenido del acumulador
movlw 0x04
movwf dato ;ponemos un cuatro en el registro dato
goto ent ;saltamos a introducir el dato

n5 bsf rb,2 ;manda un uno para quitar la interrupcion
call d_4seg
decfsz rr1,w
;goto no_borrar5
call borrar
no_borrar5 decfsz clr,0 ;decrementa el registro clr, si es cero salta
;y escribe el cero, si es distinto de cero
;borra todos los registros internos
call b_todo ;borra registros internos
call lcd1 ;configura los puertos
movlw '5'
call lcd_datos ;escribe en el lcd el contenido del acumulador
movlw 0x05
movwf dato ;ponemos un cinco en el registro dato
goto ent ;saltamos a introducir el dato

n6 bsf rb,2 ;manda un uno para quitar la interrupcion
call d_4seg
decfsz rr1,w
;goto no_borrar6
call borrar
no_borrar6 decfsz clr,0 ;decrementa el registro clr, si es cero salta
;y escribe el cero, si es distinto de cero
;borra todos los registros internos
call b_todo ;borra registros internos
call lcd1 ;configura los puertos
movlw '6'
call lcd_datos ;escribe en el lcd el contenido del acumulador
movlw 0x06
movwf dato ;ponemos un seis en el registro dato
goto ent ;saltamos a introducir el dato

n7 bsf rb,1 ;manda un uno para quitar la interrupcion
call d_4seg
decfsz rr1,w
;goto no_borrar7
call borrar
no_borrar7 decfsz clr,0 ;decrementa el registro clr, si es cero salta
;y escribe el cero, si es distinto de cero
;borra todos los registros internos
call b_todo ;borra registros internos
call lcd1 ;configura los puertos
movlw '7'
call lcd_datos ;escribe en el lcd el contenido del acumulador
movlw 0x07
movwf dato ;ponemos un siete en el registro dato
goto ent ;saltamos a introducir el dato

n8 bsf rb,1 ;manda un uno para quitar la interrupcion
call d_4seg
decfsz rr1,w
;goto no_borrar8
call borrar
no_borrar8 decfsz clr,0 ;decrementa el registro clr, si es cero salta
;y escribe el cero, si es distinto de cero
;borra todos los registros internos
call b_todo ;borra registros internos
call lcd1 ;configura los puertos
movlw '8'
call lcd_datos ;escribe en el lcd el contenido del acumulador
movlw 0x08
movwf dato ;ponemos un ocho en el registro dato
goto ent ;saltamos a introducir el dato

n9 bsf rb,1 ;manda un uno para quitar la interrupcion
call d_4seg
call lcd1 ;configura los puertos
decfsz rr1,w
;goto no_borrar9
call borrar
no_borrar9 decfsz clr,0 ;decrementa el registro clr, si es cero salta
;y escribe el cero, si es distinto de cero
;borra todos los registros internos
call b_todo ;borra registros internos
;call lcd1
movlw '9'
call lcd_datos ;escribe en el lcd el contenido del acumulador
movlw 0x09
movwf dato ;ponemos un nueve en el registro dato
goto ent ;saltamos a introducir el dato

regsum movlw 1 ;ponemos en el registro clr un 1 para que
movwf clr ;nos guarde el resultado en el primer operando
;ya que hemos pulsado una operacion
bsf rb,3 ;manda un uno para quitar la interrupcion
bsf regest,2 ;ponemos a 1 el bit de la suma
call b_lcd ;borra el lcd
call vuelta ;habilita interrupciones antes de volver al programa principal
retfie

regres movlw 1
movwf clr ;ponemos en el registro clr un 1 para que
;nos guarde el resultado en el primer operando
;ya que hemos pulsado una operacion
bsf rb,2 ;manda un uno para quitar la interrupcion
movf pbyte1,0 ;llevamos pbyte1 al acumulador
btfss estado,2 ;miramos si es cero
goto par ;primer operando distinto de 0
movf sbyte1,0 ;llevamos sbyte1 al acumulador
btfss estado,2 ;miramos si es cero
goto par ;primer operando distinto de 0
movf tbyte1,0 ;llevamos tbyte1 al acumulador
btfss estado,2 ;miramos si es cero
goto par ;primer operando distinto de 0
btfss regest,7 ;primer operando es 0, cambiamos el
;signo del primer operando
goto pone_ ;si primer operando positivo salta a poner -
goto quitar_ ;si primer operando negativo salta a quitar -

pone_ ;call lcd1
call d_4seg
movlw 1
movwf rr1
call b_lcd ;inicializa el lcd
movlw '-'
call lcd_datos ;escribe en el lcd el contenido del acumulador
bsf regest,7 ;ponemos a 1 el bit de signo del primer operando
call d_4seg ;retardo de 250ms.
call vuelta ;habilita interrupciones antes de volver al programa principal
retfie

quitar_ ;call lcd1
call b_lcd ;inicializa el lcd
bcf regest,7 ;ponemos a 0 el bit de signo del primer operando
call d_4seg ;retardo de 250ms.
call vuelta ;habilita interrupciones antes de volver al programa principal
retfie

par movlw 0x0f
andwf regest,w ;miramos si hay alguna operacion pulsada
btfss estado,2 ;
goto seg_neg ;si no la hay, vamos a mirar si el 2§ operando
;es cero
;call lcd1
call b_lcd ;inicializa el lcd
bsf regest,3 ;ponemos a 1 el bit de la resta
call delay_5ms ;retardo de 5ms.
call vuelta ;habilita interrupciones antes de volver al programa principal
retfie

seg_neg movf pbyte2,0 ;llevamos pbyte2 al acumulador
btfss estado,2 ;miramos si es cero
goto nocero ;segundo operando distinto de 0
movf sbyte2,0 ;llevamos sbyte2 al acumulador
btfss estado,2 ;miramos si es cero
goto nocero ;segundo operando distinto de 0
movf tbyte2,0 ;llevamos tbyte2 al acumulador
btfsc estado,2 ;miramos si es cero
goto sicero ;el 2§ operando es 0 y vamos a cambiar el signo
nocero call delay_5ms ;retardo de 5ms.
call vuelta ;habilita interrupciones antes de volver al programa principal
retfie

sicero btfss regest,6 ;miramos el signo del 2§ operando
goto pone2_ ;si es positivo lo ponemos negativo
goto quitar2_ ;si es negativo lo ponemos positivo

pone2_ ;call lcd1
call b_lcd ;inicializa el lcd
call d_4seg
movlw '-'
call lcd_datos ;escribe en el lcd el contenido del acumulador
bsf regest,6 ;ponemos a 1 el bit de signo del 2§ operando
call d_4seg ;retardo de 250ms.
call vuelta ;habilita interrupciones antes de volver al programa principal
retfie

quitar2_ ;call lcd1
call b_lcd ;borra el lcd
bcf regest,6 ;ponemos a 0 el bit de signo del 2§ operando
call d_4seg ;retardo de 250ms.
call vuelta ;habilita interrupciones antes de volver al programa principal
retfie

regmult movlw 1
movwf clr ;ponemos en el registro clr un 1 para que
;nos guarde el resultado en el primer operando
;ya que hemos pulsado una operacion
bsf rb,1 ;manda un uno para quitar la interrupcion
bsf regest,0 ;ponemos a 1 el bit de la multiplicacion
;call lcd1
call b_lcd ;borra el lcd
call d_4seg ;retardo de 250ms
call vuelta ;habilita interrupciones antes de volver al programa principal
retfie

regdiv movlw 1
movwf clr ;ponemos en el registro clr un 1 para que
;nos guarde el resultado en el primer operando
;ya que hemos pulsado una operacion
bsf rb,0 ;manda un uno para quitar la interrupcion
bsf regest,1 ;ponemos a 1 el bit de la division
call d_4seg ;retardo de 250ms
call lcd1
call b_lcd ;borra el lcd
call inicial

call vuelta ;habilita interrupciones antes de volver al programa principal
retfie

regigual bsf rb,0 ;manda un uno para quitar la interrupcion
;call lcd1
call b_lcd ;borra el lcd
call delay_5ms ;retardo de 5ms.
goto operacion ;vamos a ver que operacion ha sido pulsada

clear2 bsf rb,0 ;manda un uno para quitar la interrupcion
;call lcd1
call b_lcd ;borra el lcd
goto clear ;reseteamos la calculadora

;**********ENTRADA DE DATOS A LOS OPERANDOS**********
; ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
;****************************************************************************
;* *
;* Cuando se detecta un numero por el teclado, miramos si hay una *
;* operacion pulsada: *
;* * Si hay una operacion pulsada multiplicamos por 10 *
;* el operando 2 y sumamos el dato correspondiente *
;* * Si hay una operacion pulsada multiplicamos por 10 *
;* el operando 1 y sumamos el dato correspondiente *
;* *
;* Ejemplo: *
;* 123 = ((((((0*10)+1)*10)+2)*10)+3) *
;* *
;****************************************************************************


ent call d_4seg ;retardo de 250ms
clrf presul ;³
clrf sresul ;³->ponemos a cero el resultado
clrf tresul ;³
movlw 0x0f ;miramos si se ha pulsado una operacion
andwf regest,w
btfss estado,z
goto op2 ;si se ha pulsado una operacion
;vamos a op2
; goto op1 ;si no se ha pulsado una operacion
;vamos a op1

op1 movf pbyte1,w ;guardamos valor del operando1 en registros auxiliares
movwf cont1 ; ³
movf sbyte1,w ; ³
movwf cont2 ; 
movf tbyte1,w
movwf cont3
goto sumarj

op2 movf pbyte2,w ;guardamos valor del operando2 en registros auxiliares
movwf cont1 ; ³
movf sbyte2,w ; ³
movwf cont2 ; 
movf tbyte2,w
movwf cont3

;MULTIPLICAMOS POR 10 EL VALOR DEL OPERANDO
;==========================================

sumarj movlw 0xa
movwf diez ;llevamos un diez al registro diez
sumarj1 movf cont1,w
addwf presul,f ;sumamos presul al cont1
btfsc estado,ac ;miramos si hay acarreo
goto inc_re2 ;si hay acarreo salta a incrementar el sresul
conti1 movf cont2,w
addwf sresul,f ;sumamos sresul al cont2
btfsc estado,ac ;miramos si hay acarreo
goto inc_re3 ;si hay acarreo salta a incrementar el tresul
conti2 movf cont3,w
addwf tresul,f ;sumamos tresul al cont3
btfsc estado,ac ;miramos si hay acarreo
goto regerror ;si hay acarreo se desborda y se produce error
decfsz diez,f ;decrementa diez y salta si cero
goto sumarj1 ;vuelve a sumarj1
goto finalj ;si diez es cero saltamos a finalj

inc_re2 movlw 1
addwf sresul,f ;suma 1 al 2§ byte si hay acarreo
btfss estado,ac ;mira si hay acarreo
goto conti1 ;si no hay acarreo continua sumando el 2§ byte
addwf tresul,f ;suma 1 al tercer byte si hay acarreo
btfss estado,ac ;mira si hay acarreo
goto conti1 ;si no hay acarreo continua sumando el 2§ byte
goto regerror ;hay acarreo y se produce error

inc_re3 movlw 1
addwf tresul,f ;suma 1 al 3er byte si hay acarreo
btfsc estado,ac ;mira si hay acarreo
goto regerror ;hay acarreo y se produce error
goto conti2 ;si no hay acarreo sumamos el tercer byte

;SUMAR EL NUEVO DATO
;===================

finalj movf dato,w
addwf presul,1 ;sumamos el dato al presul
btfss estado,ac ;mira si hay acarreo
goto finalj2 ;si no hay salta a final
movlw 1
addwf sresul,f ;si hay acarreo suma 1 al sresul
btfss estado,ac ;mira si hay acarreo
goto finalj2 ;si no hay salta a final
addwf tresul,f ;si hay acarreo suma 1 al tresul
btfss estado,ac ;mira si hay acarreo
goto finalj2 ;si no hay salta a final
goto regerror ;si hay acarreo se produce error


errj movlw 0xff ;se ha desbordado el 3er byte y nos hemos salido
movwf err ;del rango de la calculadoraÄÄÄ->ERROR
goto regerror ;


finalj2 movlw 0x0f ;miramos en que operando tenemos que guardar el
andwf regest,w ;dato segun si se ha pulsado alguna operacion o no
btfss estado,z ;
goto op22 ;si se ha pulsado una operacion vamos al op2
;goto op11 ;si no se ha pulsado una operacion vamos al op1


op11 movf presul,w ;volvemos a restaurar el op1
movwf pbyte1 ; ³
movf sresul,w ; ³
movwf sbyte1 ; 
movf tresul,w
movwf tbyte1
call vuelta ;habilita interrupciones antes de volver al programa principal
retfie ;volvemos a introducir otro dato

op22 movf presul,w ;volvemos a restaurar el op2
movwf pbyte2 ; ³
movf sresul,w ; ³
movwf sbyte2 ; 
movf tresul,w
movwf tbyte2
call vuelta ;habilita interrupciones antes de volver al programa principal
retfie ;volvemos a introducir otro dato

;MIRAR LA OPERACION PULSADA
;==========================

operacion bcf regest,4 ;miramos que operacion ha sido pulsada
btfsc regest,0 ; ³
goto mult ; ³
btfsc regest,1 ; 
goto div
btfsc regest,2
goto sumah
btfsc regest,3
goto restah
call vuelta ;habilita interrupciones antes de volver al programa principal
retfie ;si no se ha pulsado ninguna operacion vuelve
;a inicio


;**********MULTIPLICACION**********
; ÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
;****************************************************************************
;* Miramos el primer bit del segundo operando: *
;* - Si es 0 rotamos a la izquierda el primer operando, a la *
;* derecha el segundo y volvemos a empezar *
;* - Si es 1 rotamos a la izquierda el primer operando, a la *
;* derecha el segundo y sumamos el primer operando al resultado *
;* y volvemos a empezar *
;* Ponemos un contador a 24d para hacer 24 rotaciones, ya que los *
;* numeros tienen 24 bits *
;****************************************************************************

mult bcf regest,w
movlw 0x18 ;inicializamos cont1 a 18h(24d)
movwf cont1
clrf tresul ;³
clrf sresul ;³->reseteamos el resultado
clrf presul ;³
;clrf err

bucle btfss pbyte2,w ;testea bit0 de op2
goto rotar ;si 0 rota op1 a izquierda y op2 a derecha
goto sumarm ;si 1 suma op1 a resul

sumarm movf pbyte1,w ;suma pbyte1 a presul
addwf presul,f ;
btfss estado,ac ;mira si hay acarreo
goto aa ;si no hay salta
movf sbyte1,w
addlw 1 ;si hay acarreo suma 1 al 2§ byte
addwf sresul,f ;suma sbyte1 a sresul
btfss estado,ac ;mira si hay acarreo
goto bb ;si no hay salta
cc movf tbyte1,w
addlw 1 ;si hay acarreo suma 1 al tercer byte
addwf tresul,f ;suma tbyte1 a tresul
btfss estado,ac ;mira si hay acarreo
goto rotar ;salta a rotar
goto regerror ;si hay acarreo se produce error
aa movf sbyte1,w
addwf sresul,f ;suma sbyte1 a sresul
btfsc estado,ac ;mira si hay acarreo
goto cc ;si no hay salta
bb movf tbyte1,w
addwf tresul,f ;suma tbyte1 a tresul
btfss estado,ac ;mira si hay acarreo
goto rotar ;va a rotar el op2 a dcha y op1 a izda
goto regerror ;se ha desbordado el 3er byte

;ROTAMOS EL PRIMER OPERANDO
;==========================

rotar bcf estado,ac ;ponemos a cero el acarreo
rlf tbyte1,f ;rotamos a la izquierda el tercer byte del op1
btfsc estado,ac ;mira si hay acarreo
goto mirar0 ;si hay salta
bcf estado,ac ;ponemos a cero el acarreo
rlf sbyte1,f ;rotamos a la izquierda el segundo byte del op1
btfsc estado,ac ;mira si hay acarreo
bsf tbyte1,0 ;ponemos a 1 el bit 0 del tercer byte del op1
bcf estado,ac ;ponemos a cero el acarreo
rlf pbyte1,f ;rotamos a la izquierda el primer byte del op1
btfsc estado,ac ;mira si hay acarreo
bsf sbyte1,0 ;ponemos a 1 el bit 0 del segundo byte del op1
bcf estado,ac ;ponemos a cero el acarreo
rrf pbyte2,f ;rotamos a la derecha el primer byte del op2
bcf estado,ac ;ponemos a cero el acarreo
rrf sbyte2,f ;rotamos a la derecha el segundo byte del op2
btfsc estado,ac ;mira si hay acarreo
bsf pbyte2,7 ;ponemos a 1 el bit 7 del primer byte del op2
bcf estado,ac ;ponemos a cero el acarreo
rrf tbyte2,f ;rotamos a la derecha el tercer byte del op2
btfsc estado,ac ;mira si hay acarreo
bsf sbyte2,7 ;ponemos a 1 el bit 7 del segundo byte del op2
decfsz cont1,f ;decrementa el cont1
goto bucle ;no 0, otra iteracion
goto final ;rotacion n§ 24, final

mirar0 movf pbyte2,w ;mira si 2§ operando es 0 por posible error
btfss estado,z ; ³
goto regerror ; ³
movf sbyte2,w ; 
btfss estado,z
goto regerror
movf tbyte2,w
btfss estado,z
goto regerror ;si el 2§ op no es cero se produce error
goto final ;si el 2§ op es cero se va a final

;EL SIGNO DEL RESULTADO DE LA MULTIPLICACION Y LA DIVISION
;=========================================================

signo btfss regest,7 ;miramos el signo del op1
goto ab ;salta si es +
btfss regest,6 ;miramos el signo del op2
goto neg ;salta si es +
goto pos ;salta si es -
ab btfss regest,6 ;miramos el signo del op2
goto pos ;salta si es +
neg bsf regest,5 ;ponemos el resultado -
return
pos bcf regest,5 ;ponemos el resultado +
return


;**********DIVISION**********
; ÍÍÍÍÍÍÍÍ

;****************************************************************************
;* Miramos si el operando 2 ( divisor ) es 0, entonces ERROR *
;* *
;* ALGORITMO DE DIVISION: *
;* P 6 registros: * Resto (mitad izquierda-reg auxiliares) *
;* * Cociente (mitad derecha (primer operando)) *
;* Inicialmente: * En cociente ponemos el dividendo *
;* * En resto ponemos un 0 *
;* *
;* 1.- Desplazar P un bit a la izquierda *
;* 2.- Restar el op2 al resto y guardas el resultado en ‚l *
;* 3.- Si el resultado del paso 2 es < 0 entonces ponemos el bit *
;* de orden inferior de P a 0, y a 1 en cualquier otro caso *
;* 4.- Si el resultado del paso 2 es < 0 restauramos el valor *
;* antiguo del resto. *
;* 5.- Miramos si es la ultima rotacion: *
;* - SI, entonces final *
;* - NO, volvemos al paso 1 *
;****************************************************************************


div bcf regest,1 ;ponemos a cero el bit de la division

clrf cont1 ;³
clrf cont2 ;³reseteamos registros auxiliares
clrf err ;³
clrf cont3 ;³
clrf rac ;³

movlw 0x18 ;ponemos un contador a 18h(24d)
movwf cont4
clrw ;reseteamos el acumulador
addwf pbyte2,f ;miramos si el pbyte2 es 0
btfss estado,z
goto dbucle ;si no cero vamos a dividir
addwf sbyte2,f ;miramos si el sbyte2 es 0
btfss estado,z
goto dbucle ;si no cero vamos a dividir
addwf tbyte2,f ;miramos si el tbyte2 es 0
btfsc estado,z
;goto dbucle ;si no cero vamos a dividir
goto regerror ;si 2§ operando=0ÄÄÄ>ERROR


dbucle bcf estado,ac ;ponemos a cero el acarreo
rlf cont3,f ;rotamos a la izquierda el contador 3
bcf estado,ac ;ponemos a cero el acarreo
rlf cont2,f ;rotamos a la izquierda el contador 2
btfsc estado,ac ;miramos si hay acarreo
bsf cont3,0 ;ponemos a uno el bit 0 de cont3
bcf estado,ac ;ponemos a cero el acarreo
rlf cont1,f ;rotamos a la izquierda el contador 1
btfsc estado,ac ;miramos si hay acarreo
bsf cont2,0 ;ponemos a uno el bit 0 de cont2
bcf estado,ac ;ponemos a cero el acarreo
rlf tbyte1,f ;rotamos a la izquierda el tercer byte del op1
btfsc estado,ac ;miramos si hay acarreo
bsf cont1,0 ;ponemos a uno el bit 0 de cont1
bcf estado,ac ;ponemos a cero el acarreo
rlf sbyte1,f ;rotamos a la izquierda el segundo byte del op1
btfsc estado,ac ;miramos si hay acarreo
bsf tbyte1,0 ;ponemos a uno el bit 0 del tercer byte de op1
bcf estado,ac ;ponemos a cero el acarreo
rlf pbyte1,f ;rotamos a la izquierda el primer byte del op1
btfsc estado,ac ;miramos si hay acarreo
bsf sbyte1,0 ;ponemos a uno el bit 0 del segundo byte del op1

movf cont1,w ;³
movwf r1 ;³
movf cont2,w ;³guardamos el contenido de los contadores
movwf r2 ;³en registros auxiliares para no perder su
movf cont3,w ;³valor
movwf r3 ;³

movf pbyte2,w ;³restamos el segundo operando
subwf cont1,f ;³a los contadores:
btfsc estado,ac ;³ -si el resultado es negativo el
goto daaa ;³ segundo operando es mayor que la
movf sbyte2,w ;³ parte seleccionada del primer
addlw 1 ;³ operando y salta a poner un 0 en
;³ el primer bit del primer operando
subwf cont2,f ;³ -si el resultado es mayor o igual
btfsc estado,ac ;³ que cero la parte seleccionada del
goto dbbb ;³ primer operando es mayor que el segundo
dccc movf tbyte2,w ;³ operando y salta a poner un 1 en
addlw 1 ;³ el primer bit del primer operando
subwf cont3,f ;³ ³
btfsc estado,ac ;³ ³
goto poner1 ;³ ³
goto poner0 ;³ 
daaa movf sbyte2,w ;³
subwf cont2,f ;³
btfss estado,ac ;³
goto dccc ;³
dbbb movf tbyte2,w ;³
subwf cont3,f ;³
btfss estado,ac ;³
;goto poner1 ;³
goto poner0 ;³


poner1 bsf pbyte1,0 ;si resta >= 0 ÄÄ>ponemos 1 al resultado
decfsz cont4,f ;decrementa el cont4 para ver si es la ultima rotacion
goto dbucle ;si no es la ultima vuelve a empezar
movf pbyte1,w ;si es la ultima guarda el resultado en los
movwf presul ;registros especificos para ello
movf sbyte1,w
movwf sresul
movf tbyte1,w
movwf tresul
goto final


poner0 bcf pbyte1,0 ;si resta < 0 ÄÄ>ponemos 0 al resultado

movf r1,w ;³
movwf cont1 ;³
movf r2,w ;³restauramos el valor de los contadores
movwf cont2 ;³
movf r3,w ;³
movwf cont3 ;³

decfsz cont4,f ;decrementa el cont4 para ver si es la ultima rotacion
goto dbucle ;si no es la ultima vuelve a empezar
movf pbyte1,w ;si es la ultima guarda el resultado en los
movwf presul ;registros especificos para ello
movf sbyte1,w
movwf sresul
movf tbyte1,w
movwf tresul


final call signo ;ponemos el signo al resultado
goto extrac ;y lo sacamos por pantalla


;**********SUMA**********
; ÍÍÍÍ
;****************************************************************************
;* *
;* 1.- Miramos los signos de los operandos: *
;* * Si iguales entonces los sumamos y ponemos el signo *
;* * Si distintos entonces ponemos el signo del mayor al *
;* resultado, los comparamos y restamos al mayor el menor *
;* *
;****************************************************************************

sumah btfsc regest,7 ;testeamos los signos de los operandos
goto suma2h ; ³
btfsc regest,6 ; ³
goto opresta ; 
call opsuma ; (signo del resultado (+)
bcf regest,5 ; si op1 y op2 son +)
goto extrac

suma2h bcf regest,2
btfss regest,6
goto opresta
call opsuma ; (signo del resultado (-)
bsf regest,5 ; si op1 y op2 son -)
goto extrac

opsuma movf pbyte1,w ;realizamos la suma si los signos son iguales
addwf pbyte2,w ; ³ÿ
movwf presul ; ³
btfsc estado,ac ; 
goto carry
yo movf sbyte1,w
addwf sbyte2,w
movwf sresul
btfsc estado,ac
goto carry2
tu movf tbyte1,w
addwf tbyte2,w
movwf tresul
btfsc estado,ac
goto regerror
retlw 0
carry movlw 0x01 ;sumamos 1 al 2§ byte si acarreo
addwf sbyte2,f
btfss estado,ac
goto yo
goto carry2
carry2 movlw 0x01 ;sumamos 1 al 3er byte si acarreo
addwf tbyte2,f
btfss estado,ac
goto tu
goto regerror ;Cuando se desborde ÄÄÄ> ERROR

opresta call comp ;realizamos la resta si los signos son distintos
bcf estado,ac ; ³
movf pbyte2,w ; ³
subwf pbyte1,w ; 
movwf presul
movf sbyte2,w
btfss estado,ac
addlw 1
subwf sbyte1,w
movwf sresul
movf tbyte2,w
btfss estado,ac
addlw 1
subwf tbyte1,w
movwf tresul
goto extrac

comp movf tbyte2,w ;comparamos los operandos
subwf tbyte1,w ; ³
btfss estado,ac ; 
goto cambiar ; ( si el op2 > op1 en la resta,
btfss estado,z ; hay que restarle el op2 al
goto sr ; op1, por lo que intercambiamos
movf sbyte2,w ; los operandos,restamos y
subwf sbyte1,w ; ponemos el signo del mayor
btfss estado,ac ; (op2) )
goto cambiar
btfss estado,z
goto sr
movf pbyte2,w
subwf pbyte1,w
btfss estado,ac
goto cambiar
goto sr
btfss estado,z
goto cero ;Ponemos un cero en el resultado si son iguales
;los operandos y los restamos

sr btfss regest,7 ;Ponemos el signo del op1 si es el mayor
bcf regest,5 ; ³
btfsc regest,7 ; 
bsf regest,5
retlw 0

cambiar movf pbyte2,w ;si op2 > op1 ÄÄ>los intercambiamos
movwf presul ; ³
movf pbyte1,w ; ³
movwf pbyte2 ; 
movf presul,w
movwf pbyte1
movf sbyte2,w
movwf sresul
movf sbyte1,w
movwf sbyte2
movf sresul,w
movwf sbyte1
movf tbyte2,w
movwf tresul
movf tbyte1,w
movwf tbyte2
movf tresul,w
movwf tbyte1
btfss regest,6 ;Ponemos el signo del op2 en el resultado
bcf regest,5 ;porque es el mayor operando y lo hemos
btfsc regest,6 ;intercambiado
bsf regest,5
retlw 0

cero movlw 0x00 ;ponemos a 0 el resultado
movwf presul ; ³
movwf sresul ; 
movwf tresul
goto extrac

regerror call b_todo ;borra registros internos
call d_4seg
;call lcd1
call b_lcd ;inicializa el lcd
movlw 'E'
call lcd_datos ;escribe en el lcd el contenido del acumulador
reset goto reset
retfie



;**********RESTA**********
; ÍÍÍÍÍ
;****************************************************************************
;* *
;* 1.- Cambiamos el signo del segundo operando y vamos a la operacion *
;* de SUMA *
;* *
;****************************************************************************

restah bcf regest,3 ;cambiamos el signo del 2§ operando
btfsc regest,6 ;y nos vamos a la operacion de sumar
goto asd ;
bsf regest,6
goto sumah
asd bcf regest,6
goto sumah





;**********EXTRACCION DEL RESULTADO**********
; ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
;****************************************************************************
;* *
;* 1.- Dividimos el resultado entre 10 (con el algoritmo de division) *
;* 2.- El resto lo guardamos en una posicion de memoria (dato valido) *
;* 3.- Restauramos el cociente como resultado y volvemos al paso 1 *
;* *
;****************************************************************************

extrac movlw 0x23 ;inicializamos el FSR donde guardamos el
movwf fsr ;primer digito
movlw 0x08 ;inicializamos un contador con el numero
movwf diez ;maximo de digitos que puede tener el resultado

movf tresul,0 ;ALGORITMO DE DIVISION (explicado anteriormente)
movwf tbyte1 ; ³
movf sresul,0 ; ³
movwf sbyte1 ; 
movf presul,0
movwf pbyte1
bucle1v clrf cont1
clrf cont2
clrf cont3
movlw 0x18
movwf cont4
movlw 0x0a
movwf pbyte2
buclev bcf estado,ac
rlf cont3,f
bcf estado,ac
rlf cont2,f
btfsc estado,ac
bsf cont3,0
bcf estado,ac
rlf cont1,f
btfsc estado,ac
bsf cont2,0
bcf estado,ac
rlf tresul,f
btfsc estado,ac
bsf cont1,0
bcf estado,ac
rlf sresul,f
btfsc estado,ac
bsf tresul,0
bcf estado,ac
rlf presul,f
btfsc estado,ac
bsf sresul,0
movf cont1,w
movwf r1
movf cont2,w
movwf r2
movf cont3,w
movwf r3
movf pbyte2,w
subwf cont1,f
btfsc estado,ac
goto poner1v
movlw 0x01
subwf cont2,f
btfsc estado,ac
goto poner1v
movlw 0x01
subwf cont3,f
btfss estado,ac
; goto poner1v
goto poner0v

poner1v bsf presul,0
decfsz cont4,f
goto buclev
goto finalv

poner0v bcf presul,0
movf r1,w
movwf cont1
movf r2,w
movwf cont2
movf r3,w
movwf cont3
decfsz cont4,f
goto buclev

finalv movf cont1,w ;ponemos el resto de la division en la
movwf indf ;direccion indicada por el FSR
incf fsr,f ;incrementamos el FSR
clrw ;
decfsz diez,f ;decrementamos el contador diez
goto aqui ;si no es cero va a guardar el resultado
goto fin2 ;si es cero, acaba
aqui addwf presul,f ;miramos si el resultado es cero
btfss estado,z ;si es cero salta a relleno
goto bucle1v ;si no es cero hacemos otra iteracion
addwf sresul,f ; ³
btfss estado,z ; ³
goto bucle1v ; 
addwf tresul,f
btfss estado,z
goto bucle1v


relleno movlw 0x80 ;rellena donde no hay cifras significativas
movwf indf ;para sacar en el lcd
incf fsr,f
decfsz diez,f

goto relleno

;**************RUTINA QUE SACA EL RESULTADO POR EL LCD

fin2 call d_4seg
clrf intcon ;deshabilita las interrupciones
call lcd1 ;configura los puertos
call b_lcd ;borra el lcd

movf pbyte1,w ;³
btfss estado,2 ;³
goto p_menos ;³
movf sbyte1,w ;³
btfss estado,2 ;³mira si el resultado es cero
goto p_menos ;³si lo es no escribimos el signo
movf tbyte1,w ;³
btfss estado,2 ;³
goto p_menos ;³
bcf regest,7 ;³
goto cargar1 ;³

p_menos btfsc regest,5 ;testea el signo del resultado
call pmenos ;ponemos el signo - en el lcd
cargar1 movlw 0x2b ;Inicializa la posicion de la cifra mas alta
movwf fsr ;del resultado
cargar decf fsr,f ;decrementamos el FSR
movlw 0x22 ;mira a ver si es el ultimo numero ( que esta
subwf fsr,w ;en la posicion 22 )
btfsc estado,z ;
goto volver ;si ya ha terminado salta a volver
movlw 0x80 ;si no ha terminado compara con 80 el INDF
subwf indf,w ;para ver si es un dato valido
btfsc estado,z ;
goto cargar ;si no es un dato valido no lo escribe y vuelve
call lcd1 ;configura los puertos
movf indf,w ;mueve el INDF al acumulador
addlw d'48' ;y le suma 48 para obtener el equivalente en ascii
call lcd_datos ;escribe en el lcd el contenido del acumulador
goto cargar

volver clrf pbyte2 ;pone a cero el segundo operando
movlw 2 ;pone un 2 el clr para poder aprovechar el
movwf clr ;resultado como primer operando
bcf regest,6 ;pone a cero el signo del segundo operando
btfss regest,5 ;testea el signo del resultado
goto camb_bit ;si es cero salta a ponerlo a positivo
bsf regest,7 ;lo pone negativo
call vuelta ;habilita interrupciones antes de volver al programa principal
retfie
camb_bit bcf regest,7 ;lo pone positivo
call vuelta ;habilita interrupciones antes de volver al programa principal
retfie

pmenos call lcd1 ;configura los puertos
call delay_5ms
movlw '-'
call lcd_datos ;escribe en el lcd el contenido del acumulador
return

deshab bcf intcon,5 ;³deshabilita las
bcf intcon,2 ;³interrupciones

movlw 0x52 ;³
movwf cont5 ;³ponemos los contadores para
movlw 0x08 ;³temporizar 2 min. con el TMR0
movwf cont6 ;³
return

b_todo call lcd1 ;configura los puertos
call b_lcd ;borra el lcd

movlw 0x0c ;³
movwf fsr ;³
inc_fsr clrf indf ;³borramos todos los registros auxiliares
incf fsr,1 ;³con la ayuda del FSR
movlw 0x2b ;³
subwf fsr,0 ;³
btfss estado,2 ;³
goto inc_fsr ;³

movlw 1 ;³se pone a 1 el clr para indicar
movwf clr ;³que se tiene que eliminar el resultado
return

vuelta bsf estado,5 ;selecciona el banco uno
movlw 0xf0 ;ponemos <0:3> como salida y <4:7> como entrada
movwf trisb ;configura el puerto b
bcf estado,5 ;selecciona el banco cero
movlw 0xf0 ;ponemos el f0h en el puerto b
movwf portb ;
bsf estado,5 ;selecciona el banco uno
bcf option_reg,7 ;activamos pull-up
bcf estado,5 ;selecciona el banco cero
movlw 0xa8
movwf intcon ;habilita las interrupciones
return


d_4seg movlw 0x10 ;³
movwf cont3 ;³
vuel call delay_5ms ;³retardo de 1/8 seg.
decfsz cont3,1 ;³
goto vuel ;³
return

borrar movlw 1
movwf rr1 ;
;call lcd1 ;configuramos puertos
;movlw b'00000001' ;borra el lcd
;call lcd_reg
;call delay_5ms ; retardo de 5ms
call b_lcd ;borramos el lcd
return

;RUTINAS DEL LCD***********************************


;lce_e genera un pulso en la se¤al e de 1 us de duraci¢n. esto es posible
;gracias a la nop y a que el pic trabaja a 4mhz. para velocidades superiores
;habr que insertar alguna nop adicional para no rebasar la duraci¢n m¡nima
;del lcd

lcd_e bsf ra,2 ;activa e
nop ;pausa
bcf ra,2 ;desactiva e
return

;lcd_e bsf ra,2
; nop
; bcf ra,2
; bsf rb,7
; return

;lcd_busy chequea el estado del flag busy del lcd y espera a que finalice
;cualquier comando previo antes de retornar

lcd_busy bsf ra,1 ;pone el lcd en modo rd
bsf estado,5 ;selecciona el banco 1
movlw 0xff
movwf trisb ;puerta b es entrada
bcf estado,5 ;selecciona el banco 0
bsf ra,2 ;activa el lcd (e)
nop
l_busy btfsc rb,7 ;chequea el bit busy
goto l_busy
bcf ra,2 ;desactiva el lcd (e)
bsf estado,5 ;selecciona el banco 1
clrf trisb ;puerta b salida
bcf estado,5 ;selecciona el banco 0
bcf ra,1 ;pone el lcd en modo wr
return

;lcd_dato deposita el c¢digo ascii presente en w, sobre rb. espera que el
;lcd ejecute la £ltima operaci¢n y genera el pulso e.

lcd_datos bcf ra,0 ;desactiva rs (modo comando)
movwf rb ;valor ascii a sacar por rb
call lcd_busy ;espera que se libere el lcd
bsf ra,0 ;activa rs (modo dato)
goto lcd_e ;genera pulso en se¤al e

;lcd_reg deposita el c¢digo del comando presente en w, sobre rb. espera que
;el lcd ejecute la £ltima operaci¢n y genera el pulso e.

lcd_reg bcf ra,0 ;desactiva rs (modo comando)
movwf rb ;c¢digo del comando
call lcd_busy ;espera que se libere el lcd
goto lcd_e ;genera pulso en se¤al e

;lcd_ini realiza la inicializaci¢n del lcd seg£n los tiempos marcados por el
;fabricante. se inicia con un interface de 8 bits, 1 l¡neas de visualizaci¢n,
;y caracteres de 5 * 7. se temporiza 15 ms.


lcd_ini movlw b'00110000'
call lcd_reg
call delay_5ms ;retardo de 5ms.
movlw b'00110000'
call lcd_reg
call delay_5ms ;retardo de 5ms.
movlw b'00110000'
call lcd_reg
call delay_5ms ;retardo de 5ms.
return

;delay_5ms genera una temporizaci¢n de 5ms necesario para la secuencia de
;inicio del lcd

delay_5ms movlw 0x1a
movwf cont2
clrf cont1
delay_1m decfsz cont1,f
goto delay_1m
decfsz cont2,f
goto delay_1m
return

lcd1 bsf estado,5 ;Selecciona el banco 1 de datos
clrf trisb ;RB se programa como salida
movlw b'00011000' ;RA<4:3> se programan como entradas
movwf trisa ;RA<2:0> se programan como salidas
bcf estado,5 ;Selecciona el banco 0 de datos
bcf ra,0 ;Desactiva RS del m¢dulo LCD
bcf ra,2 ;Desactiva E del m¢dulo LCD
call delay_5ms ;retardo de 5ms.
return


inicial call lcd1 ;configura los puertos
movlw b'00000001' ;Borrar LCD y Home
call lcd_reg
movlw b'00000110'
call lcd_reg
movlw b'00001100' ;LCD On, cursor On
call lcd_reg
call delay_5ms ;retardo de 5ms.
return

b_lcd ; call lcd1 ;configura los puertos
movlw b'00000001' ;borra el lcd
call lcd_reg
call delay_5ms ; retardo de 5ms
return
end

ADJUNTE EL ARCHIVO, PERO NO SE SI QUEDO BIEN ADJUNTADO, POR ESO PUSE AQUÍ, ESPERO Y ME PUEDAN HECHAR UNA MANO CON ESO SE LOS AGRADECERIA MUCHO, GRACIAS
 

Adjuntos

  • CALCULADORA.txt
    62.7 KB · Visitas: 36
Atrás
Arriba