Autor Tema: Contador de 2 dígitos  (Leído 5744 veces)

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

Desconectado Lorenzo

  • PIC16
  • ***
  • Mensajes: 110
Contador de 2 dígitos
« en: 05 de Agosto de 2006, 14:53:12 »
Hola, estoy utilizando mal, creo, la interrupción por desbordamiento del TMR0, pero no sé dónde está el fallo, así que aquí os dejo el archivo. Estoy intentando hacer un contador ascendente del 0 al 99, con una pausa de aproximadamente medio segundo.
Gracias y saludos.

      
;Se especifica tipo de micro, este programa es un contador
;ascendente del cero al nueve.

      LIST   P=16F84A


;Se definen los registros específicos SFR.

TMR0      EQU   01      
OPT      EQU   01
PCL      EQU   02
ESTADO      EQU   03         
PUERTAA      EQU   05      
PUERTAB      EQU   06      
INTCON      EQU   0B
               
;Se definen los bits de los registros específicos.

C      EQU   00      ;Se define el bit 0 del registro 3 Estado.
W      EQU   00      ;Se define el registro de trabajo.
F      EQU   01      ;Se define F como
T0IF      EQU   02      ;Se define el bit 2 del registro 2 INTCON
RP0      EQU   05      ;Se define el bit 5 del registro ESTADO.
Z      EQU   02      ;Se define el bit 2 del registro ESTADO.


;Se definen los registros generales

CONTADOR   EQU   0D      
UNIDAD      EQU   0E      ;Aquí se cargará el display 1
DECENA      EQU   0F      ;Aquí se cargara el display 2.


      ORG   0
      goto   CONFIGURACION
      ORG   4
      goto   INTERRUPCION
      ORG   5



;Configuramos los registros específicos.

CONFIGURACION   
      bsf   ESTADO,RP0   ;Pasamos al banco1.
      movlw   b'11100'
      movwf   PUERTAA      
      movlw   b'00000000'
      movwf   PUERTAB      ;Se especifica la Puerta B como salida
      movlw   b'00000111'   ;Se le asigna el temporizador al TMR0 con predivisor de 256.
      movwf   OPT            
      bcf   ESTADO,RP0   ;Regresamos al banco 0.
      movlw   b'10100000'   ;Activamos la interrupción por desbordamiento de TMR0.
      movwf   INTCON


INICIO      
      clrf   UNIDAD      ;Limpiamos el registro DIGITO, lo ponemos a cero.
      clrf   DECENA      ;Limpiamos el registro DIGITO, también lo ponemos a cero.



COMIENZO   
      movf   UNIDAD,W   ;Pasamos el valor de registro DIGITO al registro de trabajo.
      call   DISPLAY      ;Llamamos a la subrutina para configurar el número en el display.
      bsf   PUERTAA,0   ;Aquí nos aseguramos que alimentamos el display 1.
      bcf   PUERTAA,1   ;y nos aseguramos que el display 2 esté inactivo.
      movwf   PUERTAB      ;Mostramos el número en dicho display.
      movf   DECENA,W   
      call   DISPLAY      
      bcf   PUERTAA,0   ;Nos aseguramos de que el display 1 esté inactivo.
      bsf   PUERTAA,1   ;Nos aseguramos que esté activo el display 2.
      movwf   PUERTAB      
      goto   COMIENZO   ;Volvemos al comienzo para seguir mostrando el display


      

      
INTERRUPCION   
      movlw   07
      movwf   CONTADOR
      bcf   INTCON,T0IF



INTERRUPCION2   
      clrf   TMR0



INTERRUPCION3   
      btfss   INTCON,T0IF
      goto   INTERRUPCION3
      decfsz   CONTADOR
      goto   INTERRUPCION2      
      
      
      incf   UNIDAD,F
      movf   UNIDAD,W
      xorlw   b'1010'      ;Comprobamos si la unidad a pasado de 9 a 10.
      btfsc   ESTADO,Z   ;sino es así volvemos al COMIENZO.   
      goto   COMIENZO
      bcf   ESTADO,Z
      movlw   3F      
      movwf   UNIDAD
      incf   DECENA
      movf   DECENA,W
      xorlw   b'1010'      ;Si la decena pasa a 10 la volvemos a cero
      btfsc   ESTADO,Z
      goto   COMIENZO
      bcf   ESTADO,Z
      movlw   3F
      movwf   DECENA
      bcf   INTCON,T0IF
      retfie
      




DISPLAY      
      addwf   PCL,F      ;Se le suma los datos del registro W, proveniente de la puerta A
               ;y se vuelve a guardar en el mismo registro PCL.
      retlw   3F      ;Se define el cero para ser mostrado en el display.
      retlw   06      ;Se define el uno.
      retlw   5B      ;Se define el dos.
      retlw   4F      ;Se define el tres.
      retlw   66      ;Se define el cuatro.
      retlw   6D      ;Se define el cinco.
      retlw   7D      ;Se define el seis.
      retlw   07      ;Se define el siete.
      retlw   7F      ;Se define el ocho.
      retlw   6F      ;Se define el nueve.
      


      END         ;Finaliza el programa.

« Última modificación: 05 de Agosto de 2006, 20:27:12 por Lorenzo »

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Contador de 2 dígitos
« Respuesta #1 en: 05 de Agosto de 2006, 16:10:21 »
Hola

Código: ASM
  1. bcf   INTCON,T0IF   ;<-Limpias el flag de desbordamiento del TImer0
  2.  
  3. INTERRUPCION2   clrf   TMR0
  4.  
  5. INTERRUPCION3   btfss   INTCON,T0IF  ;<-Checkeas el flag de desbordamiento que acabas de limpiar.
  6.       goto   INTERRUPCION3                  ;Resultado: loop eterno(no sale de aqui).
  7.       decfsz   CONTADOR

Solución:

Si sólo pensas utilizar esta interrupcion, elimina las lineas:

Código: ASM
  1. INTERRUPCION3   btfss   INTCON,T0IF
  2.       goto   INTERRUPCION3

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Lorenzo

  • PIC16
  • ***
  • Mensajes: 110
Re: Contador de 2 dígitos
« Respuesta #2 en: 05 de Agosto de 2006, 17:54:36 »
Hola Brunof, pues he probado lo que me comentas y no ha funcionado. Este seañlizador se activa al producirse la interrupción, entonces, como yo quiero que pase medio segundo entre cada incremento tengo que hacer una temporización dentro de la interrupción. Así que si yo lo bajo, no creo que entraría en un bucle infinito, ya que el temporizador seguiría incrementandose. Así que aquí sigo intentandolo y con los displays a cero. ¿Hay algún programa aparte del MPLAB para poder simularlo?
Gracias y saludos.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Contador de 2 dígitos
« Respuesta #3 en: 05 de Agosto de 2006, 19:11:14 »
Hola. Esta bien...no se para que haces eso, pero lo respeto.
Hay otros soft de simulacion pero los creo necesarios. Con el MPLAB te tiene que bastar.

Con respecto al programa. Lo simule. La interrupcion ocurre cada 13.10ms aprox.

