Autor Tema: problemas con assembler una ayudita por favor  (Leído 2481 veces)

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

Desconectado M@XI

  • PIC10
  • *
  • Mensajes: 5
problemas con assembler una ayudita por favor
« en: 04 de Octubre de 2015, 15:35:33 »
hola como eststas?? disculpen las molestias pero tengo que hacer un trabajo para la facultad en assembler y la verdad no entiendo nada...hice asta donde pude y ya no entiendo nada queria saber si me podrias dar una mano y sacarme de este pozo ya que no encuentro la salida de este problema
los problemas que tengo son con la memoria eeprom y con unos retardos y creo que eso es todo....
 
PD: desde ya muchas gracias...espero su respuesta

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: problemas con assembler una ayudita por favor
« Respuesta #1 en: 04 de Octubre de 2015, 15:45:49 »
Seria util que pusieras exactamente que problemas tenes con esos casos. Tambien que microcontrolador estas usando. Ejemplo:

- No se escribir / leer la memoria EEPROM, no encontre codigos que lo hagan, etc
- No se crear delays , o no entiendo como es que X codigo termina siendo un delay, como calculo el tiempo que tarda en ejecutarse este codigo.

Dependiendo del PIC tambien va a cambiar una que otra instrucciones,registro, etc.
Por eso mismo intenta explayarte mas.

Citar
Tengo este codigo


------


Y quiero guardar ese dato en la EEPROM. Esto lo quiero hacer unicamente cuando ....
Y luego quiero crear una demora para que el led este encendido 1 segundo
« Última modificación: 04 de Octubre de 2015, 15:47:52 por KILLERJC »

Desconectado M@XI

  • PIC10
  • *
  • Mensajes: 5
Re: problemas con assembler una ayudita por favor
« Respuesta #2 en: 04 de Octubre de 2015, 15:49:50 »
es verdad me re olvide utilizo un pic16f628a

uno de mi problemas es que quiero guardar y que lea la memoria eeprom pero no encontre un codigo que me explique como hacerlo con dos variables osea yo estoy haciendo un contador que va de 0 a 20 y tiene dos contadores uno para unidades y otro para decenas y mi problema es como hago eso que guarde un valor por ejemplo el 15...en el data sheet mucho no lo entendi....

si quieren pongo mi codigo para que me ayuden a ubicar el problema y tambien a ubicar en donde pongo lo de la eeprom

Desconectado M@XI

  • PIC10
  • *
  • Mensajes: 5
Re: problemas con assembler una ayudita por favor
« Respuesta #3 en: 04 de Octubre de 2015, 15:51:31 »
Código: [Seleccionar]
;---------------------CONFIGURO EL PIC--------------------------
__CONFIG _CP_OFF&_LVP_OFF&_WDT_OFF&_PWRTE_ON&_XT_OSC

LIST P=16F628A
#INCLUDE <P16F628A.INC>
;--------------------------------------------------------------
;----------------DECLARO LAS VARIABLES-------------------------
CBLOCK 0X20
UNIDAD
DECENA
CONT1
CONT2
CONT3
ENDC
;---------------------------------------------------------------
;--------CONFIGURO LOS PUERTOS Y PONGO LAS VARIABLES EN 0-------

PRINCIPAL
BSF STATUS,5
CLRF TRISA
BCF OPTION_REG,7
MOVLW B'00000001'
MOVWF TRISB
BCF STATUS,5
MOVLW D'7'
MOVWF CMCON
CLRF PORTB
CLRF DECENA
CLRF UNIDAD

BOT BTFSC PORTB,0
GOTO BOT
BTFSS PORTB,0
GOTO INICIO
;----------------------------------------------------------------
;-------------VERIFICO QUE NO LLEGUE A DIEZ----------------------
INICIO
BTFSS UNIDAD,1
GOTO UNIDADES
BTFSS UNIDAD,3
GOTO UNIDADES

CLRF UNIDAD
INCF DECENA,1
BTFSS DECENA,1
GOTO DECENAS
BTFSS DECENA,3
GOTO DECENAS
CLRF DECENA
GOTO BOT
;-----------------------------------------------------------------
;----------------------REALIZO EL CONTEO--------------------------
UNIDADES
MOVLW B'00000001'
MOVWF PORTA
MOVF UNIDAD,0
CALL TABUNIDAD
MOVWF PORTB
CALL RETARDO
INCF UNIDAD,1

