Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

06/08/2012 #1

Avatar de Meta

Manejar bien interruptores y pulsadores en asm.
Hola:

Teniendo un pulsador escrito en ASM sea del PIC16Fxxx. Se hace de esta manera.



Código:
INICIO
     btfss PORTA,0     ;¿Entrada a 1? ¿Interruptor pulsado?
     goto ENCENDER
     goto APAGAR
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.
Mi idea es ahcerlo con un pulsador, es decir, con el mismo botón pueda apagar un Led y encenderlo. Recuerda que es un pulsador, no interruptor. La diferencia es que al pulsar el pulsador, mientras esté pulsado pasa a estado 0, si lo dejas de pulsar, pasa otra vez a 1.

¿Cómo hago esto en ensamblador?

Un cordial saludo.

PD: Me da la impresión que el código será un poco más largo.
06/08/2012 #2
Moderador

Avatar de Chico3001

De echo el codigo es el mismo.. a menos que necesites mantener el led activo, en cuyo caso solo hay que quitar la rutina de apagado y ponerla en otro lugar despues de ejecutar la accion...
06/08/2012 #3
Moderador

Avatar de Dano

Meta dijo: Ver Mensaje
Hola:

Teniendo un pulsador escrito en ASM sea del PIC16Fxxx. Se hace de esta manera.

http://www.olimex.cl/images/tutorial...l-up/boton.jpg

Código:
INICIO
     btfss PORTA,0     ;¿Entrada a 1? ¿Interruptor pulsado?
     goto ENCENDER
     goto APAGAR
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.
Mi idea es ahcerlo con un pulsador, es decir, con el mismo botón pueda apagar un Led y encenderlo. Recuerda que es un pulsador, no interruptor. La diferencia es que al pulsar el pulsador, mientras esté pulsado pasa a estado 0, si lo dejas de pulsar, pasa otra vez a 1.

¿Cómo hago esto en ensamblador?

Un cordial saludo.

PD: Me da la impresión que el código será un poco más largo.
Lo que se hace es un biestable por decirlo de una manera simple.

Código:
INICIO
     goto APAGADO  

ENCENDIDO
     bsf PORTB,0       ; Enciender Led.
     btfsc PORTA,0     ;¿Entrada a 1? ¿Interruptor pulsado?
     goto ENCENDIDO       ; Vuelve a INICIO.
     goto APAGADO     

APAGADO
     bcf PORTB,0       ; Apaga el Led.
     btfss PORTA,0     ;¿Entrada a 1? ¿Interruptor pulsado?
     goto ENCENDIDO       ; Vuelve a INICIO.
     goto APAGADO

END     ; Fin de programa.
es bueno agregarle un detector de flancos al pulsador (electronico o programado), asi como esta diseñado cambia de estado por nivel por lo tanto si mantenes apretado el pulsador va a saltar de un estado a otro.
06/08/2012 #4

Avatar de Meta

Hola:

Lo he comprobado con el MPLAB v8.86. Se comporta como una señal cuadrada. Uso el PIC16F886.

Por si acaso, a lo mejor no me expliqué bien. Cuando pulsa el botón, el Led queda encendido. Si lo vuelves a pulsar, se apaga. Hay que dejar claro una cosa. Como es un pulsador, al pulsar tiene 0 y cuando dejo de pulsar tiene un 1. No es un interruptor y se comporta como si lo fuera. LA función con el ejemplo que me pusieron, funciona bien si dejo el botón pulsado con el dedo. Espero que lo haya explicado bien lo que quiero decir.


Aquí dejo el código.
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

            org    0x00
            goto    Inicio            ;Vector de reset
            org    0x05    

Inicio    
        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
        movlw    b'11111111'        
        movwf    TRISA            ;RA5:RA0 se configuran como entrada
        bcf        STATUS,RP0        ;Selecciona banco 0            

ENCENDIDO
         bsf PORTB,0       ; Enciender Led.
         btfsc PORTA,0     ;¿Entrada a 1? ¿Interruptor pulsado?
         goto ENCENDIDO       ; Vuelve a INICIO.
         goto APAGADO     