La variable CONTADOR no esta haciendo lo que deberia hacer.Acordate de limpiar el INTCON,T0IF en cada loop.
El programa no esta funcionando porque cargas el valor 0x3F en UNIDAD, y al ir a la tabla DISPLAY se va a zonas de la memoria del pic mas alla de lo que programaste.

Ademas:
Código: ASM
  1. goto   COMIENZO

Estas lineas dentro de la rutina de interrupcion van a producir un OVERFLOW del STACK.
No podes volver al programa principal desde la interrupcion sin antes descargar el STACK. La interrupcion produce que se almacene la direccion de la ultima posicion ejecutada, para saber adonde volver cuando salis de la interrupcion. Si no liberas esta posicion(con un RETURN o RETFIE) el STACK se llena, y una vez llenos sus 8 niveles, se desborda y se dispara para cualquier lado.
Hay que guardar los registros claves inmediatamente despues de entrar a la interrupcion, y reestablecerlos antes de salir de la misma.
Te lo configura para que incremente cada 498ms.

Usa la tecla <TAB> del teclado para los espacios, no utilices la barra espaciadora. Esto facilita el aspecto visual del codigo.
Saludos.


 

Código: ASM
  1. LIST            P=16F84A        ;Se especifica tipo de micro, este programa es un contador
  2.                                         ;ascendente del cero al nueve.
  3.         #include        <P16F84A.INC>
  4.  
  5.  
  6. ;Se definen los registros específicos SFR.
  7.  
  8. TMR0    EQU     01      
  9. OPT     EQU     01
  10. PCL     EQU     02
  11. ESTADO  EQU     03          
  12. PUERTAA EQU     05      
  13. PUERTAB EQU     06      
  14. INTCON  EQU     0B
  15.                
  16. ;Se definen los bits de los registros específicos.
  17.  
  18. C       EQU     00      ;Se define el bit 0 del registro 3 Estado.
  19. W       EQU     00      ;Se define el registro de trabajo.
  20. F       EQU     01      ;Se define F como
  21. T0IF    EQU     02      ;Se define el bit 2 del registro 2 INTCON
  22. RP0     EQU     05      ;Se define el bit 5 del registro ESTADO.
  23. Z       EQU     02      ;Se define el bit 2 del registro ESTADO.
  24.  
  25. ;Se definen los registros generales
  26.  
  27. CONTADOR        EQU     0C      
  28. UNIDAD          EQU     0D      ;Aquí se cargará el display 1
  29. DECENA          EQU     0E      ;Aquí se cargara el display 2.
  30. W_TEMP          EQU             0F
  31. PCLATH_TEMP     EQU             10
  32. STATUS_TEMP     EQU             11
  33.  
  34.         ORG     0
  35.         goto    CONFIGURACION
  36.         ORG     4
  37.         goto    INTERRUPCION
  38.         ORG     5
  39.  
  40. ;Configuramos los registros específicos.
  41.  
  42. CONFIGURACION
  43.         bsf     ESTADO,RP0      ;Pasamos al banco1.
  44.         movlw   b'11100'
  45.         movwf   PUERTAA      
  46.         movlw   b'00000000'
  47.         movwf   PUERTAB         ;Se especifica la Puerta B como salida
  48.         movlw   b'00000111'     ;Se le asigna el temporizador al TMR0 con predivisor de 256.
  49.         movwf   OPT            
  50.         bcf     ESTADO,RP0      ;Regresamos al banco 0.
  51.         movlw   b'10100000'     ;Activamos la interrupción por desbordamiento de TMR0.
  52.         movwf   INTCON
  53.  
  54.  
  55. INICIO
  56.         clrf    UNIDAD          ;Limpiamos el registro DIGITO, lo ponemos a cero.
  57.         clrf    DECENA          ;Limpiamos el registro DIGITO, también lo ponemos a cero.
  58.  
  59. COMIENZO
  60.         movf    UNIDAD,W        ;Pasamos el valor de registro DIGITO al registro de trabajo.
  61.         call    DISPLAY         ;Llamamos a la subrutina para configurar el número en el display.
  62.         bsf     PUERTAA,0       ;Aquí nos aseguramos que alimentamos el display 1.
  63.         bcf     PUERTAA,1       ;y nos aseguramos que el display 2 esté inactivo.
  64.         movwf   PUERTAB         ;Mostramos el número en dicho display.
  65.         movf    DECENA,W
  66.         call    DISPLAY
  67.         bcf     PUERTAA,0       ;Nos aseguramos de que el display 1 esté inactivo.
  68.         bsf     PUERTAA,1       ;Nos aseguramos que esté activo el display 2.
  69.         movwf   PUERTAB  
  70.         goto    COMIENZO        ;Volvemos al comienzo para seguir mostrando el display
  71.      
  72. INTERRUPCION  
  73.                 MOVWF   W_TEMP
  74.                 SWAPF   STATUS,W
  75.                 CLRF    STATUS
  76.                 MOVWF   STATUS_TEMP
  77.                 MOVF    PCLATH, W
  78.                 MOVWF   PCLATH_TEMP
  79.                 CLRF    PCLATH         
  80.  
  81.                 movlw   25
  82.                 movwf   CONTADOR
  83.      
  84.  
  85. INTERRUPCION2
  86.                 bcf     INTCON,T0IF
  87.                 clrf    TMR0
  88.  
  89. INTERRUPCION3
  90.                 btfss   INTCON,T0IF
  91.                 goto    INTERRUPCION3
  92.                 decfsz  CONTADOR,F
  93.                 goto    INTERRUPCION2
  94.  
  95.                 bcf     INTCON,T0IF
  96.  
  97.                 incf    UNIDAD,F
  98.                 movf    UNIDAD,W
  99.                 xorlw   b'1010'         ;Comprobamos si la unidad a pasado de 9 a 10.
  100.                 btfss   ESTADO,Z        ;sino es así volvemos al COMIENZO.  
  101.                 goto    volver
  102.  
  103.                 clrf    UNIDAD
  104.                 incf    DECENA,F
  105.                 movf    DECENA,W
  106.                 xorlw   b'1010'         ;Si la decena pasa a 10 la volvemos a cero
  107.                 btfss   ESTADO,Z
  108.                 goto    volver
  109.  
  110.                 clrf    DECENA
  111.  
  112. volver
  113.                 MOVF    PCLATH_TEMP, W
  114.                 MOVWF   PCLATH
  115.                 SWAPF   STATUS_TEMP,W
  116.                 MOVWF   STATUS
  117.                 SWAPF   W_TEMP,F
  118.                 SWAPF   W_TEMP,W               
  119.                 RETFIE      
  120.  
  121.  
  122. DISPLAY
  123.                 addwf   PCL,F   ;Se le suma los datos del registro W, proveniente de la puerta A
  124.                                 ;y se vuelve a guardar en el mismo registro PCL.
  125.  
  126.                 retlw   3F      ;Se define el cero para ser mostrado en el display.
  127.                 retlw   06      ;Se define el uno.
  128.                 retlw   5B      ;Se define el dos.
  129.                 retlw   4F      ;Se define el tres.
  130.                 retlw   66      ;Se define el cuatro.
  131.                 retlw   6D      ;Se define el cinco.
  132.                 retlw   7D      ;Se define el seis.
  133.                 retlw   07      ;Se define el siete.
  134.                 retlw   7F      ;Se define el ocho.
  135.                 retlw   6F      ;Se define el nueve.
  136.      
  137.  
  138.                 END             ;Finaliza el programa.