DECENAS
MOVLW B'00000000'
MOVWF PORTA
MOVF DECENA,0
CALL TABDECENAS
MOVWF PORTB
CALL RETARDO
GOTO BOT
;------------------------------------------------------------------
;---------------------DECLARO LAS TABLAS---------------------------
TABUNIDAD
ADDWF PCL,1
RETLW B'01111110';0
RETLW B'00001100';1
RETLW B'10110110';2
RETLW B'10011110';3
RETLW B'11001100';4
RETLW B'11011010';5
RETLW B'11111010';6
RETLW B'00001110';7
RETLW B'11111110';8
RETLW B'11001110';9
RETURN

TABDECENAS
ADDWF PCL,1
RETLW B'01111110';0
RETLW B'00001100';1
RETLW B'10110110';2
RETLW B'10011110';3
RETLW B'11001100';4
RETLW B'11011010';5
RETLW B'11111010';6
RETLW B'00001110';7
RETLW B'11111110';8
RETLW B'11001110';9
RETURN
;----------------------------------------------------------------------
;------------------------REALIZO EL RETARDO----------------------------
RETARDO
MOVLW 0xC3
MOVWF CONT1
LOOP1
MOVLW 0x2E
MOVWF CONT2
LOOP2
MOVLW 0X03
MOVWF CONT3
LOOP3
DECFSZ CONT3,1
GOTO LOOP3
DECFSZ CONT2,1
GOTO LOOP2
DECFSZ CONT1,1
GOTO LOOP1
RETURN
;-------------------------------------------------------------------------------------
END

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: problemas con assembler una ayudita por favor
« Respuesta #4 en: 04 de Octubre de 2015, 16:26:03 »
La EEPROM tiene varios registros, y estan el el banco 1. Pensa en la EEPROM como otra memoria aparte la cual comienza en 0x00 y en ese PIC ocupa hasta la direccion 0x7F , es decir 128 posiciones de memoria o 128bytes.

Entonces para leer la EEPROM debemos:

- Asegurarnos que estemos en el banco 1 ya que ahi estan los registros
- Indicarle la direccion que queremos leer
- Luego decirle al modulo de la EEPROM que lea, para que tome el dato y lo ponga en el registro EEDATA
- Fin

Para escribir es un poco mas complejo ya que tiene unos mecanismos de proteccion de esa forma no cualquier ruido o mal manejo por parte del usuario puede cambiar esos datos.

- Nuevamente me aseguro  que este en el banco 1
- Cargo el valor a escribir en EEDATA, y le digo en que direccion ponerlo con EEADR
- Algo crucial si es que usas interrupciones, es que esten desabilitadas al momento de escribir la EEPROM, para que no ocurra una interrupcion en el medio de la escritura, asi que la desactivamos
- Luego como dije hay un mecanismo de proteccion, que es escribir 0x55 y 0xAA ( en ese orden ) en EECON2 , solo para que esto no ocurra por "error", si no haces esto cuando le das la orden de escribir , no escribe nada.
- Finalmente le damos la orden que escriba en la memoria.
- De usar las interrupciones volvemos a activarlas, sino las dejamos asi



Eso que nombre esta en los codigos del datasheet:
Lo acomode un poco.. en este caso uso 2 registros ( definidos por vos ) que son llamdos:

DIRECCION y DATOEE

Leer:

Código: ASM
  1. LeeEEPROM:
  2.         MOVF    DIRECCION,W     ; CONFIG_ADDR = direccion del dato
  3.         BSF     STATUS,RP0      ; Bank 1
  4.         MOVWF   EEADR           ; Direccion a leer
  5.         BSF     EECON1,RD       ; Avisamos que queremos leer asi EEDATA se carga con el valor
  6.         MOVF    EEDATA,W        ; ubicado en la direccion CONFIG_ADDR de la moemoria EEPROM
  7.         BCF     STATUS,RP0      ; y guardamos en W, procedemos a volver al banco 0
  8.         MOVWF   DATOEE 
  9.         RETURN
   

Eso es para leer la EEPROM, como usarla ? Supongamos que guardas los valores asi:

Direccion 0x00 - Unidades
Direccion 0x01 - Decenas

Si quisiera leer las Decenas, lo que haria es lo siguiente:

Código: ASM
  1. MOVLW   0x01
  2.         MOVWF   DIRECCION
  3.         CALL    LeeEEPROM