APAGADO
         bcf PORTB,0       ; Apaga el Led.
         btfss PORTA,0     ;¿Entrada a 1? ¿Interruptor pulsado?
         goto ENCENDIDO       ; Vuelve a INICIO.
         goto APAGADO


        END                        ;Fin del programa.
Un saludo.
06/08/2012 #5
Moderador

Avatar de Dano

Hago una acotación principalmente para los principiantes, cuando edité el código de Meta no modifique los comentarios, por lo tanto no miren los comentarios porque no tienen lógica.
06/08/2012 #6


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.

Ese te va a cambiar de apagado a encendido el led cada que presiones el pulsador
06/08/2012 #7

Avatar de Meta

Hola:

Cuando doy algunos pulsos probando. El Led nunca se enciende, jejejej.



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

            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
        movlw    b'11111111'        
        movwf    TRISA            ;RA5:RA0 se configuran como entrada
        bcf        STATUS,RP0        ;Selecciona banco 0            

; CODIGO**********************************************************
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
Un saludo.
06/08/2012 #8
Moderador

Avatar de D@rkbytes

Saludos.
Aquí pongo un ejemplo sencillo de como hacer el efecto Toggle.
Básicamente es algo como esto:
Código:
Ciclo 
; Esperar a que se presione el botón
Si_Push btfsc   GPIO,0        ; Repetir hasta que GP0 sea 0
    goto    $-1                ; No es 0, regresar 1 instrucción
; Hacer el Toggle
    bsf        GPIO,1            ; Es 0 (Encender LED) 
    xorlw    b'10'            ; Toggle sobre el bit correspondiente (GP1)
    movwf   GPIO            ; Mover W a GPIO
 ; Esperar a que se suelte el botón
No_Push btfss   GPIO,0        ; Repetir hasta que GP0 sea 1
    goto    $-1                ; No es 1, regresar 1 instrucción    
    goto    Ciclo            ; Es 1, repetir el ciclo
Adjunto una simulación para el 12F508 que use para hacer la prueba.
Pero el código también funciona para otros PIC.

Nota: También lo probe fisicamente.
Quizás solo haga falta agregar un pequeño retardo, pero así funciona bien.
Suerte.
Archivos Adjuntos
Tipo de Archivo: rar LED TOGGLE ASM.rar (7,6 KB (Kilobytes), 90 visitas)
06/08/2012 #9

Avatar de Meta

Buenas:

Ahora mismo no dispongo de simulador Proteus. Deja ver si lo consigo instalar.

Lo voy a adaptar al 16F886 que es que dispongo ahora mismo para simularo con un módulo físico. Haber si esta vez funciona.

En tu caso usa memoria RAM. Estaba averiguando si hay manera de no hacerlo así, jeejjee. Entre la memoria RAM y usarlo sin RAM, hay que ver cual usas menos código.

Gracias por tu ejemplo y tiempo, incluyendo a los demás.
06/08/2012 #10

Avatar de fdesergio

El gran problema es que no tienes en cuenta el rebote del pulsador (en la parte real) debes cada vez que vas a la subrutina de cambio de estado hacer un delay y revisar nuevamente el pulsador para ver si continua en el estado correcto, personalmente uso un delay de 150mS pq es el tiempo normal que mantiene uno presionado un pulsador y que sea valido, chauuuuuuuuu
06/08/2012 #11

Avatar de Meta

Si lo tengo en cuenta, lo haré al final de todo.
06/08/2012 #12
Excluido


les hago una consulta:
ustedes en la realidad usan eso ????

yo cuando programaba en asm como venia de la costumbre de el tema de los rebotes de pulsadores y ruidos siempre para mi la deteccion de un pulsadr NO era verificar la entrada una vez y listo, no .
siempre tenia una rutina de verificacion, en la cual hacia avanzar un contador y solo si el contador llegaba a tal valor ahi se daba por confirmada.
o sea verificaba en la interrupcion que la entrada sea igual digamos 10 tiempos , o lo que sea.

