Pulsador con PIC16F84A

Hola:

Teniendo un PIC16F84A quiero hacer pruebas con un pulsador. Por ejemplo, en este caso no me sale.

Es fácil hacer un interruptor, cuando lo dejas pulsado el Led está encendido, cuando pulsas el interruptor otra vez el Led se apaga.

Quiero hacer lo mismo pero con un pulsador, que no es lo mismo que un interruptor.

La idea de este pulsador es que al pulsarlo, se quede encendido un Led, al vovler al pulsar se apague. Se que este caso necesita almacenar un Flag en la memoria RAM del PIC como indica abajo.

Código:
    LIST        P=16F84A
    INCLUDE        <P16F84A>
    __CONFIG    _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC

    CBLOCK 0x0C
    Flag
    ENDC

¿Alguna idea?

Un cordial saludo.
 
Hola Meta, no necesariamente tendrías que guardar el flag para tu caso. Podrías simplemente complementar la salida cada vez que se accione el pulsador. Si el led está apagado, se encenderá al pulsar y viceversa.

Saludos
 
Lo que indicas, por lo que entiendo es un interruptor que no es lo mismo.

Es un pulsador digital que al pulsarlo y luego soltar el dedo del pulsador enciende un Led, es digital, no a palancas como interruptores.
 
No.. te entendí perfectamente lo que querías hacer, yo también hablo de un pulsador y no de un interruptor.

Yo suelo hacer lo siguiente para tu situación:

1º Escribo las líneas para detectar la acción del pulsador.
2º Una vez detectado el pulso, reviso la condición en la que se encuentra el led de salida y en base a eso ejecuto 2 acciones distintas: Si se encuentra apagado ejecuto una rutina que lo encienda (y el resto de las acciones que quisieras agregar); si se encuentra encendido, ejecuto otra rutina distinta que lo apague.

No hace falta almacenar una variable para ese caso.

Saludos
 
Hice algo parecido para que fusionase bien hice una líneas que detecte que el pulsador ya no este presionado después de la activación para la acción del led.
También lo hacía con retardo pero a veces se pasaba y prendía y apagaba varias veces rápido.
 
Última edición:
Tal como te indica mnicolau simplemente un complemento al pin de salida que quieras apagar/encender no hay mayor complicación.

- Detectas el accionamiento del pulsador
- Entras en una subrutina que simplemente complementa el pin de salida donde esta el LED, si el estaba encendido con el complemento se apaga y viceversa.
- Esperas a que el pulsador se deje de presionar.
- Sales de la subrutina y esperas al siguiente pulso.
 
Buenas:

Exacto, la variable Flag empieza con 0, en caso de que detecte .1 (decimal).

Explicado lo quiero así:
- Si pulso el pulsador RA0, que luego dejo de pulsar, enciende un led RB0. De hecho se pone a .1 el Flag para que siga el led encendido.

- Si vuelvo a pulsar el mismo pulsador y luego lo suelto, tampoco voy a dejar el dedo puesto al pulsador, el Flag se pone a 0 y el led se apaga.

Código:
; ZONA DE DATOS **********************************************************************

    LIST        P=16F84A
    INCLUDE        <P16F84A.INC>
    __CONFIG    _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC

    CBLOCK 0x0C
    Flag
    ENDC

; ZONA DE CÓDIGOS ********************************************************************

    ORG     0                        ; El programa comienza en la dirección 0.
Inicio
    bsf        STATUS,RP0                ; Acceso al Banco 1.
    clrf    PORTB                    ; Las líneas del Puerto B se configuran como salida.
    movlw    b'00011111'                ; Las 5 líneas del Puerto A se configuran como entrada.
    movwf    PORTA
    bcf        STATUS,RP0                ; Acceso al Banco 0.

Principal
    clrf    Flag
    btfss    PORTA,0                    ; Pulsador.
    goto     Principal
    btfss    Flag,0
    goto    Led_ON