El dato leido va a estar en DATOEE.
Si hubiera querido leer las Unidades, solo ponia un 0x00 en DIRECCION

Ahora para escribir:

Código: ASM
  1. EscribirEEPROM:
  2.         MOVF    DATOEE,W        ; Cargo el valor a escribir
  3.         BSF     STATUS,RP0      ; Banco 1
  4.         MOVWF   EEDATA
  5.         BCF     STATUS,RP0      ; Banco 0
  6.         MOVF    DIRECCION,W     ; Cargo direccion a escribir
  7.         BSF     STATUS,RP0      ; Banco 1
  8.         MOVWF   EEADR
  9.         BSF     EECON1,WREN     ; Habilitamos la escritura de la EEPROM
  10.         ;Codigo obligatorio
  11.         BCF     INTCON,GIE      ; Desabilitamos interrupciones ya que afectarian la escritura
  12.         MOVLW   0x55            ; Una proteccion que posee la EEPROM, es que antes de escribir
  13.         MOVWF   EECON2          ; debe escribirse los valores 0x55 y 0xAA en orden
  14.         MOVLW   0xAA
  15.         MOVWF   EECON2
  16.         BSF     EECON1,WR       ; Finalmente podemos darle la orden que escriba en la EEPROM
  17.         ;Fin codigo obligatorio
  18.  
  19.         BSF     INTCON,GIE      ; De usar interrupciones las habilitamos de nuevo
  20.         BCF     STATUS,RP0      ; Banco 0
  21.         RETURN

Y como usarlo ?, esta ves voy a guardar las unidades

Código: ASM
  1. MOVF    Unidades,W
  2.         MOVWF   DATOEE
  3.         MOVLW   0x00
  4.         MOVWF   DIRECCION
  5.         CALL    EscribirEEPROM

Lo que mover las unidades a DATOEE ( es decir el dato a guardar ) y le digo que lo ponga en la direccion 0x00 y llamo a la funcion que va a escribir el dato.

Nuevamente si no usas interrupciones esta linea al final de la escritura no hace falta.

   BSF   INTCON,GIE   ; De usar interrupciones las habilitamos de nuevo

---------------------------------

Con respecto a los delays, si queres crear alguno, hay paginas online que lo hacen

http://www.piclist.com/techref/piclist/codegen/delay.htm

- En Delay pones el tiempo en segundos ( o en ciclos de instruccion )
- Temporary Register podes dejarlo como esta, o cambiarle el nombre a unos registros creados por vos ( que los tengas tambien para usarlos de forma temporal )
- Luego pones bien el valor de frecuencia de cristal, si es 4Mhz, o si es que tiene oscilador interno le pones el valor del mismo, etc.
- Tilda donde dice "Generate Routine" , y le podes poner el nombre que quieras.

Un ejemplo:

Delay 1s
Dejo los registros como estan
Tengo un oscilador interno de 8Mhz
Y quiero que mi rutina se llama Delay_1s

Codigo creado:

Código: ASM
  1. Delay = 1 seconds
  2. ; Clock frequency = 8 MHz
  3.  
  4. ; Actual delay = 1 seconds = 2000000 cycles
  5. ; Error = 0 %
  6.  
  7.         cblock
  8.         d1
  9.         d2
  10.         d3
  11.         endc
  12.  
  13. Delay_1s
  14.                         ;1999996 cycles
  15.         movlw   0x11
  16.         movwf   d1
  17.         movlw   0x5D
  18.         movwf   d2
  19.         movlw   0x05
  20.         movwf   d3
  21. Delay_1s_0
  22.         decfsz  d1, f
  23.         goto    $+2
  24.         decfsz  d2, f
  25.         goto    $+2
  26.         decfsz  d3, f
  27.         goto    Delay_1s_0
  28.  
  29.                         ;4 cycles (including call)
  30.         return

Al comienzo el CBLOCK define esos "registros" y para usarlo directamente hago un

Código: ASM
  1. CALL Delay_1s


----------------------------------------------------------------------------

Lo mas importante de la EEPROM

OJO que solo tiene 1.000.000 de grabaciones, si tu codigo se la pasa grabando la EEPROM vas a destruir la posicion de memoria.
Asi que asegurate que solo grabe cuando se necesite nada mas. Ejemplo no tendria sentido grabar el mismo valor que queres grabar.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: problemas con assembler una ayudita por favor
« Respuesta #5 en: 04 de Octubre de 2015, 16:35:12 »
Para verificar que un dato no llegue a X valor usas una resta,