digamos que me aseguraba que el pulsador este pulsado 50 o 100ms .
idem al soltar si lo ameritaba .

ustedes no hacen asi ???
06/08/2012 #13
Moderador

Avatar de D@rkbytes

fernandob dijo: Ver Mensaje
les hago una consulta:
ustedes en la realidad usan eso ????

yo cuando programaba en asm como venia de la costumbre de el tema de los rebotes de pulsadores y ruidos siempre para mi la deteccion de un pulsadr NO era verificar la entrada una vez y listo, no .
siempre tenia una rutina de verificacion, en la cual hacia avanzar un contador y solo si el contador llegaba a tal valor ahi se daba por confirmada.
o sea verificaba en la interrupcion que la entrada sea igual digamos 10 tiempos , o lo que sea.

digamos que me aseguraba que el pulsador este pulsado 50 o 100ms .
idem al soltar si lo ameritaba .

ustedes no hacen asi ???
Pues, yo lo que generalmente hago, es después de la comparación de botón pulsado llamar a una rutina de retardo.
Por lo regular de 100 a 250 mS, pero dependiendo del tipo de rutina a seguir.
Si quiero avances rápidos, el retardo lo hago más corto.
Por ejemplo para hacer avanzar un contador, ó hacer el cambio de canales de un sintonizador.
En esos casos se requiere de un avance más o menos rápido.
Y si la rutina es por ejemplo, solo hacer cierta tarea y regresar, entonces el retardo lo hago más largo.

Saludos fernandob
07/08/2012 #14

Avatar de Meta

fernandob dijo: Ver Mensaje
les hago una consulta:
ustedes en la realidad usan eso ????

yo cuando programaba en asm como venia de la costumbre de el tema de los rebotes de pulsadores y ruidos siempre para mi la deteccion de un pulsadr NO era verificar la entrada una vez y listo, no .
siempre tenia una rutina de verificacion, en la cual hacia avanzar un contador y solo si el contador llegaba a tal valor ahi se daba por confirmada.
o sea verificaba en la interrupcion que la entrada sea igual digamos 10 tiempos , o lo que sea.

digamos que me aseguraba que el pulsador este pulsado 50 o 100ms .
idem al soltar si lo ameritaba .

ustedes no hacen asi ???
Esa idea es original.

Como un reloj CASIO. Si te fijas bien a cambiar de modo.

Al pulsar el botón "MODE" desde que lo pulse cambia de modo, claro como es un pulsador vuelve al estado original como normalmente abierto "N/A". Así es lo que quiero usar el botón.

En estos momentos estoy adaptando el código del 12F508 al 16F886 para saber si funciona, lo del retardo lo haré despué shaber donde lo meto.

Gracias a todos, luego publico el código.

---------- Actualizado después de 21 minutos ----------

Hola:

Algo no hice bien, doy el pulso, sube pero no baja.



Su código es:
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

            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
        movlw    b'11111111'        
        movwf    TRISA            ;RA5:RA0 se configuran como entrada
        bcf        STATUS,RP0        ;Selecciona banco 0            

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


Ciclo 
; Esperar a que se presione el botón
Si_Push 
    btfsc   PORTA,0        ; Repetir hasta que GP0 sea 0
    goto    Si_Push                ; No es 0, regresar 1 instrucción
; Hacer el Toggle
    bsf        PORTB,1            ; Es 0 (Encender LED) 
    xorlw    b'00000010'            ; Toggle sobre el bit correspondiente (GP1)
    movwf   PORTB           ; Mover W a GPIO
 ; Esperar a que se suelte el botón
No_Push 
    btfss   PORTA,0        ; Repetir hasta que GP0 sea 1
    goto    No_Push                ; No es 1, regresar 1 instrucción    
    goto    Ciclo            ; Es 1, repetir el ciclo

    END                        ;Fin del programa.
Saludo.
07/08/2012 #15
Moderador

Avatar de D@rkbytes