Led_OFF
    movlw    .1
    movwf    Flag
    bcf        PORTB,0
    goto    Principal

Led_ON
    bsf        PORTB,0
    goto Principal

    END

Aún no me funciona.

Un cordial saludo.
 
No te funciona porque estás limpiando el flag antes de sensarlo, entonces siempre te dará 0.

Con estos cambios te va a funcionar:

Código:
Principal
    btfss    PORTA,0                    ; Pulsador.
    goto     Principal
    btfss    Flag,0
    goto    Led_ON

Led_OFF
   clrf    Flag 
     bcf        PORTB,0
    goto    Principal

Led_ON
    movlw    .1
    movwf    Flag
    bsf        PORTB,0
    goto Principal

Ahora... si en lugar de sensar el flag, sensás la salida del led, te ahorrás crear esa nueva variable, tal como te estuvimos comentando anteriormente ;).

Otra cosa, necesitarías agregar un par de líneas para evitar rebotes en el pulsador, a menos que lo hagas por hard. Ah y si estás usando el pulsador desde el pin A0 a masa (con una R desde dicho pin a +V), como se suele hacer, tendrías que cambiar el btfss PORTA,0 por un btfsc PORTA,0.

Saludos
 
Yo lo haría así:

Código:
pulsador
	btfsc	PORTA,0		;Espera que se pulse
	goto	pulsador
	movlw	b'00000001'
	xorwf	PORTB,F		;Invierte el bit 0 del puerto B
espera
	btfss	PORTA,0
	goto	espera		;Espera que el pulsador se deje de presionar
	goto	pulsador

Solo 7 instrucciones (falta también el anti-rebotes) la salida donde esta el led simplemente se invierte a cada pulsación, no importa en que estado se encuentre, y no usas ningún registro de la RAM...

El pulsador da un cero al ser presionado en este ejemplo.
 
Buenas:

Si, hay una librería llamada retardos.inc que hay que usar sobre los rebotes.

Código:
;**************************** Librería "RETARDOS.INC" *********************************
;
;    ===================================================================
;      Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
;      E. Palacios, F. Remiro y L. López.        www.pic16f84a.com
;       Editorial Ra-Ma.  www.ra-ma.es
;    ===================================================================
;
; Librería con múltiples subrutinas de retardos, desde 4 microsegundos hasta 20 segundos. 
; Además se pueden implementar otras subrutinas muy fácilmente.
;
; Se han calculado para un sistema microcontrolador con un PIC trabajando con un cristal
; de cuarzo a 4 MHz. Como cada ciclo máquina son 4 ciclos de reloj, resulta que cada
; ciclo máquina tarda 4 x 1/4MHz = 1 µs.
;
; En los comentarios, "cm" significa "ciclos máquina".
;
; ZONA DE DATOS *********************************************************************

    CBLOCK
    R_ContA                        ; Contadores para los retardos.
    R_ContB
    R_ContC
    ENDC
;
; RETARDOS de 4 hasta 10 microsegundos ---------------------------------------------------
;
; A continuación retardos pequeños teniendo en cuenta que para una frecuencia de 4 MHZ,
; la llamada a subrutina "call" tarda 2 ciclos máquina, el retorno de subrutina
; "return" toma otros 2 ciclos máquina y cada instrucción "nop" tarda 1 ciclo máquina.
;
Retardo_10micros                ; La llamada "call" aporta 2 ciclos máquina.
    nop                            ; Aporta 1 ciclo máquina.
    nop                            ; Aporta 1 ciclo máquina.
    nop                            ; Aporta 1 ciclo máquina.
    nop                            ; Aporta 1 ciclo máquina.
    nop                            ; Aporta 1 ciclo máquina.
Retardo_5micros                    ; La llamada "call" aporta 2 ciclos máquina.
    nop                            ; Aporta 1 ciclo máquina.
Retardo_4micros                    ; La llamada "call" aporta 2 ciclos máquina.
    return                        ; El salto del retorno aporta 2 ciclos máquina.