Entonces esto NO es correcto

Código: ASM
  1. BTFSS UNIDAD,1
  2.         GOTO UNIDADES
  3.         BTFSS UNIDAD,3
  4.         GOTO UNIDADES


Si unidades es xxxx 1xx1 donde X puede 1 o 0 no es indicativo que llego a 10. Lo que haces es:

Código: ASM
  1. MOVF    UNIDAD,W        ;W = Unidad
  2.         SUBLW   0x10            ;W = 10 - W , actualiza las flags C,DC y Z
  3.         BTFSS   STATUS,Z        ;Si Z=1 quiere decir que Unidad era 10 ya que al restar quedo en 0
  4.         GOTO    UNIDADES        ;Aca va si Z es 0
  5.                                 ;Aca va si Z es 1

En ese codigo exactamente cuando es 10 procede a ponerse Z en 1, si quisiera saber si Unidades es mayor a 9 deberias cambiar el SUBLW 0x10 por 0x09 y preguntar por el flag C, entonces cualquier valor mayor a 9 no estaria permitido. Lo mismo ocurre para las decenas.

Código: ASM
  1. MOVF    UNIDAD,W        ;W = Unidad
  2.         SUBLW   0x9             ;W = 9 - W , actualiza las flags C,DC y Z
  3.         BTFSS   STATUS,C        ;Si C=1 quiere decir que Unidad es mayor a 9
  4.         GOTO    UNIDADES        ;Aca va si C es 0
  5.                                 ;Aca va si C es 1

----------------

No tiene sentido tener 2 tablas identicas como tenes, directamente usa 1, si ambas son iguales. Me refiero a:

TABUNIDAD
TABDECENAS


-----------------

Recomendacion usa W y F , en ves de 0 y 1, es mas simple de ver esto:

Código: ASM
  1. MOVF    UNIDAD,W

que esto:

Código: ASM
  1. MOVF    UNIDAD,0

En el primer codigo se que va a parar a W, en el segundo si no recuerdo cual era 0 o 1 estoy perdido
« Última modificación: 04 de Octubre de 2015, 16:39:00 por KILLERJC »

Desconectado M@XI

  • PIC10
  • *
  • Mensajes: 5
Re: problemas con assembler una ayudita por favor
« Respuesta #6 en: 04 de Octubre de 2015, 16:56:36 »
MUCHAS GRACIAS POR LA AYUDA Y LO PONDRE EN PRACTICA Y MODIFICARE LO MENSIONADO....CUALQUIER RESULTADO SE LO ESTARE DICIENDO YA SEA POSITIVO O NEGATIVO MUCHAS GRACIAS

Desconectado M@XI

  • PIC10
  • *
  • Mensajes: 5
Re: problemas con assembler una ayudita por favor
« Respuesta #7 en: 04 de Octubre de 2015, 17:51:54 »
Código: [Seleccionar]
;---------------------CONFIGURO EL PIC--------------------------
__CONFIG _CP_OFF&_LVP_OFF&_WDT_OFF&_PWRTE_ON&_XT_OSC

LIST P=16F628A
#INCLUDE <P16F628A.INC>
;--------------------------------------------------------------
;----------------DECLARO LAS VARIABLES-------------------------
CBLOCK 0X20
UNIDAD
DECENA
CONT1
CONT2
CONT3
DIRECCION
DATOEE
ENDC
;---------------------------------------------------------------
;--------CONFIGURO LOS PUERTOS Y PONGO LAS VARIABLES EN 0-------

PRINCIPAL
BSF STATUS,5
CLRF TRISA
BCF OPTION_REG,7
MOVLW B'00000001'
MOVWF TRISB
BCF STATUS,5
MOVLW D'7'
MOVWF CMCON
CLRF PORTB
CLRF DECENA
CLRF UNIDAD

