Autor Tema: flanco descendente RBIE pic16f87X  (Leído 2783 veces)

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

Desconectado ubect

  • PIC10
  • *
  • Mensajes: 3
flanco descendente RBIE pic16f87X
« en: 03 de Abril de 2017, 10:24:37 »
Hola a todos! Soy nuevo en el foro, y llevo días atascado con una duda, pregunté en otro foro pero me borraron el tema porque " hay que utilizar el buscador " antes de preguntar, y lo entiendo pero es que si no he encontrado nada y me borran el tema, no me ayudan para nada.

Bueno, agradecería cualquier pequeña ayuda, doy detalles....

Tengo un programa para clase que me pide lo siguiente: si acciono RB7, al soltarlo, debe pausar mi programa, y al volver a presionar y soltar, debe reanudarlo. Entiendo que es por flanco ascendente, pero claro... en estos pines, se detectan cambios de nivel, es decir tanto 1 a 0 como 0 a 1.

Mi programa se inicia con RB0, RB6 lo resetea, pero la duda la tengo con RB7 para utilizar un pulsador para hacer dos funciones, cualquier pequeña ayuda es bien recibida.

Gracias por adelantado.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:flanco descendente RBIE pic16f87X
« Respuesta #1 en: 03 de Abril de 2017, 14:40:01 »
Antes que nada para solucionarte la vida, en ASM si incluis el .inc podes usar los nombres de los bits, asi resulta mas facil, es decir:

Esto:
Citar
   btfsc   INTCON,2
Por esto:
Citar
   btfsc   INTCON,TMR0IF

Entonces se sabe con facilidad, tanto vos como cualquier persona que lo lea que ese bit es del Timer 0 y es el Flag de Interrupcion.

Otro problema que tenes ( en realidad no te afecta ahora ) es que te falta codigo en la interrupcion, cuando entras en la interrupcion deberias SI o SI guardar STATUS y W en registros temporales. Este codigo te lo da el datasheet, simplemente busca W_TEMP, Lo que si vas a tener en cuenta que siempre vas a tener 1 punto de entrada y 1 punto de salida. Explicado en los comentarios.

Código: ASM
  1. ISR:
  2.         MOVWF   W_TEMP                  ;Copy W to TEMP register
  3.         SWAPF   STATUS,W                ;Swap status to be saved into W
  4.         CLRF    STATUS                  ;bank 0, regardless of current bank, Clears IRP,RP1,RP0
  5.         MOVWF   STATUS_TEMP     ;Save status to bank zero STATUS_TEMP register
  6.         MOVF    PCLATH, W               ;Only required if using pages 1, 2 and/or 3
  7.         MOVWF   PCLATH_TEMP     ;Save PCLATH into W
  8.         CLRF    PCLATH                  ;Page zero, regardless of current page
  9.  
  10.  
  11.         ; Aca pones todo el codigo que quieras de la interrupcion
  12.         ; Si queres salir de la interrupcion en ves de usar RETFIE
  13.         ; Haces un GOTO Salir_ISR, asi se reestablecen los valores que tenia
  14.         ; Antes de entrar a la interrupcion
  15.  
  16. Salir_ISR:
  17.         MOVF    PCLATH_TEMP, W  ;Restore PCLATH
  18.         MOVWF   PCLATH                  ;Move W into PCLATH
  19.         SWAPF   STATUS_TEMP,W   ;Swap STATUS_TEMP register into W
  20.         MOVWF   STATUS                  ;Move W into STATUS register
  21.         SWAPF   W_TEMP,F                ;Swap W_TEMP
  22.         SWAPF   W_TEMP,W                ;Swap W_TEMP into W
  23.         RETFIE

No me puse a ver demasiado el programa, pero no es necesario que TODO sea por interrupcion...
Por interrupcion haces lo de incrementar y mostrar .. NADA MAS
En tu MAIN te pones a verificar los botones de forma simple...
Lo mas simple es esto:

