Si te podes explicar un poco mejor en el funcionamiento seria ideal.No se si esta es la forma de responder, lo siento si lo estoy haciendo mal "soy nuevo en el foro" RB0 creara la interrupcion y hara que parpadee tres veces mas una vez que se suelta RB0, mientras se mantiene presionado el led no tiene que hecer nada solo esperar hasta que se suelte para hacer los 3 parpadeos y luego apagarse, hasta que RB1 se encienda y pueda salir de el bucle y limpiar INTF para que pueda salir de la interrupcion y regresar al programa
Hasta ahora lo unico que me quedo claro es que parpadea cada medio segundo RC0
Cual es el objetivo de RB0?
Cual es el objetivo de RB1?
Si entendi correctamente:En general no era eso, creo que me explique pésimo, el programa en si lo que hace es que de arranque sin interrupción esta parpadeando continuamente a .5 segundos, mientras RB0 se mantiene presionado, el bit de RC0 esta en 0, cuando se suelta RB0 parpadea 3 veces y se apaga a través de RC0, si RB1 es presionado, mientras se mantiene presionado el bit RC0 sigue apagado, cuando se suelta es cuando vuelve a parpadear continuamente esperando que RB0 sea presionado, mi problema principal es que no activa la interrupcion no se por que pero por mas que presiono RB0 no consigo que provoque interrupcion, incluso probe con interrupciones mas simples como simplemente encender el led y no consigo que la interrupcion se de, respecto a las correcciones lo agradezco mucho creo que ahora puedo corregir a mejor mi programa solo que sigo con el mismo problema, no se da la interrupcion :( perdon.
Al soltarse RB0: Debe parpadear 3 veces.
Si se presiona y suelta RB0 finalizado el parpadeo, no debe pasar nada.
Si se presiona y suelta RB0 mientra parpadea, no debe pasar nada.
Si se presiona RB1 luego de lo anterior, debe habilitar a RB0 a hacer otros 3 parpadeos
Si se presiona RB1 mientras hace los parpadeos: ??????? voy a suponer que debe terminar los parpadeos
Si se presiona RB1 antes de que RB0 haga algo, entonces no pasa nada.
me voy a basar en lo que entendi.
Bueno te explico masomenos como va el tema de las interrupciones:
- Nunca podes tener un loop que no salga (o tener un boton como RB1 con ese goto ) dentro de la interrupcion. Si haces eso, entonces no tiene tener una interrupcion. Ya que estarias bloqueando las otras posibles interrupciones ( en caso que tengas varias) tal ves aca no te afecte, pero en si mejor acostumbrarse a eso.
- Te falta el guardar el contexto y restablecerlo al salir , con contexto me refiero a los registros STATUS, W y PCLATH, ya que si vuelve al programa principal luego de que vos cambiaste los valores de W y STATUS (valores que trabajste en la interrupcion ) no van a ser los mismos que venia usando el programa principal. Microchip ofrece el codigo, busca W_TEMP en el datasheet y lo vas a encontrar.
Esto que nombre te va a llevar a tener un solo RETFIE.
Respecto al programa, no se si vale la pena usar la interrupcion para este ejemplo, pero creo que estas intentando hacerlo asi. Asi que vamos a seguir con esa idea.
Primero vamos a la base:Código: ASM
list p=16f886 #include <p16f886.inc> __CONFIG _CONFIG1, _LVP_OFF & _FCMEN_ON & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT __CONFIG _CONFIG2, _WRT_OFF & _BOR21V CBLOCK 0x70 W_TEMP ; 0x70 STATUS_TEMP ; 0x71 ENDC ORG 0x000 GOTO INICIO ORG 0X004 GOTO INTERRUPCION INICIO ;Configuracion de puertos/modulos ; Inicializacion de cualquier variable LOOP ; Loop principal GOTO LOOP INTERRUPCION ; Guardo MOVWF W_TEMP SWAPF STATUS,W MOVWF STATUS_TEMP ; Comienza codigo de interrupcion BTFSC INTCON, INTF CALL INT_BOTON_RB0 ; Fin de codigo de interrupcion ; Reestablezco SWAPF STATUS_TEMP,W MOVWF STATUS SWAPF W_TEMP,F SWAPF W_TEMP,W RETFIE END
De aca debemos pensar el programa
La seccion de configuracion me parece correcta. Por lo que no deberia tocarse. Pero lo demas hay que pasarle una repasada.
En la interrupcion tenemos 2 casos a tener en cuenta:
- Cuando se presiona ( supongamos que va a 0V al presionarlo ) entonces es cuadno se detecta un flanco descendente. Este no nos interesa para nada.
- Cuando se suelta, si seguimos con el la idea, entonces al soltarlo tenemos un flanco ascendente. Este si nos interesa. Asi que estaria bien configurado.
Una ves detectado el boton, podriamos usar un bit de algun registro para saber si tenemos permitido hacer o no los parpadeos.
Vamos a crear un registro llamado BANDERAS el cual el bit 0 va a indicar si debe hacerse o no los parpadeos.
La interrupcion es simple... Es activar este bit y desactivar la interrupcion de RB0Código: ASM
INT_BOTON_RB0 BCF INTCON, INTF BTFSC BANDERAS, 0 GOTO ACTIVO_TODAVIA ;Por si se quiere agregar algun codigo que haga algo si es que se suelta mientras esta parpadeando BSF BANDERAS, 0 ; Activo el bit para saber que ya puede parpadear BCF INTCON, INTE ; Desactivo las interrupciones de RB0 MOVLW 0x06 MOVWF CONTADOR ; Recargo el contador de parpadeos ACTIVO_TODAVIA RETURN
Por otra parte necesitamos hacer el Loop principal, en este loop vamos a leer RB1 y actuar en consecuencia, y ademas hacer el parpadeo.Código: ASM
LOOP CALL LEER_RB1 CALL LED_TMR GOTO LOOP
Respecto a RB1:
Si estan desactivadas las interrupciones de RB0 esto nos dice que ya se presiono antes RB1, por lo que no nos interesa hacer nada en ese caso. Luego observamos si esta presionado RB1, si lo esta, procedemos a reactivar las interrupciones.Código: ASM
LEER_RB1 BTFSS INTCON, INTE RETURN ; En caso que no este activado las interrupciones ( se presione 2 veces RB1) BTFSS PORTB, 1 ; Se presiono RB1 RETURN BCF INTCON, INTF ; Limpio bandera BSF INTCON, INTE ; Activo nuevamente las interrupciones. RETURN
Respecto al parpadeo:
Aca dijimos que ibamos a usar el bit 0 de BANDERAS para saber si debiamos parpadear o no. Por eso mismo lo primero que leemos es si este bit nos habilita o no a parpadear.
De alli si esta habilitado necesitamos saber si paso o no el tiempo de parpadeo, si no paso que salga y pruebe leer RB1 y que vuelva.
Si se cumplio el tiempo, cambiamos el estado de RC0, recargamos el Timer, y borramos la bandera del Timer, ademas tenemos que llevar la cuenta de cuantas veces cambiamos la salida, por eso usamos otro registro llamado CONTADOR.
Mientras no se termina de parpadear, esto sigue, cuando se termina, pone a 0 el bit de BANDERAS, para indicar que termino y no debe entrar mas. Y la unica forma que se habilite es que se presione RB1 (para activar las interrupciones) y que luego se presione/suelte RB0 para activar nuevamente este bit.Código: ASM
LED_TMR BTFSS BANDERAS, 0 ; Tengo que parpadear ? RETURN BTFSS INTCON, T0IF ; Paso el tiempo? RETURN ; No paso el tiempo, vuelvo MOVLW 0x01 XORWF PORTC ; Invierto el estado de RC0 MOVLW .12 MOVWF TMR0 ; Recargo el timer BCF INTCON, T0IF ; Limpio bandera DECFSZ CONTADOR, F ; Decremetno la cantidad de parpadeos RETURN ;Aca llegamos cuando se termino contador BCF BANDERAS, 0 ; Se terminaron los 3 parpadeos, entonces procedo a apagar la funcion de parpadeo RETURN