MOVLW 0x00
MOVWF DIRECCION
CALL LeeEEPROM
MOVWF PORTB
MOVLW 0x01
MOVWF DIRECCION
CALL LeeEEPROM
MOVWF PORTB
;--------------------BOTON---------------------------------------
BOT BTFSC PORTB,0
GOTO BOT
BTFSS PORTB,0
GOTO INICIO
;----------------------------------------------------------------
;-------------VERIFICO QUE NO LLEGUE A DIEZ----------------------
INICIO
BTFSS UNIDAD,1
GOTO UNIDADES
BTFSS UNIDAD,3
GOTO UNIDADES
CLRF UNIDAD
INCF DECENA,1
BTFSS DECENA,1
GOTO DECENAS
BTFSS DECENA,3
GOTO DECENAS
CLRF DECENA
GOTO BOT
;-----------------------------------------------------------------
;----------------------REALIZO EL CONTEO--------------------------
UNIDADES
MOVLW B'00000001'
MOVWF PORTA
MOVF UNIDAD,0
CALL TABUNIDAD
MOVWF PORTB
CALL RETARDO
INCF UNIDAD,1
MOVF UNIDAD,W
MOVWF DATOEE
MOVLW 0x00
MOVWF DIRECCION
CALL EscribirEEPROM

DECENAS
MOVLW B'00000000'
MOVWF PORTA
MOVF DECENA,0
CALL TABDECENAS
MOVWF PORTB
CALL RETARDO
MOVF DECENA,W
MOVWF DATOEE
MOVLW 0x01
MOVWF DIRECCION
CALL EscribirEEPROM
GOTO BOT
;------------------------------------------------------------------
;---------------------DECLARO LAS TABLAS---------------------------
TABUNIDAD
ADDWF PCL,1
RETLW B'01111110';0
RETLW B'00001100';1
RETLW B'10110110';2
RETLW B'10011110';3
RETLW B'11001100';4
RETLW B'11011010';5
RETLW B'11111010';6
RETLW B'00001110';7
RETLW B'11111110';8
RETLW B'11001110';9
RETURN

TABDECENAS
ADDWF PCL,1
RETLW B'01111110';0
RETLW B'00001100';1
RETLW B'10110110';2
RETLW B'10011110';3
RETLW B'11001100';4
RETLW B'11011010';5
RETLW B'11111010';6
RETLW B'00001110';7
RETLW B'11111110';8
RETLW B'11001110';9
RETURN
;----------------------------------------------------------------------
EscribirEEPROM:
MOVF DATOEE,W ; Cargo el valor a escribir
BSF STATUS,RP0 ; Banco 1
MOVWF EEDATA
BCF STATUS,RP0 ; Banco 0
MOVF DIRECCION,W ; Cargo direccion a escribir
BSF STATUS,RP0 ; Banco 1
MOVWF EEADR
BSF EECON1,WREN ; Habilitamos la escritura de la EEPROM
;Codigo obligatorio
BCF INTCON,GIE ; Desabilitamos interrupciones ya que afectarian la escritura
MOVLW 0x55 ; Una proteccion que posee la EEPROM, es que antes de escribir
MOVWF EECON2 ; debe escribirse los valores 0x55 y 0xAA en orden
MOVLW 0xAA
MOVWF EECON2
BSF EECON1,WR ; Finalmente podemos darle la orden que escriba en la EEPROM
;Fin codigo obligatorio
 
BSF INTCON,GIE ; De usar interrupciones las habilitamos de nuevo
BCF STATUS,RP0 ; Banco 0
RETURN
LeeEEPROM:
MOVF DIRECCION,W ; CONFIG_ADDR = direccion del dato
BSF STATUS,RP0 ; Bank 1
MOVWF EEADR ; Direccion a leer
BSF EECON1,RD ; Avisamos que queremos leer asi EEDATA se carga con el valor
MOVF EEDATA,W ; ubicado en la direccion CONFIG_ADDR de la moemoria EEPROM
BCF STATUS,RP0 ; y guardamos en W, procedemos a volver al banco 0
MOVWF DATOEE
RETURN
;------------------------REALIZO EL RETARDO----------------------------
RETARDO
MOVLW .15
MOVWF CONT1
LOOP1
MOVLW .8
MOVWF CONT2
LOOP2
MOVLW .255
MOVWF CONT3
LOOP3
DECFSZ CONT3,1
GOTO LOOP3
DECFSZ CONT2,1
GOTO LOOP2
DECFSZ CONT1,1
GOTO LOOP1
RETURN
;-------------------------------------------------------------------------------------
END