Código: ASM
  1. MAIN:
  2.         BTFSS   PORTB,0
  3.         CALL    BOTON_INIT              ;Si es 0 entra
  4.         BTFSS   PORTB,6
  5.         CALL    BOTON_RESET             ;Si es 0 entra
  6.         BTFSS   PORTB,7
  7.         CALL    BOTON_PAUSA             ;Si es 0 entra
  8.         GOTO    MAIN                    ; Loop infinito
  9.  
  10. BOTON_INIT:
  11.         BTFSS   PORTB,0                 ; Entro aca si era 0, ahora debo esperar que suelte
  12.         GOTO    $-1                             ; El $ indica la direccion de memoria de esta linea, el -1 hace que sea un GOTO a la instruccion anterior
  13.         BSF     MIFLAG, 0               ; Utilizo el bit 0 para indicar que funciona o no, lo pongo en 1 que me indica que debo contar
  14.         RETURN
  15.  
  16. BOTON_RESET:
  17.         BTFSS   PORTB,0                 ; Entro aca si era 0, ahora debo esperar que suelte
  18.         GOTO    $-1                             ; El $ indica la direccion de memoria de esta linea, el -1 hace que sea un GOTO a la instruccion anterior
  19.         BCF     MIFLAG, 0               ; Utilizo el bit 0 para indicar que funciona o no, Lo pongo en 0, ya que no deberia contar mas
  20.         ;Aca borrar el contador
  21.         RETURN
  22.  
  23. BOTON_PAUSA:
  24.         BTFSS   PORTB,0                 ; Entro aca si era 0, ahora debo esperar que suelte
  25.         GOTO    $-1                             ; El $ indica la direccion de memoria de esta linea, el -1 hace que sea un GOTO a la instruccion anterior
  26.         MOVLW   0x01                    ; Cargo b'0000 0001' Al hacer una XOR estoy invirtiendo el primer bit
  27.         XORWF   MIFLAG, F               ; Aca invierto.
  28.         RETURN

En tu interrupcion solo deberias preguntar por el bit 0 del registro/variable MIFLAG,
En la interrupcion:
Si es 1 procedes a recargar el timer, incrementar y mostrar, en ese orden
Si es 0 procedes a recargar el timer, y salir

Entonces con un simple

Código: ASM
  1. ISR
  2.         ; Aca codigo para salvar STATUS, W y PCLATH
  3.  
  4.         ;Aca recargo Timer
  5.  
  6.         BTFSS MIFLAG,0
  7.         GOTO Salida_ISR
  8.         ;Aca codigo de incremento y muestra
  9.  
  10.  
  11. Salida_ISR
  12.         ;Aca codigo de salida de ISR
  13.         RETFIE

Desconectado ubect

  • PIC10
  • *
  • Mensajes: 3
Re:flanco descendente RBIE pic16f87X
« Respuesta #2 en: 03 de Abril de 2017, 17:42:37 »
Hola, gracias por la respuesta, de verdad.

No suelo usar los nombres de los flags y demás que voy comprobando pero lo tendré en cuenta. Por otro lado, el profesor nos lo pide así, comprobando las interrupciones en el vector de interrupciones, y no es por otro motivo que las haga así.

Entonces, con la parte correspondiente al código que más o menos era btfss PORTB,7 goto $-1, esperaria a que cambiase? Pero no me ha quedado claro a la hora de hacer esto, como puedo resetear y pausar con el mismo botón por flanco descendente en ambos casos.

Espero haberme explicado, muchísimas gracias de verdad me has ayudado mucho!

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:flanco descendente RBIE pic16f87X
« Respuesta #3 en: 03 de Abril de 2017, 19:01:17 »
Decidi hacerlo asi porque la consigna habla solamente de la parte del contador, cumplis con que el timer incremente y muestre cada 20ms de forma correcta, pero el tratamiento de botones se hace por otro lado.

Es que es un poco insensato dejar el loop del main libre sin nada, ya que podrias, como te dije que hicieras, utilizar el main para los botones y la interrupcion para la parte de cuenta y muestra.

Tus botones manejan solamente 1 bit para indicar si pausa o continua, el cual es leido por la interrupcion y en la interrupcion decide o no incrementar el valor. Tambien para el caso especial del reset es que volves a 0 el valor.

¿Como modificar tu programa para que sea TODO por interrupciones ?