;
; RETARDOS de 20 hasta 500 microsegundos ------------------------------------------------
;
Retardo_500micros                ; La llamada "call" aporta 2 ciclos máquina.
    nop                            ; Aporta 1 ciclo máquina.
    movlw    d'164'                ; Aporta 1 ciclo máquina. Este es el valor de "K".
    goto    RetardoMicros        ; Aporta 2 ciclos máquina.
Retardo_200micros                ; La llamada "call" aporta 2 ciclos máquina.
    nop                            ; Aporta 1 ciclo máquina.
    movlw    d'64'                ; Aporta 1 ciclo máquina. Este es el valor de "K".
    goto    RetardoMicros        ; Aporta 2 ciclos máquina.
Retardo_100micros                ; La llamada "call" aporta 2 ciclos máquina.
    movlw    d'31'                ; Aporta 1 ciclo máquina. Este es el valor de "K".
    goto    RetardoMicros        ; Aporta 2 ciclos máquina.
Retardo_50micros                ; La llamada "call" aporta 2 ciclos máquina.
    nop                            ; Aporta 1 ciclo máquina.
    movlw    d'14'                ; Aporta 1 ciclo máquina. Este es el valor de "K".
    goto    RetardoMicros        ; Aporta 2 ciclos máquina.
Retardo_20micros                ; La llamada "call" aporta 2 ciclos máquina.
    movlw    d'5'                ; Aporta 1 ciclo máquina. Este es el valor de "K".
;
; El próximo bloque "RetardoMicros" tarda:
; 1 + (K-1) + 2 + (K-1)x2 + 2 = (2 + 3K) ciclos máquina.
;
RetardoMicros
    movwf    R_ContA                ; Aporta 1 ciclo máquina.
Rmicros_Bucle
    decfsz    R_ContA,F            ; (K-1)x1 cm (cuando no salta) + 2 cm (al saltar).
    goto    Rmicros_Bucle        ; Aporta (K-1)x2 ciclos máquina.
    return                        ; El salto del retorno aporta 2 ciclos máquina.
;
;En total estas subrutinas tardan:
; - Retardo_500micros:    2 + 1 + 1 + 2 + (2 + 3K) = 500 cm = 500 µs. (para K=164 y 4 MHz).
; - Retardo_200micros:    2 + 1 + 1 + 2 + (2 + 3K) = 200 cm = 200 µs. (para K= 64 y 4 MHz).
; - Retardo_100micros:    2     + 1 + 2 + (2 + 3K) = 100 cm = 100 µs. (para K= 31 y 4 MHz).
; - Retardo_50micros :    2 + 1 + 1 + 2 + (2 + 3K) =  50 cm =  50 µs. (para K= 14 y 4 MHz).
; - Retardo_20micros :    2     + 1     + (2 + 3K) =  20 cm =  20 µs. (para K=  5 y 4 MHz).
;
; RETARDOS de 1 ms hasta 200 ms. --------------------------------------------------------
;
Retardo_200ms                    ; La llamada "call" aporta 2 ciclos máquina.
    movlw    d'200'                ; Aporta 1 ciclo máquina. Este es el valor de "M".
    goto    Retardos_ms            ; Aporta 2 ciclos máquina.
Retardo_100ms                    ; La llamada "call" aporta 2 ciclos máquina.
    movlw    d'100'                ; Aporta 1 ciclo máquina. Este es el valor de "M".
    goto    Retardos_ms            ; Aporta 2 ciclos máquina.
Retardo_50ms                    ; La llamada "call" aporta 2 ciclos máquina.
    movlw    d'50'                ; Aporta 1 ciclo máquina. Este es el valor de "M".
    goto    Retardos_ms            ; Aporta 2 ciclos máquina.
Retardo_20ms                    ; La llamada "call" aporta 2 ciclos máquina.
    movlw    d'20'                ; Aporta 1 ciclo máquina. Este es el valor de "M".
    goto    Retardos_ms            ; Aporta 2 ciclos máquina.
