Autor Tema: Manejo de displays utilizando Tmr0 e interrupciones - P16F628A  (Leído 3904 veces)

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

Desconectado markz

  • PIC10
  • *
  • Mensajes: 6
Manejo de displays utilizando Tmr0 e interrupciones - P16F628A
« en: 27 de Septiembre de 2018, 22:33:46 »
Buenas noches, soy nuevo en el foro, y vengo con una duda. actualmente estoy haciendo un trabajo para la facultad donde me piden por un DISPLAY de 7 segmentos contar automáticamente, en hexadecimal,de 0 hasta 15 (F), y después decrementar también automáticamente y con el pulsador RB0 se debe poder pausar o reanudar el proceso del contador.

Mi problema es que cuando agregue un tmr0 en el código (ya que lo necesito para pasar de numero en numero en 1 segundo por display), me dejo de funcionar la parte de Interrupción del código, donde se realizaba la pausa y reanudación.

¿Cual seria el error y como podría solucionarlo?

muchas gracias.


Código: [Seleccionar]
#include <p16f628a.inc>

__CONFIG  _CP_OFF & _WDT_OFF & _LVP_OFF & _PWRTE_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF& _BODEN_ON

Contador equ 0x20
AuxStatus equ 0x21
AuxW equ 0x22
Contador3 equ 0x24
CONT EQU 0x27
CONT2 EQU 0x28
CONT3 EQU 0x29
CONT_TMR0 EQU 0x30

org 0
goto Configuracion
org 0x04

Interrupcion:
btfsc PORTB,0
goto Interrupcion
goto Pausa
reanudar
bcf INTCON,GIE ;INHABILITO INTERRUPCIONES GLOBALES
bcf INTCON,INTF ;BAJO EL FLAG DE INTERRUPCION DE RB0
bsf INTCON,GIE ;HABILITO INTERRUPCIONES GLOBALES
movwf AuxW ;GUARDO EL CONTENIDO DE W
movfw STATUS
movwf AuxStatus ;GUARDO EL CONTENIDO DEL STATUS
movwf STATUS
movfw AuxW
retfie
Pausa
btfss PORTB,0
goto PAUSA
goto    reanudar

Configuracion:
bsf INTCON,GIE ;HABILITO INTERRUPCIONES GLOBALES
bsf INTCON,INTE ;HABILITO INTERRUPCIONES POR RB0
bsf STATUS,RP0 ;CAMBIO A BANCO 1
movlw .250
movwf CONT_TMR0 ;Agrego 250 a contador de tmr0
clrf         TRISB ;SETEA TODOS LOS BITS DEL TRISB EN 0
bsf TRISB,0 ;RB0 COMO ENTRADA
MOVLW   B'00000011'
        MOVWF   OPTION_REG
bcf STATUS,RP0 ;CAMBIO A BANCO 0
movlw B'01111110' ;EL DISPLAY INICIA EN 0
movwf PORTB
call Timer0_1seg ;Mantengo el display en 0 por 1segundo
clrf Contador ;INICIALIZO EL CONTADOR EN 0

Inicio:
movlw d'15
movwf Contador3
incf         Contador,1
movfw Contador ;SE PASA EL VALOR DE CONTADOR A W
call         Display
movwf PORTB
call         Timer0_1seg
decfsz Contador3,f
goto         $-.6 ;HASTA CALL PRESION
movlw d'15
movwf Contador3
decf         Contador,1
movfw Contador
call         Display
movwf PORTB
call         Timer0_1seg
decfsz Contador3,f
goto         $-.6 ;HASTA CALL PRESION
goto         Inicio


Display:
    addwf  PCL,1
    retlw   B'01111110'             ;NUMERO 0
    retlw   B'00001100'             ;NUMERO 1
    retlw   B'10110110'             ;NUMERO 2
    retlw   B'10011110'             ;NUMERO 3
    retlw   B'11001100'             ;NUMERO 4
    retlw   B'11011010'             ;NUMERO 5
    retlw   B'11111010'             ;NUMERO 6
    retlw   B'00001110'             ;NUMERO 7
    retlw   B'11111110'             ;NUMERO 8
    retlw   B'11011110'             ;NUMERO 9
    retlw   B'11101110'             ;LETRA A
    retlw   B'11111000'             ;LETRA B
    retlw   B'01110010'             ;LETRA C
    retlw   B'10111100'             ;LETRA D
    retlw   B'11110010'             ;LETRA E
    retlw   B'11100010'             ;LETRA F