Podrias tener el mismo "sistema" de acceso a incrementar, pero distinta aplicación por parte de la botonera..
RB0 podemos configurarlo por flanco, pero RB6 y 7 no. Entonces lo primero que debemos asegurarnos es como detectar el flanco en RB6 y RB7.
Supongamos que cuando presionas el boton tenes un 0 en la entrada.
Uno deberia guardar el ultimo valor que tuvo el puerto, y luego compararlo con lo actual, si el valor guardado era 0 y el nuevo es 1, entonces quiere decir que se solto.
Quedando asi de simple:


Código: ASM
  1. ISR:
  2.  
  3.         ;Aca codigo de guardado de registros W,STATUS,PCLATH
  4.  
  5.         BTFSC   INTCON, TMR0IF
  6.         CALL    TIEMPO_CUMPLIDO                 ;SE CUMPLIO TIEMPO
  7.         BTFSC   INTCON, INTF
  8.         CALL    BOTON_START_PRESIONADO          ; BOTON START
  9.         BTFSC   INTCON, RBIF
  10.         CALL    REVISAR_BOTONES                 ; BOTON PAUSA O RESET
  11.  
  12.         ;Aca codigo de resutaracion de registros W,STATUS,PCLATH
  13.  
  14. TIEMPO_CUMPLIDO:
  15.  
  16.         BTFSS   MIFLAGS,0               ; En caso de estar apagado por los botones salir
  17.         RETURN
  18.         ;Incremento el Contador
  19.         ;Muestro en leds
  20.         RETURN
  21.  
  22. BOTON_START_PRESIONADO
  23.         BSF     MIFLAGS,0
  24.         BCF     INTCON, INTF
  25.         RETURN
  26.  
  27. REVISAR_BOTONES
  28.         MOVF    PORTB, W
  29.         ANDLW   0B11000000              ; Solo dejo los bits de mi interes.
  30.         MOVWF   TEMP                    ; Lo muevo a un registro Temporal
  31.                                         ; Comienzo a revisar pin a pin
  32.         BTFSC   VALOR_ANTERIOR,6        ; El valor anterior del puerto, era 0 ?
  33.         GOTO    REVISAR_BOTONES_7       ; Si era 1, entonces no me interesa, y voy a ver el otro boton
  34.         BTFSS   TEMP, 6                 ; Ahora reviso el valor actual, si es 1, significa flanco ascendente
  35.         GOTO    REVISAR_BOTONES_7       ; Este GOTO es por si no hubo flanco ascendente
  36.         BCF     MIFLAGS,0               ; Paro el contador, si no se quiere parar se comenta esta linea
  37.         CLRF    CONTAR_20MS             ; Limpio el contador ( porque RB6 era el reset )
  38. REVISAR_BOTONES_7:                      ; Y por las dudas continuo para ver el boton RB7
  39.         BTFSC   VALOR_ANTERIOR,7        ; Ahora RB7, El valor anterior del puerto, era 0 ?
  40.         GOTO    REVISAR_BOTONES_FIN     ; Si era 1, entonces no me interesa, ya vi los 2 botones, salgo y limpio
  41.         BTFSS   TEMP, 7                 ; Ahora reviso el valor actual, si es 1, significa flanco ascendente
  42.         GOTO    REVISAR_BOTONES_FIN     ; Este GOTO es por si no hubo flanco ascendente
  43.         MOVLW   0x01
  44.         XORWF   MIFLAGS, F              ; Simplemente pauso o reanudo, es decir invierto el valor del bit.
  45. REVISAR_BOTONES_FIN:
  46.         ; Termine de revisar los botones, limpio flag, Actualizo el ultimo valor del puerto y salgo.
  47.         MOVF    TEMP, W                 ; Actualizo el ultimo valor del puerto
  48.         MOVWF   VALOR_ANTERIOR
  49.         BCF     INTCON, RBIF
  50.         RETURN

Desconectado ubect

  • PIC10
  • *
  • Mensajes: 3
Re:flanco descendente RBIE pic16f87X
« Respuesta #4 en: 04 de Abril de 2017, 10:16:06 »
Voy a ponerme con ello, creo que entiendo la idea, ahora voy a ver si consigo que finalmente funcione. Muchas gracias!


 

anything