"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Lorenzo

  • PIC16
  • ***
  • Mensajes: 110
Re: Contador de 2 dígitos
« Respuesta #4 en: 06 de Agosto de 2006, 06:49:03 »
Hola BrunoF, ni mucho menos quiero quitarte la razón, si hay alguien que está equivocado soy yo, si yo digo algo y estoy equivocado, quiero que me corrijan para así aprender, porque sino estoy perdido. Te he hecho caso y así poder publicar de una forma más clara el código, por cierto, ¿cómo te sale así tu código? Ahora he cambiado mi código a otra forma creo que menos complicada, pero nada sigue sin salir, he simulado el código, y aunque tarda mucho en representarlo, seguramente porque no sabré usarlo bien, pero los datos por la puerta B salen correcto.
Gracias y saludos.


;Se especifica tipo de micro, este programa es un contador
;ascendente del cero al nueve.

      LIST   P=16F84A


;Se definen los registros específicos SFR.

TMR0      EQU   01      
OPT      EQU   01
PCL      EQU   02
ESTADO      EQU   03         
PUERTAA      EQU   05      
PUERTAB      EQU   06      
INTCON      EQU   0B



               
;Se definen los bits de los registros específicos.

C      EQU   00      ;Se define el bit 0 del registro 3 Estado.
W      EQU   00      ;Se define el registro de trabajo.
F      EQU   01      ;Se define F como
T0IF      EQU   02      ;Se define el bit 2 del registro 2 INTCON
RP0      EQU   05      ;Se define el bit 5 del registro ESTADO.
Z      EQU   02      ;Se define el bit 2 del registro ESTADO.




;Se definen los registros generales

CONTADOR   EQU   0D
CONTADOR1   EQU   10
CONTADOR2   EQU   11      
UNIDAD      EQU   0E      ;Aquí se cargará el display 1
DECENA      EQU   0F      ;Aquí se cargara el display 2.


      ORG   0
      goto   CONFIGURACION
      ORG   4
      goto   INTERRUPCION
      ORG   5



;Configuramos los registros específicos.

CONFIGURACION   
      bsf   ESTADO,RP0   ;Pasamos al banco1.
      movlw   b'11100'
      movwf   PUERTAA      
      movlw   b'00000000'
      movwf   PUERTAB      ;Se especifica la Puerta B como salida
      movlw   b'00000111'   ;Se le asigna el temporizador al TMR0 con predivisor de 256.
      movwf   OPT            
      bcf   ESTADO,RP0   ;Regresamos al banco 0.
      movlw   b'10100000'   ;Activamos la interrupción por desbordamiento de TMR0.
      movwf   INTCON



INICIO      
      clrf   UNIDAD      ;Limpiamos el registro DIGITO, lo ponemos a cero.
      clrf   DECENA      ;Limpiamos el registro DIGITO, también lo ponemos a cero.



COMIENZO   
      movf   UNIDAD,W   ;Pasamos el valor de registro DIGITO al registro de trabajo.
      call   DISPLAY      ;Llamamos a la subrutina para configurar el número en el display.
      bsf   PUERTAA,0   ;Aquí nos aseguramos que alimentamos el display 1.
      bcf   PUERTAA,1   ;y nos aseguramos que el display 2 esté inactivo.
      movwf   PUERTAB      ;Mostramos el número en dicho display.
      movf   DECENA,W   
      call   DISPLAY      
      bcf   PUERTAA,0   ;Nos aseguramos de que el display 1 esté inactivo.
      bsf   PUERTAA,1   ;Nos aseguramos que esté activo el display 2.
      movwf   PUERTAB      
      goto   COMIENZO   ;Volvemos al comienzo para seguir mostrando el display


      

      
INTERRUPCION   
      movlw   b'11111111'
      movwf   CONTADOR
      movwf   CONTADOR1
      movlw   0A
      movwf   CONTADOR2



INTERRUPCION2   
      decfsz   CONTADOR
      goto INTERRUPCION2


INTERRUPCION3
      decfsz   CONTADOR1
      goto   INTERRUPCION3


INTERRUPCION4   
      decfsz   CONTADOR2
      goto   INTERRUPCION4   
      incf   UNIDAD,F
      movf   UNIDAD,W
      xorlw   b'1010'      ;Comprobamos si la unidad a pasado de 9 a 10.
      btfss   ESTADO,Z   ;sino es así volvemos al COMIENZO.   
      goto   INTERRUPCION5
      bcf   ESTADO,Z
      movlw   3F      
      movwf   UNIDAD
      incf   DECENA
      movf   DECENA,W
      xorlw   b'1010'      ;Si la decena pasa a 10 la volvemos a cero
      btfsS   ESTADO,Z
      goto   INTERRUPCION5
      bcf   ESTADO,Z
      movlw   3F
      movwf   DECENA


INTERRUPCION5
      bcf   INTCON,T0IF
      retfie
      


DISPLAY      
      addwf   PCL,F      ;Se le suma los datos del registro W, proveniente de la puerta A
               ;y se vuelve a guardar en el mismo registro PCL.
      retlw   3F      ;Se define el cero para ser mostrado en el display.
      retlw   06      ;Se define el uno.
      retlw   5B      ;Se define el dos.
      retlw   4F      ;Se define el tres.
      retlw   66      ;Se define el cuatro.
      retlw   6D      ;Se define el cinco.
      retlw   7D      ;Se define el seis.
      retlw   07      ;Se define el siete.
      retlw   7F      ;Se define el ocho.
      retlw   6F      ;Se define el nueve.
      


      END         ;Finaliza el programa.



Desconectado Lorenzo

  • PIC16
  • ***
  • Mensajes: 110
Re: Contador de 2 dígitos
« Respuesta #5 en: 06 de Agosto de 2006, 12:08:47 »
Hola, lo he vuelto a modificar en la subrutina de la interrupción, y por lo visto no va, así que esperaré a ver si un compañero me dice que es lo que falla.
Gracias y saludos.


;Se especifica tipo de micro, este programa es un contador
;ascendente del cero al nueve.

      LIST   P=16F84A


;Se definen los registros específicos SFR.

TMR0      EQU   01      
OPT      EQU   01
PCL      EQU   02
ESTADO      EQU   03         
PUERTAA      EQU   05      
PUERTAB      EQU   06      
INTCON      EQU   0B



               
;Se definen los bits de los registros específicos.

C      EQU   00      ;Se define el bit 0 del registro 3 Estado.
W      EQU   00      ;Se define el registro de trabajo.
F      EQU   01      ;Se define F como
T0IF      EQU   02      ;Se define el bit 2 del registro 2 INTCON
RP0      EQU   05      ;Se define el bit 5 del registro ESTADO.
Z      EQU   02      ;Se define el bit 2 del registro ESTADO.




;Se definen los registros generales