Retardo_10ms                    ; La llamada "call" aporta 2 ciclos máquina.
    movlw    d'10'                ; Aporta 1 ciclo máquina. Este es el valor de "M".
    goto    Retardos_ms            ; Aporta 2 ciclos máquina.
Retardo_5ms                        ; La llamada "call" aporta 2 ciclos máquina.
    movlw    d'5'                ; Aporta 1 ciclo máquina. Este es el valor de "M".
    goto    Retardos_ms            ; Aporta 2 ciclos máquina.
Retardo_2ms                        ; La llamada "call" aporta 2 ciclos máquina.
    movlw    d'2'                ; Aporta 1 ciclo máquina. Este es el valor de "M".
    goto    Retardos_ms            ; Aporta 2 ciclos máquina.
Retardo_1ms                        ; La llamada "call" aporta 2 ciclos máquina.
    movlw    d'1'                ; Aporta 1 ciclo máquina. Este es el valor de "M".
;
; El próximo bloque "Retardos_ms" tarda:
; 1 + M + M + KxM + (K-1)xM + Mx2 + (K-1)Mx2 + (M-1) + 2 + (M-1)x2 + 2 =
; = (2 + 4M + 4KM) ciclos máquina. Para K=249 y M=1 supone 1002 ciclos máquina
; que a 4 MHz son 1002 µs = 1 ms.
;
Retardos_ms
    movwf    R_ContB                ; Aporta 1 ciclo máquina.
R1ms_BucleExterno
    movlw    d'249'                ; Aporta Mx1 ciclos máquina. Este es el valor de "K".
    movwf    R_ContA                ; Aporta Mx1 ciclos máquina.
R1ms_BucleInterno
    nop                            ; Aporta KxMx1 ciclos máquina.
    decfsz    R_ContA,F            ; (K-1)xMx1 cm (cuando no salta) + Mx2 cm (al saltar).
    goto    R1ms_BucleInterno    ; Aporta (K-1)xMx2 ciclos máquina.
    decfsz    R_ContB,F            ; (M-1)x1 cm (cuando no salta) + 2 cm (al saltar).
    goto    R1ms_BucleExterno     ; Aporta (M-1)x2 ciclos máquina.
    return                        ; El salto del retorno aporta 2 ciclos máquina.
;
;En total estas subrutinas tardan:
; - Retardo_200ms:    2 + 1 + 2 + (2 + 4M + 4KM) = 200007 cm = 200 ms. (M=200 y K=249).
; - Retardo_100ms:    2 + 1 + 2 + (2 + 4M + 4KM) = 100007 cm = 100 ms. (M=100 y K=249).
; - Retardo_50ms :    2 + 1 + 2 + (2 + 4M + 4KM) =  50007 cm =  50 ms. (M= 50 y K=249).
; - Retardo_20ms :    2 + 1 + 2 + (2 + 4M + 4KM) =  20007 cm =  20 ms. (M= 20 y K=249).
; - Retardo_10ms :    2 + 1 + 2 + (2 + 4M + 4KM) =  10007 cm =  10 ms. (M= 10 y K=249).
; - Retardo_5ms  :    2 + 1 + 2 + (2 + 4M + 4KM) =   5007 cm =   5 ms. (M=  5 y K=249).
; - Retardo_2ms  :    2 + 1 + 2 + (2 + 4M + 4KM) =   2007 cm =   2 ms. (M=  2 y K=249).
; - Retardo_1ms  :    2 + 1     + (2 + 4M + 4KM) =   1005 cm =   1 ms. (M=  1 y K=249).
;
; RETARDOS de 0.5 hasta 20 segundos ---------------------------------------------------
;
Retardo_20s                        ; La llamada "call" aporta 2 ciclos máquina.
    movlw    d'200'                ; Aporta 1 ciclo máquina. Este es el valor de "N".
    goto    Retardo_1Decima        ; Aporta 2 ciclos máquina.