LA VERDAD NO SE QUE ESTOY HACIENDO MAL PERO NO ME GUARDA NADA..... SEGURO QUE HAGO MASL LAS COSAS PERO NO ENCUENTRO EN DONDE ESTA EL ERROR

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: problemas con assembler una ayudita por favor
« Respuesta #8 en: 04 de Octubre de 2015, 18:35:58 »
Tenes varios errores, toma este codigo y estudialo

Código: ASM
  1. ;---------------------CONFIGURO EL PIC--------------------------
  2. __CONFIG _CP_OFF&_LVP_OFF&_WDT_OFF&_PWRTE_ON&_XT_OSC
  3.  
  4. LIST P=16F628A
  5. #INCLUDE <P16F628A.INC>
  6. ;--------------------------------------------------------------
  7. ;----------------DECLARO LAS VARIABLES-------------------------
  8. CBLOCK 0X20
  9. UNIDAD
  10. DECENA
  11. CONT1
  12. CONT2
  13. CONT3
  14. DIRECCION
  15. DATOEE
  16. FLAG
  17. ENDC
  18.  
  19. ;---------------------------------------------------------------
  20. ;--------------VECTORES DE RESET E INTERRUPCION-----------------
  21.  
  22.  
  23.         ORG     0x00
  24.         GOTO    CONFIGURACION
  25.         ORG     0x04
  26.         RETURN
  27.  
  28.  
  29. ;---------------------------------------------------------------
  30. ;--------CONFIGURO LOS PUERTOS Y PONGO LAS VARIABLES EN 0-------
  31.  
  32. CONFIGURACION
  33.  
  34.         BSF STATUS,RP0
  35.         CLRF TRISA
  36.         BCF OPTION_REG,NOT_RBPU
  37.         MOVLW B'00000001'
  38.         MOVWF TRISB
  39.         BCF STATUS,RP0
  40.         MOVLW D'7'
  41.         MOVWF CMCON
  42.         CLRF PORTB
  43.         CLRF DECENA
  44.         CLRF UNIDAD
  45.  
  46.         CLRF    DIRECCION
  47.         CALL    LeeEEPROM
  48.         MOVF    DATOEE,W
  49.         MOVWF   UNIDAD
  50.        
  51.         INCF    DIRECCION,F
  52.         CALL    LeeEEPROM
  53.         MOVF    DATOEE,W
  54.         MOVWF   DECENA
  55.  
  56. ;--------------------BOTON---------------------------------------
  57. ;----------------------------------------------------------------
  58. ;-------------VERIFICO QUE NO LLEGUE A DIEZ----------------------
  59. MAIN
  60.         CALL    MOSTRAR_DISPLAY
  61.         CALL    BOTON
  62.         GOTO    MAIN
  63.  
  64. BOTON
  65.         BTFSC   FLAG,0          ;Utilizo el bit este para saber si esta presionado el boton
  66.         GOTO    BOTON_0
  67.         BTFSS   PORTB,0         ;Pregunto si se presiono el boton
  68.         RETURN
  69.         BSF     FLAG,0          ;Se presiono, para que no entre nuevamente utilizo un bit
  70.  
  71.         INCF    UNIDAD,F        ; Incremento unidad, ahora me queda asegurarme que no este dentro del rango
  72.        
  73.        
  74.         MOVF    UNIDAD,W        ;W = Unidad
  75.         SUBLW   0x9             ;W = 9 - W , actualiza las flags C,DC y Z
  76.         BTFSS   STATUS,C        ;Si C=1 quiere decir que Unidad es mayor a 9
  77.         RETURN                  ; No supero asi que simplemente salgo
  78.  
  79.         CLRF    UNIDAD
  80.         INCF    DECENA,F
  81.         MOVF    DECENA,W        ;W = Decena
  82.         SUBLW   0x9             ;W = 9 - W , actualiza las flags C,DC y Z
  83.         BTFSC   STATUS,C        ;Si C=0 quiere decir que Decena es menor a 9
  84.         CLRF    DECENA          ;Si es mayor lo borro y salgo
  85.                                 ;Si es menor no hago nada
  86.  
  87.         ; Cambio las Unidades y Decenas asi que guardo
  88.         ; Las unidades si o si por que cambian seguro, las decenas tal ves no
  89.         ; Entonces primero leo y me aseguro que sea distinto
  90.  
  91.         MOVF    UNIDAD,W        ;Procedo a grabar los datos, los grabo solo cuando se presiono
  92.         MOVWF   DATOEE          ; datoee = Unidad
  93.         CLRF    DIRECCION       ; Direccion = 0x00
  94.         CALL    EscribirEEPROM  ; Grabo
  95.  
  96.         INCF    DIRECCION,F     ; Direccion = 0x01 (Decena)
  97.         CALL    LeeEEPROM       ; Leo
  98.         MOVF    DATOEE,W        ;
  99.         SUBWF   DECENA,W        ; W = Datoalmacenado - Decena
  100.         BTFSC   STATUS,Z        ; Z=1? es decir no cambio, entonces salgo
  101.         RETURN
  102.                                 ; Z=0 quiere decir que cambio, entonces guardo decenas tambien
  103.  
  104.         MOVF    DECENA,W        ; Procedo a grabar los datos, los grabo solo cuando se presiono
  105.         MOVWF   DATOEE          ; datoee = Decena, ya direccion esta en 0x01
  106.         CALL    EscribirEEPROM  ; Grabo
  107.        
  108.         RETURN                  ;Salgo
  109.  
  110. BOTON_0                         ; Caso que este presionado el boton ( lo sabemos por la flag )
  111.         BTFSS   PORTB,0         ; Preguntamos asi cuando vuelve a 0 (solto el boton) podemos borrar el flag
  112.         BCF     FLAG,0          ; Se solto el boton
  113.         RETURN                  ; Siguie presionado
  114.  
  115. ;-----------------------------------------------------------------
  116. ;----------------------REALIZO EL CONTEO--------------------------
  117. MOSTRAR_DISPLAY
  118.         CLRF    PORTA           ; pongo en 0 los catodos de los displays
  119.         MOVF    UNIDAD,W        ; Cargo el valor de las unidades en el puerto
  120.         CALL    TABLA
  121.         MOVWF   PORTB
  122.         BSF     PORTA,0         ; Enciendo el primer display y espero mientras esta encendido
  123.         CALL    RETARDO
  124.  
  125.         BCF     PORTA,0         ; Apago el primer display
  126.         MOVF    DECENA,W
  127.         CALL    TABLA
  128.         MOVWF   PORTB
  129.         BSF     PORTA,1         ; Enciendo el segundo display y espero
  130.         CALL    RETARDO
  131.  
  132.         RETURN
  133.  
  134. ;------------------------------------------------------------------
  135. ;---------------------DECLARO LAS TABLAS---------------------------
  136. TABLA
  137.         ADDWF PCL,1
  138.         RETLW B'01111110';0
  139.         RETLW B'00001100';1
  140.         RETLW B'10110110';2
  141.         RETLW B'10011110';3
  142.         RETLW B'11001100';4
  143.         RETLW B'11011010';5
  144.         RETLW B'11111010';6
  145.         RETLW B'00001110';7
  146.         RETLW B'11111110';8
  147.         RETLW B'11001110';9
  148.         RETURN
  149.  
  150. ;----------------------------------------------------------------------
  151. EscribirEEPROM:
  152.         MOVF    DATOEE,W        ; Cargo el valor a escribir
  153.         BSF     STATUS,RP0      ; Banco 1
  154.         MOVWF   EEDATA
  155.         BCF     STATUS,RP0      ; Banco 0
  156.         MOVF    DIRECCION,W     ; Cargo direccion a escribir
  157.         BSF     STATUS,RP0      ; Banco 1
  158.         MOVWF   EEADR
  159.         BSF     EECON1,WREN     ; Habilitamos la escritura de la EEPROM
  160.         ;Codigo obligatorio
  161.         BCF     INTCON,GIE      ; Desabilitamos interrupciones ya que afectarian la escritura
  162.         MOVLW   0x55            ; Una proteccion que posee la EEPROM, es que antes de escribir
  163.         MOVWF   EECON2          ; debe escribirse los valores 0x55 y 0xAA en orden
  164.         MOVLW   0xAA
  165.         MOVWF   EECON2
  166.         BSF     EECON1,WR       ; Finalmente podemos darle la orden que escriba en la EEPROM
  167.         ;Fin codigo obligatorio
  168.  
  169.         ;BSF    INTCON,GIE      ; De usar interrupciones las habilitamos de nuevo
  170.         BCF     STATUS,RP0      ; Banco 0
  171.         RETURN
  172.  
  173. LeeEEPROM:
  174.         MOVF    DIRECCION,W     ; CONFIG_ADDR = direccion del dato
  175.         BSF     STATUS,RP0      ; Bank 1
  176.         MOVWF   EEADR           ; Direccion a leer
  177.         BSF     EECON1,RD       ; Avisamos que queremos leer asi EEDATA se carga con el valor
  178.         MOVF    EEDATA,W        ; ubicado en la direccion CONFIG_ADDR de la moemoria EEPROM
  179.         BCF     STATUS,RP0      ; y guardamos en W, procedemos a volver al banco 0
  180.         MOVWF   DATOEE 
  181.         RETURN
  182. ;------------------------REALIZO EL RETARDO----------------------------
  183.  
  184. RETARDO
  185.         MOVLW .15
  186.         MOVWF CONT1
  187. LOOP1
  188.         MOVLW .8
  189.         MOVWF CONT2
  190. LOOP2
  191.         MOVLW .255
  192.         MOVWF CONT3
  193. LOOP3
  194.         DECFSZ CONT3,1
  195.         GOTO LOOP3
  196.         DECFSZ CONT2,1
  197.         GOTO LOOP2
  198.         DECFSZ CONT1,1
  199.         GOTO LOOP1
  200.         RETURN
  201. ;-------------------------------------------------------------------------------------
  202.         END