CONTADOR   EQU   0D
UNIDAD      EQU   0E      ;Aquí se cargará el display 1
DECENA      EQU   0F      ;Aquí se cargara el display 2.


      ORG   0
      goto   CONFIGURACION
      ORG   4
      goto   INTERRUPCION
      ORG   5



;Configuramos los registros específicos.

CONFIGURACION   
      bsf   ESTADO,RP0   ;Pasamos al banco1.
      movlw   b'11100'
      movwf   PUERTAA      
      movlw   b'00000000'
      movwf   PUERTAB      ;Se especifica la Puerta B como salida
      movlw   b'00000111'   ;Se le asigna el temporizador al TMR0 con predivisor de 256.
      movwf   OPT            
      bcf   ESTADO,RP0   ;Regresamos al banco 0.
      movlw   b'10100000'   ;Activamos la interrupción por desbordamiento de TMR0.
      movwf   INTCON



INICIO      
      clrf   UNIDAD      ;Limpiamos el registro DIGITO, lo ponemos a cero.
      clrf   DECENA      ;Limpiamos el registro DIGITO, también lo ponemos a cero.



COMIENZO   
      movf   UNIDAD,W   ;Pasamos el valor de registro DIGITO al registro de trabajo.
      call   DISPLAY      ;Llamamos a la subrutina para configurar el número en el display.
      bsf   PUERTAA,0   ;Aquí nos aseguramos que alimentamos el display 1.
      bcf   PUERTAA,1   ;y nos aseguramos que el display 2 esté inactivo.
      movwf   PUERTAB      ;Mostramos el número en dicho display.
      movf   DECENA,W   
      call   DISPLAY      
      bcf   PUERTAA,0   ;Nos aseguramos de que el display 1 esté inactivo.
      bsf   PUERTAA,1   ;Nos aseguramos que esté activo el display 2.
      movwf   PUERTAB      
      goto   COMIENZO   ;Volvemos al comienzo para seguir mostrando el display


      

      
INTERRUPCION   
      xorlw   b'00000000'   ;Compruebo si la variable contador ha llegado a cero
      xorwf   CONTADOR   ;para volver a cargala con el valor siete, y sino
      btfss   ESTADO,Z   ;decrementamos la variable CONTADOR.
      goto   INTERRUPCION1
      movlw   07
      movwf   CONTADOR



INTERRUPCION1   
      decfsz   CONTADOR
      goto INTERRUPCION3




INTERRUPCION2   
      incf   UNIDAD,F
      movf   UNIDAD,W
      xorlw   b'1010'      ;Comprobamos si la unidad a pasado de 9 a 10.
      btfss   ESTADO,Z   ;sino es así volvemos al COMIENZO.   
      goto   INTERRUPCION3
      bcf   ESTADO,Z
      movlw   3F      
      movwf   UNIDAD
      incf   DECENA
      movf   DECENA,W
      xorlw   b'1010'      ;Si la decena pasa a 10 la volvemos a cero
      btfsS   ESTADO,Z
      goto   INTERRUPCION3
      bcf   ESTADO,Z
      movlw   3F
      movwf   DECENA


INTERRUPCION3
      bcf   INTCON,T0IF
      retfie
      


DISPLAY      
      addwf   PCL,F      ;Se le suma los datos del registro W, proveniente de la puerta A
               ;y se vuelve a guardar en el mismo registro PCL.
      retlw   3F      ;Se define el cero para ser mostrado en el display.
      retlw   06      ;Se define el uno.
      retlw   5B      ;Se define el dos.
      retlw   4F      ;Se define el tres.
      retlw   66      ;Se define el cuatro.
      retlw   6D      ;Se define el cinco.
      retlw   7D      ;Se define el seis.
      retlw   07      ;Se define el siete.
      retlw   7F      ;Se define el ocho.
      retlw   6F      ;Se define el nueve.
      


      END         ;Finaliza el programa.



Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Contador de 2 dígitos
« Respuesta #6 en: 06 de Agosto de 2006, 12:46:26 »
Hola.
No entiendo. El programa que te pase tenia todo lo necesario para funcionar. Pero lo has vuelto a hacer como lo hiciste al principio, pese a que indique dónde estaban tus errores. :z) :z)

COMIENZO   
      movf   UNIDAD,W   ;Pasamos el valor de registro DIGITO al registro de trabajo.
      call   DISPLAY      ;Llamamos a la subrutina para configurar el número en el display.
      bsf   PUERTAA,0   ;Aquí nos aseguramos que alimentamos el display 1.
      bcf   PUERTAA,1   ;y nos aseguramos que el display 2 esté inactivo.
      movwf   PUERTAB      ;Mostramos el número en dicho display.
      movf   DECENA,W   
      call   DISPLAY      
      bcf   PUERTAA,0   ;Nos aseguramos de que el display 1 esté inactivo.
      bsf   PUERTAA,1   ;Nos aseguramos que esté activo el display 2.
      movwf   PUERTAB      
      goto   COMIENZO   ;Volvemos al comienzo para seguir mostrando el display
[/quote]

Aca hay un detalle visual importante. Agrega retardos luego de representar datos. Aunque sea unos milisegundos. Sino los valores en los displays se veran muy tenues o ni siquiera se veran.
      
INTERRUPCION   
      xorlw   b'00000000'   ;Compruebo si la variable contador ha llegado a cero
      xorwf   CONTADOR   ;para volver a cargala con el valor siete, y sino
      btfss   ESTADO,Z   ;decrementamos la variable CONTADOR.
      goto   INTERRUPCION1
      movlw   07
      movwf   CONTADOR



INTERRUPCION1   
      decfsz   CONTADOR
      goto INTERRUPCION3




INTERRUPCION2   
      incf   UNIDAD,F
      movf   UNIDAD,W
      xorlw   b'1010'      ;Comprobamos si la unidad a pasado de 9 a 10.
      btfss   ESTADO,Z   ;sino es así volvemos al COMIENZO.   
      goto   INTERRUPCION3

      bcf   ESTADO,Z
      movlw   3F      
      movwf   UNIDAD
      incf   DECENA
      movf   DECENA,W
      xorlw   b'1010'      ;Si la decena pasa a 10 la volvemos a cero
      btfsS   ESTADO,Z
      goto   INTERRUPCION3
      bcf   ESTADO,Z
      movlw   3F
      movwf   DECENA


INTERRUPCION3
      bcf   INTCON,T0IF
      retfie

Primero: Quitaste las lineas que te habia agregado para guardar los registros claves y recuperarlos antes de salir de la interrupcion. Esto te va a generar errores a corto plazo. El programa se te va a ir disparado para cualquier lado seguro sin esto.

Segundo:

      xorlw   b'00000000'   ;Compruebo si la variable contador ha llegado a cero
      xorwf   CONTADOR   ;para volver a cargala con el valor siete, y sino
      btfss   ESTADO,Z   ;decrementamos la variable CONTADOR.

Esta NO es forma de saber si CONTADOR = 0.
En todo caso podrias hacer:

      movlw   b'00000000'   ;Compruebo si la variable contador ha llegado a cero
      xorwf   CONTADOR   ;para volver a cargala con el valor siete, y sino
      btfss   ESTADO,Z   ;decrementamos la variable CONTADOR.