Timer0_1seg
    MOVLW      .12     ;Carga el Timer0 con el valor que queremos
    MOVWF     TMR0
    BCF     INTCON,T0IF     ;Reseteamos el Flag de desbordamiento del TMR0
Timer0_Desbordamiento
    BTFSS       INTCON,T0IF     ;¿Se ha desbordado el TMR0?
    GOTO        Timer0_Desbordamiento   ;Aún no, Repite.
    decfsz     CONT_TMR0,1            ;Repite 10 veces lo mismo para llegar a 1 segundo.
    GOTO     Timer0_1seg
    RETURN

end
« Última modificación: 28 de Septiembre de 2018, 01:29:12 por markz »

Desconectado Pinolillo16

  • PIC18
  • ****
  • Mensajes: 324
Re:Manejo de displays utilizando Tmr0 e interrupciones - P16F628A
« Respuesta #1 en: 28 de Septiembre de 2018, 03:09:58 »
Como ayuda, para tus registros te sugiero que uses:

Código: ASM
  1. CBLOCK 0x20
  2. cont
  3. cont1
  4. cont2
  5. con3
  6.  
  7. ENDC

De esta manera ahorras un poco de escritura.

Desconectado Pinolillo16

  • PIC18
  • ****
  • Mensajes: 324
Re:Manejo de displays utilizando Tmr0 e interrupciones - P16F628A
« Respuesta #2 en: 28 de Septiembre de 2018, 03:23:44 »
Ademas creo que hay un error en la manera de platear tu problema. El vector de interrupciones se ejecuta cuando las banderas se activan, y tu estas considerando erroneos los datos del timer.

Veamos la formula:

Int_time= (4/FOSC)*(256-TMR0)*Preescaler.

De acuerdo a tu codigo tienes un preescaler de 16. Y estas cargando un 12 al TMR0.

Estos valores nos dan= 3.9mS

Si estuvieras haciendo bien el codigo de la interrupcion cada 3.9 Mili segundos estarias entrando al vector de interrupcion.

Dentro del ORG 0x04 o vector de interrupcion, jamas limpias tu bandera de T0IF, por lo que siempre te quedas ahi...

Desconectado Pinolillo16

  • PIC18
  • ****
  • Mensajes: 324
Re:Manejo de displays utilizando Tmr0 e interrupciones - P16F628A
« Respuesta #3 en: 28 de Septiembre de 2018, 03:33:28 »
Con la idea que tienes se puede solucionar. Olvida ahora las interrupciones ya que maximo alcanzas 60ms con el preescaler mas alto. Tu tienes esto:

Código: ASM
  1. Timer0_1seg
  2.     MOVLW      .12          ;Carga el Timer0 con el valor que queremos
  3.     MOVWF     TMR0
  4.     BCF     INTCON,T0IF             ;Reseteamos el Flag de desbordamiento del TMR0
  5. Timer0_Desbordamiento
  6.     BTFSS       INTCON,T0IF                 ;¿Se ha desbordado el TMR0?
  7.     GOTO        Timer0_Desbordamiento   ;Aún no, Repite.
  8.     decfsz          CONT_TMR0,1            ;Repite 10 veces lo mismo para llegar a 1 segundo.
  9.     GOTO            Timer0_1seg
  10.     RETURN

Te sugiero hacer un cambio:

Código: ASM
  1. Timer0_1seg
  2.     MOVLW      .12                                      ; Carga el Timer0 con el valor que queremos
  3.     MOVWF     TMR0
  4.     BCF     INTCON,T0IF                         ; Reseteamos el Flag de desbordamiento del TMR0
  5. Timer0_Desbordamiento
  6.     BTFSS       PORTB,0
  7.     CALL          PAUSA                                 ; Llamo una rutina de pausa
  8.     BTFSS       INTCON,T0IF                            ; ¿Se ha desbordado el TMR0?
  9.     GOTO        Timer0_Desbordamiento       ; Aún no, Repite.
  10.     decfsz          CONT_TMR0,1                      ; Repite 10 veces lo mismo para llegar a 1 segundo.
  11.     GOTO            Timer0_1seg
  12.     RETURN
  13. PAUSA
  14.     BTFSS      PORTB,0                               ; Pongo la condicion antirebote
  15.      GOTO      PAUSA                                  ; PARA CONTINUAR HASTA SOLTAR BOTON
  16.      NOP                                                    ; PIERDO DOS CICLOS DE RELOJ POR SEGURIDAD
  17.      NOP
  18.      BTFSC     PORTB,0                                ; PREGUNTO SI HAN PRESIONADO EL BOTON
  19.      GOTO  $-1                                            ; SI NO ESTA PRESIONADO ME REGRESO UNA INSTRUCCION
  20.      RETURN                                                ; Si lo presionan inmediatamente continua el conteo