Meta dijo: Ver Mensaje
Algo no hice bien, doy el pulso, sube pero no baja.
Desafortunadamente no tengo el PIC16F886 para ver que pasa.
Pero tengo el PIC16F88 que es algo similar, y adapte el código a este PIC y funciono bien.
Este es el programa adaptado.
Código:
    list    p=16f88
    #include <p16f88.inc>

     __CONFIG    _CONFIG1, _INTRC_IO & _CP_OFF & _CCPMX_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF
     __CONFIG    _CONFIG2, _IESO_OFF & _FCMEN_OFF
    errorlevel    -302

    org    0x00

Inicio
    bsf        STATUS,RP0        ; Ir al banco 1
    movlw    0xFF            ; Todo el puerto A como entradas
    movwf    TRISA
    movlw    b'11111101'        ; RB1 como salida
    movwf    TRISB
    movlw    b'01110100'        ; Configurar el registro OSCCON a 8MHz estable
    movwf    OSCCON
    clrf    ANSEL            ; Todos los pines como entradas digitales. (Incluyendo RB5 y RB6)
    bcf        STATUS,RP0        ; Ir al banco 0
    clrf    PORTB

Ciclo 
; Esperar a que se presione el botón
Si_Push btfsc   PORTA,0        ; Repetir hasta que RA0 sea 0
    goto    $-1                ; No es 0, regresar 1 instrucción
; Hacer el Toggle
    xorlw    b'10'            ; Toggle sobre el bit correspondiente (RB1)
    movwf    PORTB            ; Mover W al puerto B
 ; Esperar a que se suelte el botón
No_Push btfss   PORTA,0        ; Repetir hasta que RA0 sea 1
    goto    $-1                ; No es 1, regresar 1 instrucción   
    goto    Ciclo            ; Es 1, repetir el ciclo

    end
Note que al declarar algunos o todos los pines del puerto B como salidas,
al hacer la función toggle, los pines del puerto B toman valor 1 por mover el resultado al puerto B.
Pero el toggle se sigue realizando sobre el bit establecido en el XORLW B'10' ; (RB1)
Puede ser que por ahí este el problema, habrá que realizar más pruebas.

Saludos.
07/08/2012 #16

Avatar de Meta

Ahora ocurre lo mismo pero al revés.


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

            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**********************************************************


    Ciclo 
; Esperar a que se presione el botón
Si_Push btfsc   PORTA,0        ; Repetir hasta que RA0 sea 0
    goto    $-1                ; No es 0, regresar 1 instrucción
; Hacer el Toggle
    xorlw    b'10'            ; Toggle sobre el bit correspondiente (RB1)
    movwf    PORTB            ; Mover W al puerto B
 ; Esperar a que se suelte el botón
No_Push btfss   PORTA,0        ; Repetir hasta que RA0 sea 1
    goto    $-1                ; No es 1, regresar 1 instrucción   
    goto    Ciclo            ; Es 1, repetir el ciclo

    END                        ;Fin del programa.
Pensando bien. Hay que hacer pruebas y las sigo haciendo sobre la instrucción btfss o btfsc solo con la memoria RAM. Me explico.
Una variable llamada Flag,0. Sólo cambia el bit de menor pero que es el 0.
Si el btfss Flag,0 ; es 1.
goto APAGAR
goto ENCENDER ; Salta aquí.

Cosas así. El problema que no estamos con modo interruptor, sino modo pulsador, por eso es más complicado.

Cuando sea uno irá a goto ENCENDER, si dejas de pulsar, se comporta como interruptor y vuelve a 0 y se apaga. El dilema que el pulsador al pulsarlo se quede encendido y al pulsarlo de nuevo se quede apagado el Led. No el efecto de que al pulsarlo se quede encendido siempre y no puedas apagarlo o que al pulsarlo o dejarlo pulsado se enciende y cuando lo dejas de pulsar se vuelva a apagar. Fuerte lío lo que acabo de decir.

Recuerdo que en el 2009 lo hice, ahora no recuerdo y debo aprenderlo otra vez y anotar estos apuntes. El ASM si no lo practicas lo olvidas muy rápido más que a la hora de aprenderlo.