O bien:

      clrw                      ;Compruebo si la variable contador ha llegado a cero
      xorwf   CONTADOR   ;para volver a cargala con el valor siete, y sino
      btfss   ESTADO,Z   ;decrementamos la variable CONTADOR.

Pero la mejor forma es hacer:

                                               ;Compruebo si la variable contador ha llegado a cero
      movf   CONTADOR,F   ;para volver a cargala con el valor siete, y sino
      btfss   ESTADO,Z   ;decrementamos la variable CONTADOR.


Tercero:

                                 bcf   ESTADO,Z

No es necesario modificar el valor del flag Z del registro STATUS. Este flag se setea solo.

Cuarto:

      movlw   3F      
      movwf   UNIDAD

¿Por que moves 0x3F a UNIDAD y DECENA? Eso era lo que antes hacia que el programa se descarrilara.

Si unidad o decena = 0x3F al ingresar a la tabla DISPLAY, si le agregas 0x37 posiciones al PCL, el programa se te va a lineas de codigo fuera de las que utilizas.
NO DEBES CARGAR 0x37. Recorda que la tabla DISPLAY hace el pasaje del valor numerico al valor a representar.
Debes ponerlas a cero, no cargarlas con 0x37.

Aún corrigiendo todo esto, no he analizado en detalle la variable CONTADOR.
La simulación no es lenta si sabes utilizar el Simulador del MPLAB correctamente.

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Lorenzo

  • PIC16
  • ***
  • Mensajes: 110
Re: Contador de 2 dígitos
« Respuesta #7 en: 06 de Agosto de 2006, 14:33:23 »
Hola BrunoF, después de tirarme media tarde con este código, me he dado cuenta de que no puedo meter retrasos dentro de la rutina de interrupción, ya que me hace cosas raras, así que al final le quito los retraso dentro de ésta, ya que produce que haya mucho tiempo si alimentar los displays. Ya he conseguido de que funcione, pero el contador va muy rápido, así que tendré que aumentar el tiempo, antes de producirse la interrupción, ya que sino los incrementos se producen muy rápidos. Ya que he introducido un preescalar de 256, entre interrupción e interrupción hay un retraso de unos 65 milisegundo, un tiempo excesivo para la vista. Ahora voy a leer tranquilamente el mensaje que veo que me has puesto mientras terminaba el código, yo supongo que lo que me intentabas decir en mensajes anteriores, es lo que he explicado anteriormente, pero yo no te comprendía, así que machacando y la ayuda inestimable de gente como tú, todo se puede conseguir. Por cierto, ¿cómo puedo aumentar el tiempo antes del desbordamiento del temporizador TMR0?
Gracias y saludos.



;Se especifica tipo de micro, este programa es un contador
;ascendente del cero al nueve.

      LIST   P=16F84A


;Se definen los registros específicos SFR.

TMR0      EQU   01      
OPT      EQU   01
PCL      EQU   02
ESTADO      EQU   03         
PUERTAA      EQU   05      
PUERTAB      EQU   06      
INTCON      EQU   0B



               
;Se definen los bits de los registros específicos.

C      EQU   00      ;Se define el bit 0 del registro 3 Estado.
W      EQU   00      ;Se define el registro de trabajo.
F      EQU   01      ;Se define F como
T0IF      EQU   02      ;Se define el bit 2 del registro 2 INTCON
RP0      EQU   05      ;Se define el bit 5 del registro ESTADO.
Z      EQU   02      ;Se define el bit 2 del registro ESTADO.




;Se definen los registros generales


UNIDAD      EQU   0E      ;Aquí se cargará el display 1
DECENA      EQU   0F      ;Aquí se cargara el display 2.


      ORG   0
      goto   CONFIGURACION
      ORG   4
      goto   INTERRUPCION
      ORG   5



;Configuramos los registros específicos.

CONFIGURACION   
      bsf   ESTADO,RP0   ;Pasamos al banco1.
      movlw   b'11100'
      movwf   PUERTAA      
      movlw   b'00000000'
      movwf   PUERTAB      ;Se especifica la Puerta B como salida
      movlw   b'00000111'   ;Se le asigna el temporizador al TMR0 con predivisor de 256.
      movwf   OPT            
      bcf   ESTADO,RP0   ;Regresamos al banco 0.
      movlw   b'10100000'   ;Activamos la interrupción por desbordamiento de TMR0.
      movwf   INTCON



INICIO      
      clrf   UNIDAD      ;Limpiamos el registro DIGITO, lo ponemos a cero.
      clrf   DECENA      ;Limpiamos el registro DIGITO, también lo ponemos a cero.



COMIENZO   
      movf   UNIDAD,W   ;Pasamos el valor de registro DIGITO al registro de trabajo.
      call   DISPLAY      ;Llamamos a la subrutina para configurar el número en el display.
      bsf   PUERTAA,0   ;Aquí nos aseguramos que alimentamos el display 1.
      bcf   PUERTAA,1   ;y nos aseguramos que el display 2 esté inactivo.
      movwf   PUERTAB      ;Mostramos el número en dicho display.
      movf   DECENA,W   
      call   DISPLAY      
      bcf   PUERTAA,0   ;Nos aseguramos de que el display 1 esté inactivo.
      bsf   PUERTAA,1   ;Nos aseguramos que esté activo el display 2.
      movwf   PUERTAB      
      goto   COMIENZO   ;Volvemos al comienzo para seguir mostrando el display


      

      
INTERRUPCION   
      incf   UNIDAD,F
      movf   UNIDAD,W
      xorlw   b'1010'      ;Comprobamos si la unidad a pasado de 9 a 10.
      btfss   ESTADO,Z   ;sino es así volvemos al COMIENZO.   
      goto   INTERRUPCION1
      bcf   ESTADO,Z
      clrf   UNIDAD
      incf   DECENA
      movf   DECENA,W
      xorlw   b'1010'      ;Si la decena pasa a 10 la volvemos a cero
      btfss   ESTADO,Z
      goto   INTERRUPCION1
      bcf   ESTADO,Z
      clrf   DECENA


INTERRUPCION1
      bcf   INTCON,T0IF
      retfie


      

DISPLAY      
      addwf   PCL,F      ;Se le suma los datos del registro W, proveniente de la puerta A
               ;y se vuelve a guardar en el mismo registro PCL.
      retlw   3F      ;Se define el cero para ser mostrado en el display.
      retlw   06      ;Se define el uno.
      retlw   5B      ;Se define el dos.
      retlw   4F      ;Se define el tres.
      retlw   66      ;Se define el cuatro.
      retlw   6D      ;Se define el cinco.
      retlw   7D      ;Se define el seis.
      retlw   07      ;Se define el siete.
      retlw   7F      ;Se define el ocho.
      retlw   6F      ;Se define el nueve.
      


      END         ;Finaliza el programa.


« Última modificación: 06 de Agosto de 2006, 14:40:48 por Lorenzo »

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Contador de 2 dígitos
« Respuesta #8 en: 06 de Agosto de 2006, 14:51:39 »
Hola Lorenzo. El TMR0 tiene límites.
La fórmula es: (4/FOSC) *prescaler* TIMER0.
Por lo tanto con un cristal de 4MHZ el maximo tiempo obtenible seria: (4/4000000) * 256*256 = 65.536ms