El boton con su resistencia pull up.


Saludos

Desconectado Pinolillo16

  • PIC18
  • ****
  • Mensajes: 324
Re:Manejo de displays utilizando Tmr0 e interrupciones - P16F628A
« Respuesta #4 en: 28 de Septiembre de 2018, 03:35:57 »
Las interrupciones son una buena herramienta para tareas de precisión pero te sugiero que siempre busques la manera de solucionar tus problemas de manera que no las uses mucho, si es que vas empezando a usar lo micros. Porque pueden resultar una desventaja si no comprendes todo el funcionamiento de un pic.

Saludos

Desconectado markz

  • PIC10
  • *
  • Mensajes: 6
Re:Manejo de displays utilizando Tmr0 e interrupciones - P16F628A
« Respuesta #5 en: 28 de Septiembre de 2018, 18:29:41 »
Muchas gracias por su ayuda.

Tengo otra duda, en caso de necesito usar si o si el TMR0 para hacer un retardo de 1 segundo por display e Interrupciones en RB0 para Pausar y Reanudar el proceso del display, como tendria que modificar el codigo?

Lo que tengo en cuenta es que como en el vector de interrupcion solo tengo codigos para Pausar y Reanudar, no tiene sentido que cada 3,9ms (por desbordamiento de TMR0) entre al vector de interrupcion.
Mi idea es que cada vez que presione un boton por RB0 entre a ese vector de interrupcion, pero que a la vez también se pueda usar TMR0 para hacer un retardo de display.
« Última modificación: 28 de Septiembre de 2018, 18:32:37 por markz »

Desconectado Pinolillo16

  • PIC18
  • ****
  • Mensajes: 324
Re:Manejo de displays utilizando Tmr0 e interrupciones - P16F628A
« Respuesta #6 en: 28 de Septiembre de 2018, 22:06:13 »
Para poder trabajar de esa manera. Desactiva la interrupcion por timer y solo activa por RB0. Con eso sera suficiente.


Saludos

Desconectado markz

  • PIC10
  • *
  • Mensajes: 6
Re:Manejo de displays utilizando Tmr0 e interrupciones - P16F628A
« Respuesta #7 en: 29 de Septiembre de 2018, 00:08:02 »
Muchas gracias por el aporte.

Disculpe mi ignorancia pero hubo otro error...
Lo que hice fue agregar un "BCF   INTCON,T0IE" en el timer0 para desactivar la interrupción y poner en 1 el INTEDG en la configuración para generar la interrupción por RB0.

El problema es que solamente puedo pausar y reanudar una vez, en el segundo intento ya no me deja pausarlo...