Retardo_10s                        ; La llamada "call" aporta 2 ciclos máquina.
    movlw    d'100'                ; Aporta 1 ciclo máquina. Este es el valor de "N".
    goto    Retardo_1Decima        ; Aporta 2 ciclos máquina.
Retardo_5s                        ; La llamada "call" aporta 2 ciclos máquina.
    movlw    d'50'                ; Aporta 1 ciclo máquina. Este es el valor de "N".
    goto    Retardo_1Decima        ; Aporta 2 ciclos máquina.
Retardo_2s                        ; La llamada "call" aporta 2 ciclos máquina.
    movlw    d'20'                ; Aporta 1 ciclo máquina. Este es el valor de "N".
    goto    Retardo_1Decima        ; Aporta 2 ciclos máquina.
Retardo_1s                        ; La llamada "call" aporta 2 ciclos máquina.
    movlw    d'10'                ; Aporta 1 ciclo máquina. Este es el valor de "N".
    goto    Retardo_1Decima        ; Aporta 2 ciclos máquina.
Retardo_500ms                    ; La llamada "call" aporta 2 ciclos máquina.
    movlw    d'5'                ; Aporta 1 ciclo máquina. Este es el valor de "N".
;
; El próximo bloque "Retardo_1Decima" tarda:
; 1 + N + N + MxN + MxN + KxMxN + (K-1)xMxN + MxNx2 + (K-1)xMxNx2 +
;   + (M-1)xN + Nx2 + (M-1)xNx2 + (N-1) + 2 + (N-1)x2 + 2 =
; = (2 + 4M + 4MN + 4KM) ciclos máquina. Para K=249, M=100 y N=1 supone 100011
; ciclos máquina que a 4 MHz son 100011 µs = 100 ms = 0,1 s = 1 décima de segundo.
;
Retardo_1Decima
    movwf    R_ContC                ; Aporta 1 ciclo máquina.
R1Decima_BucleExterno2
    movlw    d'100'                ; Aporta Nx1 ciclos máquina. Este es el valor de "M".
    movwf    R_ContB                ; Aporta Nx1 ciclos máquina.
R1Decima_BucleExterno
    movlw    d'249'                ; Aporta MxNx1 ciclos máquina. Este es el valor de "K".
    movwf    R_ContA                ; Aporta MxNx1 ciclos máquina.
R1Decima_BucleInterno          
    nop                            ; Aporta KxMxNx1 ciclos máquina.
    decfsz    R_ContA,F            ; (K-1)xMxNx1 cm (si no salta) + MxNx2 cm (al saltar).
    goto    R1Decima_BucleInterno    ; Aporta (K-1)xMxNx2 ciclos máquina.
    decfsz    R_ContB,F            ; (M-1)xNx1 cm (cuando no salta) + Nx2 cm (al saltar).
    goto    R1Decima_BucleExterno    ; Aporta (M-1)xNx2 ciclos máquina.
    decfsz    R_ContC,F            ; (N-1)x1 cm (cuando no salta) + 2 cm (al saltar).
    goto    R1Decima_BucleExterno2    ; Aporta (N-1)x2 ciclos máquina.
    return                        ; El salto del retorno aporta 2 ciclos máquina.
;
;En total estas subrutinas tardan:
; - Retardo_20s:    2 + 1 + 2 + (2 + 4N + 4MN + 4KMN) = 20000807 cm = 20 s.
;            (N=200, M=100 y K=249).
; - Retardo_10s:    2 + 1 + 2 + (2 + 4N + 4MN + 4KMN) = 10000407 cm = 10 s.
;            (N=100, M=100 y K=249).
; - Retardo_5s:        2 + 1 + 2 + (2 + 4N + 4MN + 4KMN) =  5000207 cm =  5 s.
;            (N= 50, M=100 y K=249).
; - Retardo_2s:        2 + 1 + 2 + (2 + 4N + 4MN + 4KMN) =  2000087 cm =  2 s.
;            (N= 20, M=100 y K=249).
; - Retardo_1s:        2 + 1 + 2 + (2 + 4N + 4MN + 4KMN) =  1000047 cm =  1 s.
;            (N= 10, M=100 y K=249).
; - Retardo_500ms:    2 + 1     + (2 + 4N + 4MN + 4KMN) =   500025 cm = 0,5 s.
;            (N=  5, M=100 y K=249).