Si queres lograr mayor tiempo antes que se desborde por hardware, no queda otra mas que cambiar por un oscilador con menos Mhz.

Ahora, si queres hacerlo por software, podes crear una variable que cuente la cantidad de veces que de desborda(¿la variable CONTADOR de tu programa no es la que hace esto?).

En cuanto a eso que "te hace cosas raras" tu programa nunca va a ser seguro hasta que guardes y reestablescas los registros criticos del PIC( W,STATUS y PCLATH) dentro de la rutina de interrupcion.

En el programa que modifique para ti fijate que puse las lineas al ingresar y al salir de la interrupcion.
Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Lorenzo

  • PIC16
  • ***
  • Mensajes: 110
Re: Contador de 2 dígitos
« Respuesta #9 en: 06 de Agosto de 2006, 15:00:29 »
Hola BrunoF, ya he leido tu último mensaje, después de solucionar mi código, ahora leo tu mensaje, y todo esos fallos que me comentas me he dado cuenta después de machacar mucho el código escrito, estos son errores de principiante, pero la cuestión es que me he dado cuenta antes de leer tu último mensaje, así que después de solucionarlo y ver tú mensaje se confirma mi dudas, así que muchisimas gracias por tus aportaciones que me han servido de gran ayuda.
Gracias y saludos.

Desconectado Lorenzo

  • PIC16
  • ***
  • Mensajes: 110
Re: Contador de 2 dígitos
« Respuesta #10 en: 06 de Agosto de 2006, 17:50:09 »
Hola BrunoF, por fin después de mucho esfuerzo lo he podido terminar, estoy muy contento, ya que aunque no sea una gran cosa, he aprendido mucho a la hora de que se puede hacer y que no, y sobre todo a manejar bien las interrupciones y demás. Y sobre todo porque cometiendo errores es como se aprende. Así que te vuelvo a dar las gracias por tu interés mostrado que ha sido de gran ayuda.
Gracias y saludos.



;Se especifica tipo de micro, este programa es un contador
;ascendente del cero al noventa y nueve, se podruce cada
;medio segundo aproximadamente.

      LIST   P=16F84A


;Se definen los registros específicos SFR.

TMR0      EQU   01      
OPT      EQU   01
PCL      EQU   02
ESTADO      EQU   03         
PUERTAA      EQU   05      
PUERTAB      EQU   06      
INTCON      EQU   0B



               
;Se definen los bits de los registros específicos.

C      EQU   00      ;Se define el bit 0 del registro 3 Estado.
W      EQU   00      ;Se define el registro de trabajo.
F      EQU   01      ;Se define F como
T0IF      EQU   02      ;Se define el bit 2 del registro 2 INTCON
RP0      EQU   05      ;Se define el bit 5 del registro ESTADO.
Z      EQU   02      ;Se define el bit 2 del registro ESTADO.




;Se definen los registros generales

CONTADOR   EQU   0D
UNIDAD      EQU   0E      ;Aquí se cargará el display 1
DECENA      EQU   0F      ;Aquí se cargara el display 2.


      ORG   0
      goto   CONFIGURACION
      ORG   4
      goto   INTERRUPCION
      ORG   5



;Configuramos los registros específicos.

CONFIGURACION   
      bsf   ESTADO,RP0   ;Pasamos al banco1.
      movlw   b'11100'
      movwf   PUERTAA      
      movlw   b'00000000'
      movwf   PUERTAB      ;Se especifica la Puerta B como salida
      movlw   b'00000111'   ;Se le asigna el temporizador al TMR0 con predivisor de 256.
      movwf   OPT            
      bcf   ESTADO,RP0   ;Regresamos al banco 0.
      movlw   b'10100000'   ;Habilitamos la interrupción por desbordamiento de TMR0.
      movwf   INTCON



INICIO      
                                movlw   b'111'      ;Cargamos la variable CONTADOR con el valor 7 para que se
      movwf   CONTADOR   ;los incrementos cada medio segundo aproximadamente.
      clrf   UNIDAD      ;Limpiamos el registro UNIDAD, lo ponemos a cero.
      clrf   DECENA      ;Limpiamos el registro CENTENA, también lo ponemos a cero.



COMIENZO   
      movf   UNIDAD,W   ;Pasamos el valor de registro UNIDAD al registro de trabajo.
      call   DISPLAY      ;Llamamos a la subrutina para configurar el número en el display.
      bsf   PUERTAA,0   ;Aquí nos aseguramos que alimentamos el display 1.
      bcf   PUERTAA,1   ;y nos aseguramos que el display 2 esté inactivo.
      movwf   PUERTAB      ;Mostramos el número en dicho display.
      movf   DECENA,W   ;;Pasamos el valor de registro CENTENA al registro de trabajo.
      call   DISPLAY      
      bcf   PUERTAA,0   ;Nos aseguramos de que el display 1 esté inactivo.
      bsf   PUERTAA,1   ;Nos aseguramos que esté activo el display 2.
      movwf   PUERTAB      
      goto   COMIENZO   ;Volvemos al comienzo para seguir mostrando el display


      

      
INTERRUPCION      
      decfsz   CONTADOR   ;Utilizando la variable CONTADOR se producirán incrementos
      goto   INTERRUPCION1   ;cada 7 veces de desbormdamiento del TMR0.
      movlw   b'111'
      movwf   CONTADOR
      incf   UNIDAD,F   ;Incrementamos la variable UNIDAD.
      movf   UNIDAD,W
      xorlw   b'1010'      ;Comprobamos si la unidad a pasado de 9 a 10.
      btfss   ESTADO,Z   ;sino es así volvemos al COMIENZO.   
      goto   INTERRUPCION1
      bcf   ESTADO,Z
      clrf   UNIDAD
      incf   DECENA      ;Incrementamos la variable DECENA.
      movf   DECENA,W
      xorlw   b'1010'      ;Si la decena pasa a 10 la volvemos a cero
      btfss   ESTADO,Z
      goto   INTERRUPCION1
      bcf   ESTADO,Z
      clrf   DECENA


INTERRUPCION1
      bcf   INTCON,T0IF
      retfie         ;Retornamos de la interrupción.


      

DISPLAY      
      addwf   PCL,F      ;Se le suma los datos del registro W, proveniente de la puerta A
               ;y se vuelve a guardar en el mismo registro PCL.
      retlw   3F      ;Se define el cero para ser mostrado en el display.
      retlw   06      ;Se define el uno.
      retlw   5B      ;Se define el dos.
      retlw   4F      ;Se define el tres.
      retlw   66      ;Se define el cuatro.
      retlw   6D      ;Se define el cinco.
      retlw   7D      ;Se define el seis.
      retlw   07      ;Se define el siete.
      retlw   7F      ;Se define el ocho.
      retlw   6F      ;Se define el nueve.
      


      END         ;Finaliza el programa.


Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Contador de 2 dígitos
« Respuesta #11 en: 06 de Agosto de 2006, 20:09:05 »
Me alegro que lo hayas logrado hacer funcionar.
Igual es cuestión de tiempo antes que falle.Si es sólo para probar, esta bien, pero si lo pensas poner en algun lado y dejarlo funcionando. En algun momento se va a plantar.
Ya te comente que no estas guardando los registros criticos ni reestableciendolos dentro de la interrupcion.
Tal vez con suerte nunca te falle, tal vez te falle en menos de 20 segundos.