Todo lo agregado o modificado esta comentado, es otra de las cosas que debes realizar en tus programas, SIEMPRE SIEMPRE comenta que estas haciendo, facilita mucho ver el programa incluso para vos.

Si observas hice varios cambios. Incluso como hace el loop principal ( que llame MAIN )
Cada uno de los codigos que llaman los CALL son independientes entre uno y otros lo cual los podes probar sin necesidad de la otra parte del codigo

-----------------------------------------------------------------------------------------

Tus problemas eran:

PRINCIPAL:
- Mala implementacion de la lectura de la EEPROM al comienzo, bien ubicado pero mal implementado, ya que al enviar a leer el dato quedaba en DATOEE.
Vos pusiste un MOVWF PORTB, en ves de lo que puse yo.

- Mala implementacion del boton, presionando una ves tal ves aumentaba muchas veces. Ademas esa implementacion hace que no se muestre el display si no se toca el boton
Código: ASM
  1. BOT     BTFSC PORTB,0
  2.         GOTO BOT
  3.         BTFSS PORTB,0
  4.         GOTO INICIO
  5. ;----------------------------------------------------------------
  6. ;-------------VERIFICO QUE NO LLEGUE A DIEZ----------------------
  7. INICIO

Si observas el primer BTFSC te mantiene en un loop infinito, no esta ejecutandose la rutina de mostrar en el display, por lo tanto no vas a ver nada y siempre va a estar apagado a exepcion que presiones el boton.
Cuando presiones el boton y se ponga a 0 se observa que preguntas de nuevo por el mismo ahora un BTFSS, si no se produce el salto va a INICIO por el GOTO, si se produce el salto va a INICIO igual, en resumen esas 2 instrucciones no hacen nada por tu programa.

