buena caballero y yo que me encontraba 0.00001% de estas instrucciones y ejemplos que me estas indicando estan callendo en el punto.
ademas siempre tengo la costumbre de colocar una resistencia a tierra y preguntar por unos pero eso no es un inconveniente en esto..
bueno ahi biene la pregunta si yo pregunto por unos o sea coloco una resistencis a tierra y conecto el pulsador a vcc. entonces cogeria
clrf mascara
movf porta,0
andwf mascara,1
btfss status,2
return
sigue el retardo
ahi se eliminaria le complemento de comf porta ya que no seria necesario.
como el puerto esta a tierra y al hacer AND con mascara que tambien es 0
se me activa el bit 2 de status lo cual no hay ningun pulsador presionado y el progarama sigue su retardo normal hasta que se acabe.
siguen rotando los leds con 5seg de retardo y sigo preguntado.
al salir del retardo por un pulsador
btfsc mascara,0
goto primer
btfsc mascara,1
goto segundo
btfsc mascara,2
goto tercer
caballero digame como boy .
el retardo sigue si no pulso ningun pulsador ya aqui no se toma en cuenta el tiempo pulsado en el pulsador si no que se debe atender el pulsador inmediatamente sin esperar nada.
con el programa que usted me corrigio en el otro link que el problema era del direccines generales del pic 16f873A.
tengo un retardo de 5seg y como la pregunta de los pulsadores la tengo es fuera de retardo tengo que demorar un largo rato presionando culaquier pulsador para que sea atendido.
y con esta explicacion ya se como es atendido inmediatemente sin alterar el stack de la pila y reducindo el programa.
caballero si no es un inconveniente de seguirle preguntando de esto ya que me quedan mas dudas.
gracias y saludos
No tengo problemas en responderte todas las preguntas que te surjan u ocurran. Sera un placer responderlas.
Con respecto a esto:
clrf mascara
movf porta,0
andwf mascara,1
btfss status,2
return
sigue el retardo
No va a funcionar.
Fijate que tenes pones a Mascara en todos ceros.
Entonces veamos que sucede que no funcionará:
clrf Mascara
Entonces Mascara = b'00000000'
movf PORTA,w
Entonces W = b'XXXXXXXX'
andwf Mascara,1
la AND es una multiplicacion bit a bit:
Hagamosla:
Mascara = b'00000000'
W = b'XXXXXXX'
Resultado: b'00000000'
Entonces Mascara = b'00000000'
Recorda que 0 * X = siempre 0. Ahi se hacen 8 multiplicaciones entre los bit analogos de Mascara y W.
Ese algoritmo tengas presionado o no los pulsadores, va a ejecutar el segundo entero de demora.
Mascara siempre valdra 0x00, por lo que tambien saldra de la subrutina valiendo 0x00.
Cuando salga valiendo 0x00, obviamente no va a ejecutar nunca ninguna rutina.
Entonces, veamos como hacer para que funcione con pulsadores como los tienes configurados tu( 0= no presionado, 1= presionado)
Ejemplo: si PORTA,0 es mantenido durante el segundo entero, deberia salir el bit Mascara,0 en alto para poder desviar el programa hacia primer.
Tengamos en cuenta un factor que tal vez no habias percatado:
Tenes conectados 4 pulsadores solamente en el puerto A. ¡Ojo! hay que tener en cuenta los otros 4 bits del puerto A tambien, ya que sino pueden "ensuciar" la variable Mascara, y que no pueda salir de la subrutina antes de tiempo si no hay pulsadores presionados.
Recorda que cuando lees un puerto como el Puerto A, esten configurados como entradas o salidas sus pines, te va a leer los valores de los pines igualmente.
Vamos a ver entonces...
Primero, deberiamos lograr descartar esos bits del puertoA que no estan conectados a pulsadores, o bien conectados a ellos pero que no nos interesan si se pulsan o no.
Para esto entonces podriamos optar por dos opciones. Definimos los bits a ignorar del puertoA como 0 y los que queremos revisar como 1 o viceversa.
El binario no nos deja muchas otras posibilidades, ¿eh?
Lo mas simple es definir los bits a revisar en alto, y el resto en bajo, entonces hacemos:
movlw b'00001111' ;indiquemos con altos los bits a revisar del PUERTOA!(RA0,RA1,RA2,RA3)
call UNO_SEG
Sigamos. Entonces, la idea es esta. Todo bit que yo cargue alli con un alto, deberia salir alto transcurrido el segundo(o antes si se sueltan todos).
Entonces necesito solo 1 cosa. Una instruccion que me cambie el valor de ese bit de Mascara si se solto el pulsador antes de completarse el segundo de demora: Necesito que esa instruccion mantenga ese valor cambiado, independientemente de lo que pase luego dentro de la demora con el pulsador ese.
Entonces, si tengo un 1 inicialmente indicando que voy a revisar ese pulsador, necesito algo que me cambie el valor de ese bit si el pulsador deja de presionarse antes del segundo.
La funcion es otra vez, la AND.
Llevemoslo a la practica.
ingresa Mascara cargada con un bit en ALTO(1).
luego leemos el puertoA y lo guardamos en W.Hacemos una AND entre W y Mascara
1
AND
X
Da como resultado 1 si X= 1. Si X= 0 el resultado sera 0.
¿Por que? Para que una multiplicacion binaria de como resultado 1 ambos bits de las variables a comparar deben valer 1. Facil.
Entonces, si se suelta en algun momento el pulsador la AND hace esto:
1
AND
0
Da como resultado 0. Esto provoca que Mascara ahora tenga ese bit en BAJO.
NO HAY NADA QUE PUEDA HACER QUE ESE BIT DE MASCARA VUELVA A VALER UN ALTO NUEVAMENTE dentro de la subrutina. ¿Por que?
Porque ahora ese bit de Mascara vale cero, y al hacer todas las AND posteriores dentro del retardo pasara esto:
0
AND
X
Siempre devuelve 0.
¿Para que nos ha servido?
Nos ha servido para indicar que el pulsador se solto antes de tiempo. Hemos afectado a ese bit de Mascara de manera que no pueda volver a valer un ALTO.
¿Cómo saber cuando se han soltado todos los pulsadores a revisar?
Si te fijas, veras que la funcion AND puede poner bits en BAJO, pero jamas en ALTO si una de los dos bits a comparar esta en BAJO. Esta es la propiedad caracteristica de esta instruccion.
Entonces, significa que si Mascara = 0x00 querra decir que no hay pulsadores presionados, y haremos entonces que salga de la subrutina de demora antes de completar el segundo.
El código:
movlw b'00001111' ;definimos como 1 los bits a revisar del PUERTOA!(RA0,RA1,RA2,RA3)El resto en 0
call UNO_SEG
btfsc Mascara,0 ;Pulsador RA0 mantenido durante 1 seg?
goto prog1 ;Si. Saltar a prog1
btfsc Mascara,1 ;Pulsador RA1 mantenido durante 1 seg?
goto prog2 ;Si. Saltar a prog2
btfsc Mascara,2 ;Pulsador RA2 mantenido durante 1 seg?
goto prog3 ;Si. Saltar a prog3
btfsc Mascara,3 ;Pulsador RA3 mantenido durante 1 seg?
goto prog3 ;Si. Saltar a prog3
goto siga
UNO_SEG
movwf Mascara ;Volquemos los bits a revisar del PUERTOA en una variable
movlw .14
movwf PDel0
PLoopx movlw .72
movwf PDel1
PLoopy movlw .247
movwf PDel2
PLoopz movf PORTA,W ;copiar el valor del puertoA en W
andwf Mascara,F ;Inclusión de bits entre Mascara y el PUERTOA
btfsc STATUS,Z ;¿Mascara= 0?
return ;Si. Volver
decfsz PDel2, 1 ;No. continuar revisando
goto PLoopz
decfsz PDel1, 1
goto PLoopy
decfsz PDel0, 1
goto PLoopx
PDelL1 goto PDelLx
PDelLx clrwdt
return
Te recomiendo que si sabes usar el MPLAB SIM, simules esto(no lo he hecho yo) para comprender como funciona.
Sino, agarra papel y lapiz y simula el programa y fijate que Mascara no varia si un pulsador en PORTA se mantiene presionado, y lo que sucede en Mascara cuando se suelta.
Saludos