Suerte.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Lorenzo

  • PIC16
  • ***
  • Mensajes: 110
Re: Contador de 2 dígitos
« Respuesta #12 en: 07 de Agosto de 2006, 06:29:29 »
Hola BrunoF, tengo un pequeño problema que yo creo que será por los transistores, por lo cual he puesto el mensaje o mejor dicho me lo han puesto, que será el lugar correcto, en http://www.todopic.com.ar/foros/index.php?topic=13298.0 , así que si quieres echale un vistazo. Por cierto, si no te parece mal, me podrías volver a explicar a lo que te refieres con lo de guardar los registros críticos ni reestableciendo dentro de la interrupción. Ya que una cosa es hacer un código y que funcione y otra cosa es depurar un código y evitar posibles errores o mal funcionamiento en un futuro, ya que lo que pretendo es saber programar en condiciones con un código depurado. Pero te tienes que dar cuenta que estoy aprendiendo a usar un 16f84a y todavía no sé usarlo como debiera, así que cuando expliques procura hacerlo a un nivel del que te puedes imaginar del que tengo  :wink:
Así que muchisimas gracias por tu tiempo y las molestias que te estoy ocasionando.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Contador de 2 dígitos
« Respuesta #13 en: 07 de Agosto de 2006, 18:05:48 »
Hola Lorenzo. La explicación de las instrucciones para salvar los registros especiales al ingresar a una interrupcion, y su reestablecimiento al salir de la misma esta en la pagina 30 del Datasheet del 16F84A que seguramente debes tener en tu poder.

Si estas trabajando en MPLAB o usando el MPASMWIN directamente para ensamblar el codigo, existen archivos .inc creados para cada PIC, que ya traen los registros especiales declarados, para que no tengas que andar haciendo justamente esto:

Código: ASM
  1. TMR0      EQU   01      
  2. OPT      EQU   01
  3. PCL      EQU   02
  4. ESTADO      EQU   03          
  5. PUERTAA      EQU   05      
  6. PUERTAB      EQU   06      
  7. INTCON      EQU   0B
  8.                
  9. ;Se definen los bits de los registros específicos.
  10.  
  11. C      EQU   00      ;Se define el bit 0 del registro 3 Estado.
  12. W      EQU   00      ;Se define el registro de trabajo.
  13. F      EQU   01      ;Se define F como
  14. T0IF      EQU   02      ;Se define el bit 2 del registro 2 INTCON
  15. RP0      EQU   05      ;Se define el bit 5 del registro ESTADO.
  16. Z      EQU   02      ;Se define el bit 2 del registro ESTADO.

Ya que con solo poner la linea al principio del ASM:

Código: ASM
  1. #include        <P16F84A.INC>

no necesitaras declarar ningun registro ni definir nada. Eso si...debes respetar el nombre que se les da a los registros.Por ejemplo:

Código: ASM
  1. PUERTAA      EQU   05      
  2. PUERTAB      EQU   06