Código: ASM
  1. #include        <p16f628a.inc>
  2.  
  3. CBLOCK 0x20
  4. Contador       
  5. AuxStatus      
  6. AuxW           
  7. Contador3      
  8. CONT           
  9. CONT2          
  10. CONT3          
  11. CONT_TMR0      
  12. ENDC
  13.  
  14.         org             0
  15.         goto    Configuracion
  16.         org             0x04
  17.  
  18. Interrupcion:  
  19.         btfsc   PORTB,0
  20.         goto    Interrupcion
  21.         goto    Pausa
  22. reanudar       
  23.         bcf             INTCON,GIE                                      ;INHABILITO INTERRUPCIONES GLOBALES
  24.         bcf             INTCON,INTF                                     ;BAJO EL FLAG DE INTERRUPCION DE RB0
  25.         bsf             INTCON,GIE                                      ;HABILITO INTERRUPCIONES GLOBALES
  26.         movwf   AuxW                                            ;GUARDO EL CONTENIDO DE W
  27.         movfw   STATUS
  28.         movwf   AuxStatus                                       ;GUARDO EL CONTENIDO DEL STATUS
  29.         movwf   STATUS
  30.         movfw   AuxW
  31.         retfie 
  32. Pausa
  33.         btfss   PORTB,0
  34.         goto    PAUSA
  35.         goto    reanudar
  36.        
  37. Configuracion:
  38.         bsf             INTCON,GIE                                      ;HABILITO INTERRUPCIONES GLOBALES
  39.         bsf             INTCON,INTE                                     ;HABILITO INTERRUPCIONES POR RB0
  40.         bsf             STATUS,RP0                                      ;CAMBIO A BANCO 1
  41.         movlw   .250   
  42.         movwf   CONT_TMR0
  43.         clrf    TRISB                                           ;SETEA TODOS LOS BITS DEL TRISB EN 0
  44.         bsf             TRISB,0                                         ;RB0 COMO ENTRADA
  45.         movlw   b'01000011'
  46.         movwf   option_reg
  47.         bcf             STATUS,RP0                                      ;CAMBIO A BANCO 0
  48.         movlw   B'01111110'                                     ;EL DISPLAY INICIA EN 0
  49.         movwf   PORTB
  50.         call    Timer0_1seg                                     ;Para mantener el 0 en display por 1segundo
  51.         clrf    Contador                                        ;INICIALIZO EL CONTADOR EN 0                                   
  52.  
  53. Inicio:
  54.         movlw   d'15'
  55.         movwf   Contador3
  56.         incf    Contador,1                                      ;SI FUE PULSADO, SE INCREMENTA EL CONTADOR EN 1
  57.         movfw   Contador                                        ;SE PASA EL VALOR DE CONTADOR A W
  58.         call    Display
  59.         movwf   PORTB
  60.         call    Timer0_1seg    
  61.         decfsz  Contador3,f
  62.         goto    $-.6                                   
  63.         movlw   d'15'
  64.         movwf   Contador3
  65.         decf    Contador,1
  66.         movfw   Contador
  67.         call    Display
  68.         movwf   PORTB
  69.         call    Timer0_1seg    
  70.         decfsz  Contador3,f
  71.         goto    $-.6                                   
  72.         goto    Inicio
  73.        
  74.  
  75. Display:
  76.         addwf   PCL,1
  77.         retlw   B'01111110'             ;NUMERO 0
  78.         retlw   B'00001100'             ;NUMERO 1
  79.     retlw   B'10110110'             ;NUMERO 2
  80.     retlw   B'10011110'             ;NUMERO 3
  81.     retlw   B'11001100'             ;NUMERO 4
  82.     retlw   B'11011010'             ;NUMERO 5
  83.     retlw   B'11111010'             ;NUMERO 6
  84.     retlw   B'00001110'             ;NUMERO 7
  85.     retlw   B'11111110'             ;NUMERO 8
  86.     retlw   B'11011110'             ;NUMERO 9
  87.     retlw   B'11101110'             ;LETRA A
  88.     retlw   B'11111000'             ;LETRA B
  89.     retlw   B'01110010'             ;LETRA C
  90.     retlw   B'10111100'             ;LETRA D
  91.     retlw   B'11110010'             ;LETRA E
  92.     retlw   B'11100010'             ;LETRA F
  93.  
  94.  
  95. Timer0_1seg
  96.     BCF         INTCON,T0IE
  97.     MOVLW       .12                                     ;Carga el Timer0 con el valor que queremos
  98.     MOVWF       TMR0
  99.     BCF         INTCON,T0IF                             ;Reseteamos el Flag de desbordamiento del TMR0
  100. Timer0_Desbordamiento
  101.     BTFSS       INTCON,T0IF                     ;¿Se ha desbordado el TMR0?
  102.     GOTO        Timer0_Desbordamiento   ;Aún no, Repite.
  103.     decfsz          CONT_TMR0,1                 ;Repite 10 veces lo mismo para llegar a 1 segundo.
  104.     GOTO            Timer0_1seg
  105.     RETURN
  106.  
  107. end


Desconectado markz

  • PIC10
  • *
  • Mensajes: 6
Re:Manejo de displays utilizando Tmr0 e interrupciones - P16F628A
« Respuesta #8 en: 29 de Septiembre de 2018, 00:23:48 »
ya lo pude solucionar! muchas gracias por su ayuda, de verdad.