Autor Tema: Error decrementando numero en display  (Leído 2791 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado markz

  • PIC10
  • *
  • Mensajes: 6
Error decrementando numero en display
« en: 11 de Noviembre de 2018, 12:19:48 »
Hola, necesito de ayuda en un problema, hice un programa que incrementa y decrementa numeros de 3 cifras en 3 displays, pero en la hora de decrementar salta siempre los numeros que terminan en 0, como por ejemplo de 21 a 19, salta el 20.
el codigo es muy largo entonces solo pongo las partes que hacen referencia a la incrementacion y decrementacion de los displays.
d1 es el ultimo display (la ultima unidad del numero de 3 cifras), y d2 es el segundo display (la segunda unidad)
muchas gracias.

Código: ASM
  1. BOTONES
  2.  
  3.                 BTFSC   BTN_G1
  4.                 CALL    DEMORA_AR
  5.                 BTFSC   BTN_G1
  6.                 CALL    SUMAR
  7.  
  8.                 BTFSC   BTN_G2
  9.                 CALL    DEMORA_AR
  10.                 BTFSC   BTN_G2
  11.                 CALL    RESTAR
  12.        
  13.                 BTFSC   BTN_R
  14.                 CALL    DEMORA_AR
  15.                 BTFSC   BTN_R
  16.                 CALL    SUMAR
  17.  
  18.                 BTFSC   BTN_M
  19.                 CALL    DEMORA_AR
  20.                 BTFSC   BTN_M
  21.                 CALL    SUMAR
  22.  
  23.                 GOTO    BOTONES
  24.  
  25. ;Demora
  26. DEMORA_AR
  27.                 MOVLW   .255
  28.                 MOVWF   CONT_AR
  29. LOOP_AR
  30.                 MOVLW   .255
  31.                 MOVWF   CONT_AR_2
  32. LOOP_AR_2
  33.                 DECFSZ  CONT_AR_2,1
  34.                 GOTO    LOOP_AR_2
  35.                 DECFSZ  CONT_AR,1
  36.                 GOTO    LOOP_AR
  37.                 RETURN
  38.  
  39.        
  40. SUMAR                                                  
  41.                 INCF    D1,1
  42.                 MOVF    D1,W
  43.                 XORLW   .10                     ;      
  44.                 BTFSS   STATUS,Z                ;IF LLEGA A 16 SALTA
  45.                 GOTO    VOLVER
  46.                 CALL    SUMAR2
  47.   VOLVER       
  48.                 RETURN
  49.  
  50. SUMAR2
  51.                 INCF    D2,1
  52.                 MOVF    D2,W
  53.                 CLRF    D1
  54.                 XORLW   .10                            
  55.                 BTFSS   STATUS,Z                ;IF LLEGA A 16 SALTA
  56.                 GOTO    VOLVER2
  57.                 CALL    SUMAR3
  58.   VOLVER2      
  59.                 RETURN
  60.  
  61. SUMAR3
  62.                 INCF    D3,1
  63.                 MOVF    D3,W
  64.                 CLRF    D2
  65.                 RETURN
  66.  
  67. RESTAR                                                 
  68.                 DECF    D1,1
  69.                 MOVF    D1,W
  70.                 XORLW   .0
  71.                 BTFSS   STATUS,Z                        ;SI LLEGA A 0 SALTA
  72.                 GOTO    VOLVERR
  73.                 CALL    RESTAR2
  74.  VOLVERR
  75.                 RETURN
  76.  
  77. RESTAR2
  78.                 DECF    D2,1
  79.                 MOVF    D2,W
  80.                 MOVLW   .10
  81.                 MOVWF   D1
  82.                 GOTO    RESTAR

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Error decrementando numero en display
« Respuesta #1 en: 12 de Noviembre de 2018, 08:27:24 »
Hay distintas formas de llegar a tu resultado... La primera es usar un entero comun y luego usar un codigo que transforme a BCD. De esa forma los incrementos y decrementos se hace mas sencillo, ya que es un INCF y un DECF, revisando que no supere los 999 o el 0.

La otra es trabajarlo en BCD directamente, como estas haciendo vos. La parte del incremento esta bien.. solo corregiria un poco las funciones para quitar el "GOTO VOLVER" es decir asi:

Código: ASM
  1. SUMAR                                                  
  2.                 INCF    D1, F
  3.                 MOVF    D1,W
  4.                 XORLW   .10                     ;      
  5.                 BTFSS   STATUS,Z                ;IF LLEGA A 10 SALTA
  6.                 RETURN
  7. SUMAR2
  8.                 INCF    D2, F
  9.                 MOVF    D2,W
  10.                 CLRF    D1
  11.                 XORLW   .10                            
  12.                 BTFSS   STATUS,Z                ;IF LLEGA A 10 SALTA
  13.                 RETURN
  14. SUMAR3
  15.                 INCF    D3, F
  16.                 MOVF    D3,W
  17.                 CLRF    D2
  18.                 XORLW   .10                            
  19.                 BTFSC   STATUS,Z                ;IF LLEGA A 10 BORRA
  20.                 CLRF    D3
  21.                 RETURN

Ni siquiera me hacen falta SUMAR2/SUMAR3 pero los deje para que quede mejor explicado.
Esta parte esta "bien"... llega a 10 ( se paso del 9 ) borras y aumentas el que sigue... Te faltaria una sola cosa... y es la que le agregue, es decir el borrado de D3 cuando supera el 9, asi de esa forma pasando los 999 queda en 000. Sino necesitas evitar esto y que todo quede en 999, eso queda a tu eleccion.
El problema mayor esta en la resta.

Observemos el programa:

Código: ASM
  1. RESTAR                                                  
  2.                 DECF    D1,1
  3.                 MOVF    D1,W
  4.                 XORLW   .0
  5.                 BTFSS   STATUS,Z                        ;SI LLEGA A 0 SALTA
  6.                 GOTO    VOLVERR
  7.                 CALL    RESTAR2
  8.  VOLVERR
  9.                 RETURN

Observandolo dice que cuando D1 llega a 0 , es decir al entrar estaba en 1, se decrementa y se pregunta si llego a 0, de alli tomo la decision de modificarlo. En resumen, si entra un 1 termina saliendo un 9, por eso nunca te va a funcionar... Lo que deberias detectar vos es cuando se produce un underflow, es decir cuando entre en 0 al decrementarse va a pasar a 255 ( 0xFF ) y eso es lo que necesitas detectar. No podemos usar las banderas de carry por que el DECF solo modifica la del ZERO. Entonces:

Código: ASM
  1. RESTAR                                                  
  2.                 DECF    D1, F
  3.                 MOVF    D1,W
  4.                 XORLW   .255
  5.                 BTFSS   STATUS,Z                        ;SI LLEGA A 0 SALTA
  6.                 RETURN
  7. RESTAR2
  8.                 MOVLW   .9                                   ;RECARGO CON 9
  9.                 MOVWF   D1
  10.                 DECF    D2, F
  11.                 MOVF    D2, W
  12.                 XORLW   .255
  13.                 BTFSS   STATUS,Z                        ;SI LLEGA A 0 SALTA
  14.                 RETURN
  15. RESTAR3
  16.                 MOVLW   .9                                   ;RECARGO CON 9
  17.                 MOVWF   D2
  18.                 DECF    D3, F
  19.                 MOVF    D3, W
  20.                 XORLW   .255
  21.                 BTFSS   STATUS,Z                        ;SI LLEGA A 0 SALTA
  22.                 RETURN
  23.                 MOVLW  .9
  24.                 MOVWF  D3
  25.                 RETURN

Ahora si entra con 000, el primer estar al decrementar detectaria el underflow y lo dejaria 009, obviamente que a medida que continuemos va a hacer que esto llegue a 999. pero ahora si estabamos en 21, al decrementar y entrar un 1 la condicion de igualdad no se va a cumplir y la salida va a ser 0, formando el 20

Desconectado markz

  • PIC10
  • *
  • Mensajes: 6
Re:Error decrementando numero en display
« Respuesta #2 en: 22 de Noviembre de 2018, 23:10:42 »
Hola KILLERJC como estas? Muchas gracias por su ayuda.
Ahora te consulto por otro problema que estoy intentando resolver...

En mi programa quiero hacer lo siguiente: Hacer una resta de digito a digito (son 3 digitos en 3 displays), pero tengo un problema al querer hacer una resta negativa con 3 cifras (por ejemplo 114-132 = se me rompe el programa.) lo que si pude hacer es la resta negativa con 2 cifras o 1 cifra.

Lo que hice fue lo siguiente: Primero incremento los numeros de 3 digitos, por ejemplo si quiero poner 114. voy guardando en las variables DIGITO1A = 1, DIGITO2A = 1, DIGITO3A = 4. Luego con un boton, reseteo los numeros e incremento denuevo, en este caso quiero poner 132, que voy guardando en otras variables que seria DIGITO1B=1, DIGITO2B=3, DIGITO3B=2 y con esas variables, hacer una resta presionando un boton restar.

hago lo siguiente en el digito 4 de display para que me muestre el signo menos ( - ) del negativo.
      
Código: [Seleccionar]
MOVLW b'10000001'
MOVWF D4


Aqui esta el codigo de las restas que es lo mas importante:

Código: [Seleccionar]
RESTA_1
MOVF D1,W
MOVWF DIGITO1B
MOVF D2,W
MOVWF DIGITO2B
MOVF D3,W
MOVWF DIGITO3B

MOVF DIGITO1B,W ;file pasa a w.
SUBWF DIGITO1A,W ;f-w. Se guarda en w.
BTFSS STATUS,C ;si es positivo salta
GOTO RESTAR_NEG
MOVWF D1

MOVF DIGITO2B,W ;file pasa a w.
SUBWF DIGITO2A,W ;f-w. Se guarda en w.
BTFSS STATUS,C ;si es positivo salta
GOTO RESTAR_NEG
MOVWF D2
GOTO FIN

RESTAR_NEG
MOVF DIGITO2B,W ;file pasa a w.
SUBWF DIGITO2A,W ;f-w. Se guarda en w.
BTFSC STATUS,Z ;SI ES 0 NO SALTA
GOTO NEGATIVOASEGURADO
BTFSS STATUS,C ;SI ES POSITIVO SALTA. SI NO SALTA NOS ASEGURAMOS QUE EL NUM ES NEGATIVO(SOLO DOS CIFRAS)
GOTO NEGATIVOASEGURADO

MOVLW .10
ADDWF DIGITO1A,F ;se guarda en file=1. en w=0.
MOVF DIGITO1B,W
SUBWF DIGITO1A,W ;f-w
MOVWF D1
MOVLW .1
SUBWF DIGITO2A

MOVF DIGITO2B,W ;file pasa a w.
SUBWF DIGITO2A,W ;f-w. Se guarda en w.
MOVWF D2
GOTO FIN



NEGATIVOASEGURADO

MOVF DIGITO1A,W ;file pasa a w.
SUBWF DIGITO1B,W ;f-w. Se guarda en w.
BTFSS STATUS,C ;si es positivo salta
GOTO RESTAR_NEGNEG
MOVWF D1

MOVF DIGITO2A,W ;file pasa a w.
SUBWF DIGITO2B,W ;f-w. Se guarda en w.
MOVWF D2

MOVLW b'10000001'
MOVWF D4
; GOTO $
GOTO FIN


RESTAR_NEGNEG
MOVLW .10
ADDWF DIGITO1B,F ;se guarda en file=1. en w=0.
MOVF DIGITO1A,W
SUBWF DIGITO1B,W ;f-w
MOVWF D1

MOVLW .1
SUBWF DIGITO2B

MOVF DIGITO2A,W ;file pasa a w.
SUBWF DIGITO2B,W ;f-w. Se guarda en w.
MOVWF D2


MOVLW b'10000001'
MOVWF D4

GOTO $


FIN
RETURN


por las dudas dejo el codigo completo:

Código: [Seleccionar]
#INCLUDE<P16F628A.INC>
__CONFIG 3F10

;DECLARACION DE ESPACIOS DE MEMORIA A USAR
CBLOCK 0X20
D1
D2
D3
D4
AUX_W
AUX_STATUS
CONT_AR
CONT_AR_2
DIGITO1A
DIGITO2A
DIGITO3A
DIGITO1B
DIGITO2B
DIGITO3B
AUX
ENDC

;DECLARACION DE CONSTATNES
#DEFINE BTN_G1 PORTA,6
#DEFINE BTN_G2 PORTA,7
#DEFINE BTN_R PORTA,4
#DEFINE BTN_M PORTB,0

#DEFINE PIN_D4 3 ;D1 POR D4
#DEFINE PIN_D3 2 ;D2 POR D3
#DEFINE PIN_D1 1 ;D3 POR D1
#DEFINE PIN_D2 0 ;D4 POR D2

#DEFINE CTRL_DISPLAY PORTA
#DEFINE APAGAR_DISPLAYS CLRF PORTA

;DECLARACION DE MACROS

MOSTRAR MACRO DIGITO,PIN
APAGAR_DISPLAYS
MOVF DIGITO,W
CALL TAB_DISPLAY
MOVWF PORTB
BSF CTRL_DISPLAY,PIN
ENDM


;INICIO DEL PROGRAMA

ORG 0X00
GOTO CONFI
ORG 0X04

;RUTINA DE INTERRUPCION
;DESBORDA EL TIMER CADA 15ms
;MUESTRA TODOS LOS DIGITOS DE ACUERDO A LAS VARIABLES D1:4

;GUARDA STATUS Y W EN VARIABLES AUXILIARES
BCF INTCON,T0IF
BCF INTCON,GIE
MOVWF AUX_W
MOVLW STATUS
MOVWF AUX_STATUS

;MULTIPLEXADO DE DISPLAYS
BTFSC CTRL_DISPLAY,PIN_D1
GOTO MOSTRAR_D2
BTFSC CTRL_DISPLAY,PIN_D2
GOTO MOSTRAR_D3
BTFSC CTRL_DISPLAY,PIN_D3
GOTO MOSTRAR_D4

MOSTRAR_D1
MOSTRAR D1,PIN_D1
GOTO FIN_T0I

MOSTRAR_D2
MOSTRAR D2,PIN_D2
GOTO FIN_T0I

MOSTRAR_D3
MOSTRAR D3,PIN_D3
GOTO FIN_T0I

MOSTRAR_D4
MOSTRAR D4,PIN_D4

FIN_T0I
;REINICIA TIMER Y RECUPERA STATUS Y W
MOVLW .198
MOVWF TMR0
MOVF AUX_STATUS,W
MOVWF STATUS
MOVF AUX_W,W
RETFIE

;CONFIGURACION

CONFI
MOVLW 0X07
MOVWF CMCON ;CMCON SE TIENE QUE ESTABLECER EN 7 PARA USAR TODO EL PORTA
MOVLW .198
MOVWF TMR0
BSF STATUS,RP0
MOVLW b'00000001'
MOVWF TRISB
MOVLW b'11110000'
MOVWF TRISA
BCF OPTION_REG,T0CS
BCF OPTION_REG,PSA
BSF OPTION_REG,PS0
BSF OPTION_REG,PS1
BSF OPTION_REG,PS2
BSF INTCON,GIE
BSF INTCON,T0IE
BCF STATUS,RP0

;RUTINA PRINCIPAL
;INCREMENTA DE 0 A (F) CADA DIGITO DEPENDIENDO QUE BOTON SE TOCA.

CLRF PORTA
CLRF PORTB
CLRF D1
CLRF D2
CLRF D3
CLRF D4



BOTONES

BTFSC BTN_G1
CALL DEMORA_AR
BTFSC BTN_G1
CALL SUMAR

BTFSC BTN_G2
CALL DEMORA_AR
BTFSC BTN_G2
CALL RESTAR

BTFSC BTN_R
CALL DEMORA_AR
BTFSC BTN_R
CALL LIMPIAR

BTFSC BTN_M
CALL DEMORA_AR
BTFSC BTN_M
CALL LIMPIAR

GOTO BOTONES

BOTONES2
BTFSC BTN_G1
CALL DEMORA_AR
BTFSC BTN_G1
CALL SUMAR4

BTFSC BTN_G2
CALL DEMORA_AR
BTFSC BTN_G2 ;SI ESTA APRETADO NO SALTA
CALL RESTAR

BTFSC BTN_M
CALL DEMORA_AR
BTFSC BTN_M ;SI ESTA APRETADO no SALTA
CALL RESTA_1

BTFSC BTN_R
CALL DEMORA_AR
BTFSC BTN_R
CALL LIMPIAR

GOTO BOTONES2


;Demora
DEMORA_AR
MOVLW .255
MOVWF CONT_AR
LOOP_AR
MOVLW .255
MOVWF CONT_AR_2
LOOP_AR_2
DECFSZ CONT_AR_2,1
GOTO LOOP_AR_2
DECFSZ CONT_AR,1
GOTO LOOP_AR
RETURN

SUMAR
INCF D1,1
MOVF D1,W
XORLW .10
BTFSS STATUS,Z ;IF LLEGA A 16 SALTA
GOTO VOLVER
CALL SUMAR2
VOLVER

RETURN

SUMAR2
INCF D2,1
MOVF D2,W
CLRF D1
XORLW .10
BTFSS STATUS,Z ;IF LLEGA A 16 SALTA
GOTO VOLVER2
CALL SUMAR3
VOLVER2

RETURN

SUMAR3
INCF D3,1
MOVF D3,W
CLRF D2

RETURN

SUMAR4
INCF D1,1
MOVF D1,W
XORLW .10
BTFSS STATUS,Z ;IF LLEGA A 16 SALTA
GOTO VOLVER4
CALL SUMAR5
VOLVER4

RETURN

SUMAR5
INCF D2,1
MOVF D2,W
CLRF D1
XORLW .10
BTFSS STATUS,Z ;IF LLEGA A 16 SALTA
GOTO VOLVER5
CALL SUMAR6
VOLVER5

RETURN

SUMAR6
INCF D3,1
MOVF D3,W
CLRF D2

RETURN

RESTAR                                                 
                DECF    D1, F
                MOVF    D1,W
                XORLW   .255
                BTFSS   STATUS,Z                        ;SI LLEGA A 0 SALTA
                RETURN
RESTAR2
                MOVLW   .9                                   ;RECARGO CON 9
                MOVWF   D1
                DECF    D2, F
                MOVF    D2, W
                XORLW   .255
                BTFSS   STATUS,Z                        ;SI LLEGA A 0 SALTA
                RETURN
RESTAR3
                MOVLW   .9                                   ;RECARGO CON 9
                MOVWF   D2
                DECF    D3, F
                MOVF    D3, W
                XORLW   .255
                BTFSS   STATUS,Z                        ;SI LLEGA A 0 SALTA
                RETURN
                MOVLW  .9
                MOVWF  D3
                RETURN



LIMPIAR
MOVF D1,W
MOVWF DIGITO1A
MOVF D2,W
MOVWF DIGITO2A
MOVF D3,W
MOVWF DIGITO3A
CLRF D1
CLRF D2
CLRF D3
GOTO BOTONES2
RETURN



;la resta funciona medio limitada.
;resta entre numeros de una cifra -> funciona.
;resta de doscifras-unacifra -> funciona.
;resta de unacifra-doscifras -> segun el caso. Ejemplo: 7-18 si. 7-16 no.
;resta de tres cifras  -> ni intente jej.

RESTA_1
MOVF D1,W
MOVWF DIGITO1B
MOVF D2,W
MOVWF DIGITO2B
MOVF D3,W
MOVWF DIGITO3B

MOVF DIGITO1B,W ;file pasa a w.
SUBWF DIGITO1A,W ;f-w. Se guarda en w.
BTFSS STATUS,C ;si es positivo salta
GOTO RESTAR_NEG
MOVWF D1

MOVF DIGITO2B,W ;file pasa a w.
SUBWF DIGITO2A,W ;f-w. Se guarda en w.
BTFSS STATUS,C ;si es positivo salta
GOTO RESTAR_NEG
MOVWF D2
GOTO FIN

RESTAR_NEG
MOVF DIGITO2B,W ;file pasa a w.
SUBWF DIGITO2A,W ;f-w. Se guarda en w.
BTFSC STATUS,Z ;SI ES 0 NO SALTA
GOTO NEGATIVOASEGURADO
BTFSS STATUS,C ;SI ES POSITIVO SALTA. SI NO SALTA NOS ASEGURAMOS QUE EL NUM ES NEGATIVO(SOLO DOS CIFRAS)
GOTO NEGATIVOASEGURADO

MOVLW .10
ADDWF DIGITO1A,F ;se guarda en file=1. en w=0.
MOVF DIGITO1B,W
SUBWF DIGITO1A,W ;f-w
MOVWF D1
MOVLW .1
SUBWF DIGITO2A

MOVF DIGITO2B,W ;file pasa a w.
SUBWF DIGITO2A,W ;f-w. Se guarda en w.
MOVWF D2
GOTO FIN



NEGATIVOASEGURADO

MOVF DIGITO1A,W ;file pasa a w.
SUBWF DIGITO1B,W ;f-w. Se guarda en w.
BTFSS STATUS,C ;si es positivo salta
GOTO RESTAR_NEGNEG
MOVWF D1

MOVF DIGITO2A,W ;file pasa a w.
SUBWF DIGITO2B,W ;f-w. Se guarda en w.
MOVWF D2

MOVLW b'10000001'
MOVWF D4
; GOTO $
GOTO FIN


RESTAR_NEGNEG
MOVLW .10
ADDWF DIGITO1B,F ;se guarda en file=1. en w=0.
MOVF DIGITO1A,W
SUBWF DIGITO1B,W ;f-w
MOVWF D1

MOVLW .1
SUBWF DIGITO2B

MOVF DIGITO2A,W ;file pasa a w.
SUBWF DIGITO2B,W ;f-w. Se guarda en w.
MOVWF D2


MOVLW b'10000001'
MOVWF D4

GOTO $


FIN
RETURN
« Última modificación: 22 de Noviembre de 2018, 23:23:59 por markz »

Desconectado AleSergi

  • PIC16
  • ***
  • Mensajes: 214
Re:Error decrementando numero en display
« Respuesta #3 en: 23 de Noviembre de 2018, 10:59:11 »
Yo en tu lugar de programador asm,  visito y agendo la. siguiente página

http://www.piclist.com/techref/microchip/math/basic.htm

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Error decrementando numero en display
« Respuesta #4 en: 23 de Noviembre de 2018, 23:32:19 »
Creo que antes de comenzar a restar primero compararia ambos numeros, para saber cual es mas grande asi saber el signo... luego resto el mas pequeño al mas grande.

Hay otras formas de hacerlo pero espero que esto te ayude.