Seguiré haciendo pruebas.
07/08/2012 #17
Moderador

Avatar de Dano

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

            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**********************************************************


Ciclo 
								; Esperar a que se presione el botón
Si_Push btfsc   PORTA,0        ; Repetir hasta que RA0 sea 0
 	    goto    Si_Push               ; No es 0, regresar 1 instrucción
								; Hacer el Toggle
    COMF    PORTB            ; COMPLEMENTA RB
	GOTO	Si_Push

    END                        ;Fin del programa.
Probado en MPLAB funciona perfecto, lo reduje mas al codigo, son 4 lineas ahora .

Reitero lo que dije antes, es necesario agregarle un detector de flancos pero mas alla de eso es 100% funcional.
07/08/2012 #18

Avatar de Meta

Hola:

No funciona. Lo probé con "Toggle" y el "Pulse High". Pulse High es el ideal para probarlo.

Si te refieres un detector de flancos, pues si, una direción de RAM basta. Es lo que estoy haciendo, lo haré así y sin RAM. Estoy haciendo a mano un diagrama de flujo, parece ser que se necesita hacer como mínimo tres instrucciones de salto sea el btfss o el btfsc.

Sigo investigando.

---------- Actualizado después de 35 minutos ----------

Parece que ahor ame funciona. DEbo usar retardos para antirrebores, lo probaré con hardware.

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

    ERRORLEVEL -302
    #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**********************************************************

Led_OFF
    bcf        LED         ; Apagar Led.
    btfss    PORTA,0        ; ¿Entrada 0? ¿Botón pulsado?
    goto    Led_OFF        ; Apagar Led.
    goto    Led_ON        ; Encender Led.
Led_ON
    bsf        LED            ; Encender Led.
    btfss    PORTA,0        ; ¿Entrada 0? ¿Botón pulsado?
    goto    Led_ON        
    goto    Led_OFF

    END                        ;Fin del programa.
En MPLAB simulando debo pulsar varias veces el pulsador para que me haga caso, cuando lo logro, me funciona. No hace falta RAM.

A probarlo ustedes que a lo mejor sacan mejores resultado que yo.

Sigo probando por si acaso.

Un saludo y gracias a todos.
08/08/2012 #19
Moderador

Avatar de D@rkbytes

Con estos cambios que realice al programa, funciono mejor.
También le agregue una rutina de retardo antirebotes de 150ms.

Con el programa anterior, no funcionaba con la rutina de retardo y ahora si.
Código:
Si_Push
    btfsc    PORTA,0            ; Comparar que RA0 sea 0
    goto    Si_Push            ; No es 0, regresar
    call    Demora            ; 150ms de retardo antirebote
    movlw    b'10'            ; Establecer el bit 1 (RB1)
    xorwf    PORTB,F            ; Realizar el cambio de estado (Toggle)
No_Push
    btfss    PORTA,0            ; Comparar que RA0 sea 1
    goto    No_Push            ; No es 1, regresar
    goto    Si_Push            ; Es 1, repetir el ciclo
La rutina de retardo la genere con el programa PIC Delayer (PDEL)
Igualmente probé el programa con un 16F88 y funciona excelentemente.

Saludos.
08/08/2012 #20

Avatar de Meta

Buenas:

Con lo mismo hice este y en simulador me funciona.
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    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**********************************************************

Led_OFF
    bcf        LED         ; Apagar Led.
    btfss    PORTA,0        ; ¿Entrada 0? ¿Botón pulsado?
    call    Retardo_20ms
    goto    Led_OFF        ; Apagar Led.
    goto    Led_ON        ; Encender Led.
Led_ON
    bsf        LED            ; Encender Led.
    btfss    PORTA,0        ; ¿Entrada 0? ¿Botón pulsado?
    call    Retardo_20ms
    goto    Led_ON        
    goto    Led_OFF

    INCLUDE    <RETARDOS.INC>
    END                        ;Fin del programa.
En un libro acaba de encontrar el adecuado, más efectivo que le mio.
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.