Manejar bien interruptores y pulsadores en asm.

Hola de nuevo:

El código que vi en un libro.
Código:
    LIST    P=16F886        ;Tipo de procesador
    INCLUDE    <P16F886.INC>    ;Definiciones de registros internos

;Ajusta los valores de las palabras de configuración durante el ensamblado.Los bits no empleados
;adquieren el valor por defecto.Estos y otros valores se pueden modificar según las necesidades

    __CONFIG    _CONFIG1, _LVP_OFF&_PWRTE_ON&_WDT_OFF&_EC_OSC&_FCMEN_OFF&_BOR_OFF     ;Palabra 1 de configuración
    __CONFIG    _CONFIG2, _WRT_OFF                                    ;Palabra 2 de configuración

    CBLOCk    0x20
    ENDC

    ERRORLEVEL -302
    #DEFINE Pulsador    PORTA,0
    #DEFINE    LED    PORTB,0

    ORG    0x00
    goto    Comienzo            ;Vector de reset
    ORG    0x05    

Comienzo    
    clrf     PORTB            ;Borra los latch de salida
    bsf        STATUS,RP0
    bsf        STATUS,RP1        ;Selecciona banco 3
    clrf    ANSEL            ;Puerta A digital
    clrf    ANSELH            ;Puerta B digital
    bcf        STATUS,RP1        ;Selecciona banco 1
    clrf    TRISB            ;RB7:RB0 se configuran como salida
    clrf    TRISC
    movlw    b'11111111'        
    movwf    TRISA            ;RA5:RA0 se configuran como entrada
    bcf        STATUS,RP0        ;Selecciona banco 0            

; CODIGO**********************************************************

Principal
    btfsc    Pulsador
    goto    Fin
;    call    Retardo_20ms
    btfsc    Pulsador
    goto    Fin
    bsf        LED
EsperaDejePulsar
    btfss    Pulsador
    goto    EsperaDejePulsar
Fin    goto    Principal

    INCLUDE    <RETARDOS.INC>
    END                        ;Fin del programa.

Este código hay un problema, te enciende el Led, pero no es capaz de apagarlo, jajaja.



Lo encontré, este es el código adecuado.
Código:
; ZONA DE CÓDIGOS ********************************************************************

    ORG    0                        ; El programa comienza en la dirección 0.
Inicio
     bsf        STATUS,RP0            ; Acceso al Banco 1.
    bsf        Pulsador            ; La línea RA4 se configura como entrada.
    bcf        LED                    ; Se configura como salida.
    bcf        STATUS,RP0            ; Acceso al Banco 0.
    bcf        LED                    ; En principio diodo LED apagado.
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.
    btfsc    LED                    ; Testea el último estado del LED.
     goto    EstabaEncendido
EstabaApagado
    bsf        LED                    ; Estaba apagado y lo enciende.
    goto    EsperaDejePulsar
EstabaEncendido
    bcf        LED                    ; Estaba encendido y lo apaga.
EsperaDejePulsar
    btfss    Pulsador            ; ¿Dejó de pulsar?. ¿(Pulsador)=1?
    goto    EsperaDejePulsar    ; No. Espera que deje de pulsar.
Fin
    goto    Principal

    INCLUDE <RETARDOS.INC>
    END
 
Última edición:
Amigos este programa porque no me corre?
estoy tratando de prender un led mediante un pulsador:
Código:
    LIST P=16F877
    #INCLUDE <P16F877.INC>
PORTA EQU 0X05
TRISA EQU 0X85
PORTB EQU 0X06
TRISB EQU 0X86

    ORG 0X00

    banksel TRISB
    movlw b'111111111'
    movwf TRISB
    banksel TRISA
    movlw b'000000'
    movwf TRISA

INICIO

    btfss PORTA,0 ;¿Entrada a 1?
    goto COMPROBAR ;No, Salta a comprobar
    goto INICIO ;Si, vuelve a testear el bit

COMPROBAR
    btfss PORTB,0 ;El led esta encendido?
    goto APAGAR ; Ve a apagar
    goto ENCENDER; No, Ve a encender

ENCENDER
    bsf PORTB,0 ; Enciender Led.
    goto INICIO ; Vuelve a INICIO.

APAGAR
    bcf PORTB,0 ; Apaga el Led.
    goto INICIO ; Vuelve a INICIO.
    END ; Fin de programa
 
Última edición por un moderador:
Amigos este programa porque no me corre?
estoy tratando de prender un led mediante un pulsador:
Tienes algunas fallas en el programa.
.- Debes tener en cuenta que el 16F877 tiene ADC en el puerto A y en el puerto E.
Si no lo configuras como digital I/O, la comprobación de estados lógicos no funciona.
.- No tienes establecida la palabra de configuración, y es importante declararla.
Si no lo haces, el compilador establece alguna por default, y no siempre es la requerida.
Ésto también se puede hacer con el programa que grabes el PIC.
.- Estás configurando el puerto B como entradas, el A como salidas, y quieres leer RA0. Así no se podrá.
.- También necesitas usar alguna rutina de retardo para evitar rebotes del pulsador.

Una corrección a tu código, sería así...
Código:
    LIST P=16F877
    #INCLUDE <P16F877.INC>
    __config    _XT_OSC & _WDTE_OFF & _PWRTE_ON & _LVP_OFF

    cblock    0x20
    count1,count2
    endc

    ORG 0X00

    bsf        STATUS,RP0
    movlw    0x06
    movwf    ADCON1
    movlw    b'11111110'
    movwf    TRISB
    bcf        STATUS,RP0
    clrf    PORTB