- Cuestionable nuevamente el codigo para saber si un numero es igual que el otro. Por lo que dije antes. Pero ademas esto es complicarse la vida lo que hiciste

Normalmente si tenes un numero supongamos 39 (3 9) y presionas el boton la idea es que ocurra lo siguiente:

Incremento Unidades 9 + 1 = 10
Unidades = 10 ? SI-> Unidades = 0 y decenas +1 , NO-> salgo
Decenas = 10? SI-> Decenas=0 , NO-> salgo

Vos haces todo lo contrario, preguntas todo esto, mostras en el display y luego aumentas.
Aqui ocurren 2 cosas, primer que nada estas mostrando una sola ves en el display, y la otra es que lo que quedan en los registros es el valor a "futuro",
Segun tu codigo:
  Supongamos el mismo numero que antes el "3","9"
  Pregunto, esta todo correcto, listo. Procedo a mostrar "3","9"
  Incremento "3","10"
  Guardo en EEPROM "3","10" y salgo.

Se ve la diferencia?.

- Otro "error" tal ves es la forma de multiplexar los displays, no se si es un error, pero yo supongo que son displays 7 segmentos por las tablas. Y que PORTA,0 es para el display de unidades y PORTA,1 es para el display de decenas
 Primero apagas -> cargas valor -> encendes -> esperas
Asi para cada display, eso lo podes ver en mi codigo.
« Última modificación: 05 de Octubre de 2015, 00:04:32 por KILLERJC »