;    ===================================================================
;      Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
;      E. Palacios, F. Remiro y L. López.        www.pic16f84a.com
;       Editorial Ra-Ma.  www.ra-ma.es
;    ===================================================================

La llamda que hay que usar es Retardo_20ms.

Vick, cuidado una cosa, al final usaré varios pulsadores y cada uno con su variable. Flag1, Flag2, Flag3...

Por ahora me centro en lograr lo del pulsador y luego hago los retardos.

Saludo.
 
Quizás este código entiendas el motivo de que los 20 ms funciona de maravilla.

Código:
;************************************ Pulsador_01.asm ***********************************
;
;    ===================================================================
;      Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
;      E. Palacios, F. Remiro y L. López.        www.pic16f84a.com
;       Editorial Ra-Ma.  www.ra-ma.es
;    ===================================================================
;
; Cada vez que presione el pulsador conectado al pin RA4 incrementa un contador visualizado
; en el display.
;
; ZONA DE DATOS **********************************************************************

    LIST        P=16F84A
    INCLUDE        <P16F84A.INC>
    __CONFIG    _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC

    CBLOCK  0x0C
    Contador                        ; El contador a visualizar.
    ENDC

#DEFINE Pulsador    PORTA,4            ; Pulsador conectado a RA4.
#DEFINE Display        PORTB            ; El display está conectado al Puerto B.

; ZONA DE CÓDIGOS ********************************************************************

    ORG    0                            ; El programa comienza en la dirección 0.
Inicio
      bsf        STATUS,RP0                ; Acceso al Banco 1.
    clrf    Display                    ; Estas líneas configuradas como salidas.
    bsf        Pulsador                ; Línea del pulsador configurada como entrada.
    bcf        STATUS,RP0                ; Acceso al Banco 0.
    call    InicializaContador        ; Inicializa el Contador y lo visualiza.
Principal
    btfsc    Pulsador                ; ¿Pulsador presionado?, ¿(Pulsador)=0?
    goto    Fin                        ; No. Vuelve a leerlo.
    call    Retardo_20ms            ; Espera que se estabilicen los niveles de tensión.
    btfsc    Pulsador                ; Comprueba si es un rebote.
    goto    Fin                        ; Era un rebote y sale fuera.
    call    IncrementaVisualiza        ; Incrementa el contador y lo visualiza.
EsperaDejePulsar
    btfss    Pulsador                ; ¿Dejó de pulsar?. ¿(Pulsador)=1?
    goto    EsperaDejePulsar        ; No. Espera que deje de pulsar.
Fin    goto    Principal

; Subrutina "IncrementaVisualiza" ---------------------------------------------------------

IncrementaVisualiza
    incf    Contador,F                ; Incrementa el contador y comprueba si ha
    movlw     d'10'                    ; llegado a su valor máximo mediante una
    subwf    Contador,W                ; resta. (W)=(Contador)-10.
    btfsc    STATUS,C                ; ¿C=0?, ¿(W) negativo?, ¿(Contador)<10?
InicializaContador
    clrf    Contador                ; No, era igual o mayor. Por tanto, resetea.
Visualiza
    movf    Contador,W
    call    Numero_a_7Segmentos        ; Lo pasa a siete segmento para poder ser
    movwf    Display                    ; visualizado en el display.
    return

    INCLUDE <DISPLAY_7S.INC>        ; Subrutina Numero_a_7Segmentos
    INCLUDE <RETARDOS.INC>            ; Subrutinas de retardo.
    END                                ; Fin del programa.
 
Atrás
Arriba