INICIO
    btfss    PORTA,0            ; ¿Entrada a 1?
    goto    INICIO            ; No, vuelve a testear el bit (RA0)
    call    Retardo.25
    goto    COMPROBAR        ; Si, Salta a comprobar

COMPROBAR
    btfsc    PORTB,0            ; El led esta encendido?
    goto    APAGAR            ; Si, Ve a apagar
    goto    ENCENDER        ; No, Ve a encender

ENCENDER
    bsf        PORTB,0            ; Encender Led.
    goto    INICIO            ; Vuelve a INICIO.

APAGAR
    bcf        PORTB,0            ; Apaga el Led.
    goto    INICIO            ; Vuelve a INICIO.

; Subrutina de retardo de 250ms @ 4MHz
Retardo.25
; 249993 ciclos
    movlw    0x4E
    movwf    count1
    movlw    0xC4
    movwf    count2
Retardo.25_0
    decfsz    count1,f
    goto    $+2
    decfsz    count2,f
    goto    Retardo.25_0
; 3 ciclos
    goto    $+1
    nop
; 4 ciclos (incluyendo call)
    return

    END                        ; Fin de programa
Pruébalo usando un resistencia de pull-down en RA0
Comprueba tener el pin 1 (MCLR/Vpp) hacia VDD, revisa la alimentación de los pines.
11 y 32 = VDD, 12 y 31 = VSS, y también la correcta conexión del cristal.

Suerte.
 
Última edición:
Muchas Gracias amigo
De nada, espero que hayas probado el código y que nos comentes si te funciono.

Otro detalle que se me pasó decir, es qué si incluyes la librería para el PIC con el que trabajarás,
no es necesario declarar los registros que usarás, cómo los que escribiste en tu programa...
PORTA EQU 0X05
TRISA EQU 0X85
PORTB EQU 0X06
TRISB EQU 0X86
Cuando haces uso de #INCLUDE <PXXXXXX.INC> ó INCLUDE PXXXXXX.INC
Ya no es necesario que los declares, ya que en tal librería se incluyen.
Y el compilador busca los registros declarados en las librerías agregadas.

Suerte.
 
Disculpen. Quisiera saber si está bien el código.
PHP:
LIST P = 18F4550
INCLUDE <P18F4550.INC>
;************************************************************
CONFIG FOSC = HS ;INTOSC_XT no disponible para simulación, usar HS
CONFIG PWRT = ON
CONFIG BOR = OFF
CONFIG WDT = OFF
CONFIG MCLRE = ON
CONFIG PBADEN = OFF
CONFIG LVP = OFF
CONFIG DEBUG = OFF
CONFIG XINST = OFF
; CODE ******************************************************
#define Led PORTB, 4
 
ORG 0x00    ;Iniciar el programa en el registro 0x00
 
    clrf    PORTB   ;Limpia los posibles valores actuales de PORTB
    movlw   b'1111'  ;Entradas y Salidas para PORTB
    movwf   TRISB   ;Configura TRISB <- W

INICIO
      btfss PORTB, 0
      goto Apagado
      goto Encendido
Encendido
      bsf Led
      btfss PORTB, 0
      goto Encendido
      goto Apagado
Apagado
      bcf Led
      goto INICIO
      
 
end
Cuando lo pruebo físicamente tengo presionar 2 veces o 3 para prender y lo mismo para apagar.
Suerte y se prende a la primera.

PD: Novato presente.
 

Adjuntos

  • PULSADOR.rar
    17 KB · Visitas: 4
Con un circuito DEBOUNCER

200971032127347.gif


Saludo
 
End3tz dijo:
LIST P = 18F4550
INCLUDE <P18F4550.INC>
;************************************************* ***********
CONFIG FOSC = HS ;INTOSC_XT no disponible para simulación, usar HS
CONFIG PWRT = ON
CONFIG BOR = OFF
CONFIG WDT = OFF
CONFIG MCLRE = ON
CONFIG PBADEN = OFF
CONFIG LVP = OFF
CONFIG DEBUG = OFF
CONFIG XINST = OFF
; CODE ************************************************** ****
#define Led PORTB, 4

ORG 0x00 ;Iniciar el programa en el registro 0x00

clrf PORTB ;Limpia los posibles valores actuales de PORTB
movlw b'1111' ;Entradas y Salidas para PORTB
movwf TRISB ;Configura TRISB <- W

INICIO
btfss PORTB, 0
goto Apagado
goto Encendido
Encendido
bsf Led
btfss PORTB, 0
goto Encendido
goto Apagado
Apagado
bcf Led
goto INICIO

end
Deberias cambiar el orden de las primeras 3 instrucciones, ya que primero asignas un valor al puerto sin antes configurarlo como va a trabajar. Quedaría así:

Código:
movlw   b'1111'  ;Entradas y Salidas para PORTB
movwf   TRISB   ;Configura TRISB <- W
clrf    PORTB   ;Limpia los posibles valores actuales de PORTB
Igual asi como esta, el led va a prender y apagar al presionar el botón, tendrias que esperar a soltar el pulsador para volver a leerlo, a parte del anti rebote que te posteo SSTC.

Código:
INICIO
btfss PORTB, 0
goto Apagado
goto Encendido
Encendido
bsf Led
Espera1        ; Agregado
btfsc PORTB, 0 ; Agregado
goto Espera1   ; Agregado
btfss PORTB, 0
goto Encendido
goto Apagado
Apagado
bcf Led
Espera2        ; Agregado
btfsc PORTB, 0 ; Agregado
goto Espera2   ; Agregado
goto INICIO

end
 
Atrás
Arriba