incluyendo la linea que te acabo de mencionar(#include   <P16F84A.INC>) no necesitas declararlos.
Para usarlos, simplemente pones PORTA y PORTB.

¿Ventajas? Muchas. Utilizaras nombres que son familiares para todos los usuarios del foro que programan en ASM, facilitanto la lectura de tu programa y otros.
Evitaras errores que pudieras cometer por ahi, equivocandote en el valor que le asignas a cada etiqueta.
Ademas, te ahorraras todo el trabajajo de tener que recurrir al datasheet antes de poder usar un registro especial que antes no habias utilizado.
Si tenes dudas de los nombres de los registros, podes abrir con el bloc de notas el archivo P16F84A.inc de tu pc, y hecharle un vistazo.

En cuanto a los transistores y que se te ve raro...ya te mencione que pongas retardos cada vez que muestras un numero en un display. Recorda que los LEDS que forman los 7segmentos, son LENTOS. Y vos los estas apagando y encendiendo demasiado rapido. Lo que no permite que logren encender bien y nitido.
Te  injerto las llamadas a las subrutinas de espera, luego vos crealas.

Código: ASM
  1. movf   UNIDAD,W   ;Pasamos el valor de registro UNIDAD al registro de trabajo.
  2.       call   DISPLAY      ;Llamamos a la subrutina para configurar el número en el display.
  3.       bsf   PUERTAA,0   ;Aquí nos aseguramos que alimentamos el display 1.
  4.       bcf   PUERTAA,1   ;y nos aseguramos que el display 2 esté inactivo.
  5.       movwf   PUERTAB      ;Mostramos el número en dicho display.
  6.       call    DEMORA15ms
  7.       movf   DECENA,W   ;;Pasamos el valor de registro CENTENA al registro de trabajo.
  8.       call   DISPLAY      
  9.       bcf   PUERTAA,0   ;Nos aseguramos de que el display 1 esté inactivo.
  10.       bsf   PUERTAA,1   ;Nos aseguramos que esté activo el display 2.
  11.       movwf   PUERTAB      
  12.       call    DEMORA15ms
  13.       goto   COMIENZO   ;Volvemos al comienzo para seguir mostrando el display


Crea una subrutina llamada DEMORA15ms,ajustala a 15ms y proba, seguramente este es tu problema.

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Lorenzo

  • PIC16
  • ***
  • Mensajes: 110
Re: Contador de 2 dígitos
« Respuesta #14 en: 08 de Agosto de 2006, 07:25:24 »
Hola Brunof, te comento que ya todo va perfecto :-/, de verdad que tu ayuda ha sido extremadamente útil, y que gracias a tus aportaciones y tu aclaraciones ya lo he podido terminar, además de aclararme las precauciones a tomar en cuenta al uso de los displays y el pic. Ahora paso a aclararte el tema de las declaraciones de los registros. Yo sé que existe esa directiva en la cual viene declarado todo y evito tener que hacerlo, lo que pasa que como estoy comenzando, y para evitar que no se me olvide que es cada cosa y dónde está situada procuro siempre declararlos. En cuanto a declarla de otra forma, de como esta declarada en ese archivo, como por ejemplo, PUERTAA  en vez de PORTA, es porque procuro darle una traducción al español, ya que soy un acérrimo defensor del idioma que compartimos en este foro, como es el español, ya que es un idioma mucho más rico que el inglés, y sobre todo porque hablo español y no soy inglés. Ahora comprendo, que debemos usar unos términos que use todo el mundo y lo pueda comprender tanto un persona que hable español, ingles, ruso o alemán, así que tal vez empiece a utilizarlo como dices para cuando tenga dudas y pida información a algún compañero del foro. En cuanto al retraso que debía poner para evitar imágenes extrañas, lo he hecho, y todo va perfecto, pero he tenido que variar como me comentaste, ya que si lo ponía como decías, no me acuerdo ahora, la UNIDAD o DECENA, se encendía pero la otra no se veía. Entonces he tenido que poner dos retrasos, pero de tan sólo de 250 microsegundos, ya que sino cuando mostraba el número correcto, pero se encendía y apagaba intermitente el display.

COMIENZO   
      movf   UNIDAD,W   ;Pasamos el valor de registro UNIDAD al registro de trabajo.
      call   DISPLAY      ;Llamamos a la subrutina para configurar el número en el display.
      bcf   PUERTAA,1   ;Nos aseguramos que el display 2 esté inactivo.
      bsf   PUERTAA,0   ;Y aquí nos aseguramos que alimentamos el display 1.
      movwf   PUERTAB      ;Mostramos la UNIDAD en dicho display.
      call   RETRASO      ;Se produce un retraso para evitar imágenes fantasmas.
      movf   DECENA,W   ;Pasamos el valor de registro CENTENA al registro de trabajo.
      call   DISPLAY      ;Llamamos a la subrutina para configurar el número en el display.
      bcf   PUERTAA,0   ;Nos aseguramos de que el display 1 esté inactivo.
      bsf   PUERTAA,1   ;Nos aseguramos que esté activo el display 2.
      movwf   PUERTAB      ;Mostramos la DECENA en dicho display.
      call   RETRASO      ;Se produce un retraso para evitar imágenes fantasmas.
      goto   COMIENZO   ;Volvemos al comienzo para seguir mostrando el display


      

Y ahora paso a mostrar el código de como queda definitivo, gracias a la yuda inestimable de BrunoF del cual me ha ayudado muchisimo.


;Se especifica tipo de micro, este programa es un contador
;ascendente del cero al noventa y nueve, se podruce cada
;medio segundo aproximadamente.

      LIST   P=16F84A


;Se definen los registros específicos SFR.

TMR0      EQU   01      
OPT      EQU   01
PCL      EQU   02
ESTADO      EQU   03         
PUERTAA      EQU   05      
PUERTAB      EQU   06      
INTCON      EQU   0B



               
;Se definen los bits de los registros específicos.

C      EQU   00      ;Se define el bit 0 del registro 3 Estado.
W      EQU   00      ;Se define el registro de trabajo.
F      EQU   01      ;Se define F como
T0IF      EQU   02      ;Se define el bit 2 del registro 2 INTCON
RP0      EQU   05      ;Se define el bit 5 del registro ESTADO.
Z      EQU   02      ;Se define el bit 2 del registro ESTADO.




;Se definen los registros generales

CONTADOR20   EQU   10
CONTADOR21   EQU   11
CONTADOR   EQU   0D
UNIDAD      EQU   0E      ;Aquí se cargará el display 1
DECENA      EQU   0F      ;Aquí se cargara el display 2.


      ORG   0
      goto   CONFIGURACION
      ORG   4
      goto   INTERRUPCION
      ORG   5



;Configuramos los registros específicos.

CONFIGURACION   
      bsf   ESTADO,RP0   ;Pasamos al banco1.
      movlw   b'11100'
      movwf   PUERTAA      
      movlw   b'00000000'
      movwf   PUERTAB      ;Se especifica la Puerta B como salida
      movlw   b'00000111'   ;Se le asigna el temporizador al TMR0 con predivisor de 256.
      movwf   OPT            
      bcf   ESTADO,RP0   ;Regresamos al banco 0.
      movlw   b'10100000'   ;Habilitamos la interrupción por desbordamiento de TMR0.
      movwf   INTCON



INICIO      movlw   b'111'      ;Cargamos la variable CONTADOR con el valor 7 para que se
      movwf   CONTADOR   ;los incrementos cada medio segundo aproximadamente.
      clrf   UNIDAD      ;Limpiamos el registro UNIDAD, lo ponemos a cero.
      clrf   DECENA      ;Limpiamos el registro CENTENA, también lo ponemos a cero.



COMIENZO   
      movf   UNIDAD,W   ;Pasamos el valor de registro UNIDAD al registro de trabajo.
      call   DISPLAY      ;Llamamos a la subrutina para configurar el número en el display.
      bcf   PUERTAA,1   ;Nos aseguramos que el display 2 esté inactivo.
      bsf   PUERTAA,0   ;Y aquí nos aseguramos que alimentamos el display 1.
      movwf   PUERTAB      ;Mostramos la UNIDAD en dicho display.
      call   RETRASO      ;Se produce un retraso para evitar imágenes fantasmas.
      movf   DECENA,W   ;Pasamos el valor de registro CENTENA al registro de trabajo.
      call   DISPLAY      ;Llamamos a la subrutina para configurar el número en el display.
      bcf   PUERTAA,0   ;Nos aseguramos de que el display 1 esté inactivo.
      bsf   PUERTAA,1   ;Nos aseguramos que esté activo el display 2.
      movwf   PUERTAB      ;Mostramos la DECENA en dicho display.
      call   RETRASO      ;Se produce un retraso para evitar imágenes fantasmas.
      goto   COMIENZO   ;Volvemos al comienzo para seguir mostrando el display


      

      
INTERRUPCION      
      decfsz   CONTADOR   ;Utilizando la variable CONTADOR se producirán incrementos
      goto   INTERRUPCION1   ;cada 7 veces de desbormdamiento del TMR0.
      movlw   b'111'
      movwf   CONTADOR
      incf   UNIDAD,F   ;Incrementamos la variable UNIDAD.
      movf   UNIDAD,W
      xorlw   b'1010'      ;Comprobamos si la unidad a pasado de 9 a 10.
      btfss   ESTADO,Z   ;sino es así volvemos al COMIENZO.   
      goto   INTERRUPCION1
      bcf   ESTADO,Z
      clrf   UNIDAD
      incf   DECENA      ;Incrementamos la variable DECENA.
      movf   DECENA,W
      xorlw   b'1010'      ;Si la decena pasa a 10 la volvemos a cero
      btfss   ESTADO,Z
      goto   INTERRUPCION1
      bcf   ESTADO,Z
      clrf   DECENA


INTERRUPCION1
      bcf   INTCON,T0IF
      retfie         ;Retornamos de la interrupción.


      

DISPLAY      
      addwf   PCL,F      ;Se le suma los datos del registro W, proveniente de la puerta A
               ;y se vuelve a guardar en el mismo registro PCL.
      retlw   3F      ;Se define el cero para ser mostrado en el display.
      retlw   06      ;Se define el uno.
      retlw   5B      ;Se define el dos.
      retlw   4F      ;Se define el tres.
      retlw   66      ;Se define el cuatro.
      retlw   6D      ;Se define el cinco.
      retlw   7D      ;Se define el seis.
      retlw   07      ;Se define el siete.
      retlw   7F      ;Se define el ocho.
      retlw   6F      ;Se define el nueve.


RETRASO      movlw   b'11111111'   ;Rutina de retraso de unos 250 microsegundos.
      movwf   CONTADOR20

RETRASO1   
      decfsz   CONTADOR20
      goto   RETRASO1
      return   
      


      END         ;Finaliza el programa.


Gracias y saludos

« Última modificación: 08 de Agosto de 2006, 07:34:01 por Lorenzo »


 

anything