Autor Tema: Una duda me ayudan? miren que pasa!  (Leído 2159 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado pikman

  • Moderador Local
  • PIC24F
  • *****
  • Mensajes: 679
Una duda me ayudan? miren que pasa!
« en: 14 de Febrero de 2006, 15:39:00 »
Hola a todos, y como siempre gracias por leer, el pedazo de codigo que le muestro mas abajo, con el cual perdi un monton de tiempo porque yo necesito una condicion logica OR entre una variable y una entrada y para esto escribi:

 while ((minuter!=30) || (!input(_alarm)));

y el CCS genera este ASM

0676:  MOVF   58,W
0678:  SUBLW  1E
067A:  BNZ   0676
067C:  BTFSS  F81.3
067E:  BRA    0676

En lugar de un OR, me genera una AND!!!,




Y ya quemado de puse esto

while ((minuter!=30) && (!input(_alarm)));

Y fijense genero el codigo de una OR!! y anda

0676:  MOVF   58,W
0678:  SUBLW  1E
067A:  BZ    0680
067C:  BTFSS  F81.3
067E:  BRA    0676

Si la variable minuter es igual a 30 (óGiño la entrada _alarm es 1 salta
si no  espera.


No se cual puede ser el problema, no veo el error mas que una fatalidad
del compilador, estoy compilando con la version 3.242, voy a probar con anteriores, pero es una locura que realmente el compilador cometa este error!!, que puede volver loco a cualquiera, en especial aquellos que no tengan conocimientos de lenguaje ASM, el microcontrolador utilizado es un PIC18F452.

saludos y espero estar equivocado o que el codigo este mal escrito.

ARIEL



saludos
PikMan

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: Una duda me ayudan? miren que pasa!
« Respuesta #1 en: 15 de Febrero de 2006, 01:10:00 »
Lo acabo de probar con v3.241 y es como dices van al revés:

....................    while (cant!=30);
005E:  MOVF   06,W
0060:  SUBLW  1E
0062:  BNZ   005E
....................    
....................    while (cant==30);
0064:  MOVF   06,W
0066:  SUBLW  1E
0068:  BZ    0064

¡Vaya jugada del compilador!

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
RE: Una duda me ayudan? miren que pasa!
« Respuesta #2 en: 15 de Febrero de 2006, 01:15:00 »
Pues yo no lo veo al revés, Pocher.

De ASM no entiendo mucho, pero me parece interpretar en tus dos ejemplos que el compilador lo ha hecho correctamente.

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: Una duda me ayudan? miren que pasa!
« Respuesta #3 en: 15 de Febrero de 2006, 01:23:00 »
BZ salta si el bit Z del Status es 0, es decir si la operación anterior (la resta) no ha sido cero ... y eso no se corresponde con el while

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
RE: Una duda me ayudan? miren que pasa!
« Respuesta #4 en: 15 de Febrero de 2006, 01:40:00 »
Disculpa que insista, pero en la data el 18F452, página 284 dice:
BZ Branch if Zero
Syntax: BZ n
Operands: -128 ≤ n ≤ 127
Operation: if ZERO bit is ‘1’
(PC) + 2 + 2n → PC
Status Affected: None
Encoding: 1110 0000 nnnn nnnn
Description: If the ZERO bit is ‘1’, then the program
will branch.


Por lo que sigo pensando que el compilador lo hace bien, lo cual por otra parte, es lo lógico.

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: Una duda me ayudan? miren que pasa!
« Respuesta #5 en: 15 de Febrero de 2006, 02:24:00 »
Tienes razón Nocturno, lo había interpretado mal.

BZ k -------> Branch on Zero --------> Equivalente a: BTFSC 3,2 + GOTO k

Sin embargo lo de Pikman sigue sin cumplirse:

while ((minuter!=30) && (!input(_alarm)));

Y fijense genero el codigo de una OR!! y anda

0676: MOVF 58,W
0678: SUBLW 1E
067A: BZ 0680
067C: BTFSS F81.3
067E: BRA 0676

Si el bit Z=1 (minuter=30) ya salta y no comprueba el !input

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
RE: Una duda me ayudan? miren que pasa!
« Respuesta #6 en: 15 de Febrero de 2006, 03:57:00 »
Insisto, esa compilación es correcta. Fijáos que si "minuter=30" ya no es necesario que se verifique el pin de entrada para salir de la condición, puesto que se incumple una de las dos partes del AND.
De hecho, el compilador lo construye como un "OR" porque es una simplificación lógica: un AND sobre dos negaciones es equivalente a un OR sobre dos afirmaciones.

Llevado al ejemplo de Pikman, es lo mismo decir:
     while ((minuter!=30) && (!input(_alarm)));
que
     while ((minuter==30) || (input(_alarm));

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: Una duda me ayudan? miren que pasa!
« Respuesta #7 en: 15 de Febrero de 2006, 04:16:00 »
Pués sí que estoy espeso hoy, no doy una. Así es Manolo.

10f206

  • Visitante
RE: Una duda me ayudan? miren que pasa!
« Respuesta #8 en: 15 de Febrero de 2006, 16:07:00 »
Que les pasa jovenes, en el diversificado no les quedo claro esto?

por la 3era de Boole la disyuncion no es mas que la negacion de la conjuncion con sus secciones negadas, es decir a and b = not (not a or not b) por contraposicion es lo mismo decir a or b que not (not a and not b), para los compiladores es mucho mas sencillo trabajar todo en verdadero, que en falso, es decir que buscar el complemente una vez es preferible que 2 veces, por eso pasa lo que pasa.

Colocandolo en terminos mas seculares quedaria como esto:

si no has hecho la tarea o no has terminado tu almuerzo entonces no sales a jugar

es lo mismo que

haz tu tarea y  termina tu almuerzo y entonces saldras a jugar



es lo mas sencillo del este mundo.


Saludos cordiales.

Desconectado pikman

  • Moderador Local
  • PIC24F
  • *****
  • Mensajes: 679
RE: Una duda me ayudan? miren que pasa!
« Respuesta #9 en: 15 de Febrero de 2006, 20:55:00 »
Hola, gracias a todos por la ayuda,

nocturno66 dice que

Llevado al ejemplo de Pikman, es lo mismo decir:

while ((minuter!=30) && (!input(_alarm)));

mientras ( minuter no sea igual a 30  "AND"  la entrada _alarm no sea igual a 1 )

que

while ((minuter==30) || (input(_alarm));

mientras ( minuter sea igual a 30 "OR" la entrada _alarm sea igual a 1 )



Sin embargo el codigo generado para


while ((minuter!=30) && (!input(_alarm)));

es una OR

0676:  MOVF   58,W  
0678:  SUBLW  1E        ; resta para comparar si es igual
067A:  BZ    0680         ; sale del bucle
                                    ; "OR"
067C:  BTFSC  00.0      ; Si la entrada es 0 a cero salta y sale del bucle
067E:  BRA    0676       ; si no sigue en el while  

0680:  BRA    0590

Por lo tanto lo que yo entiendo es que si se cumplen 30 minutos "O" que la
entrada es cero sale del bucle y salta a la linea 590, no hay dudas que se cumple
una condicion "O" y el operador empleado en el codigo es AND.


Esto seria lo mismo?, odeberia generar el mismo codigo?

while ((minuter==30) || (input(_alarm));

esto es lo que genera el compilador



0676:  MOVF   58,W
0678:  SUBLW  1E      ; resta para comparar el valor
067A:  BZ    0676       ; y se queda esperando que sea 30!!??

                                      "AND" y
067C:  BTFSC  F81.3  ; espera que la
067E:  BRA    0676     ; entrada se convierta en cero

0680:  BRA    0590


Por lo tanto hasta que no se cumplan los 30 minutos no revisa la entrada
entonce es SI se cumplen 30 minutos "AND" la entrada es un bajo sale del
WHILE???, es correcto, entonces porque se utiliza el operador logico OR
en el codigo, ademas el comportamiento de

while ((minuter!=30) && (!input(_alarm)));

y

while ((minuter==30) || (input(_alarm));

no es el mismo, el compilador NO genera el mismo codigo.


Entonces como escribo correctamente el codigo,  en la practica si yo escribo


while ((minuter!=30) && (input(!_alarm))); ( utilizo el operador Y )


y corro el programa en el micro, si se cumplen 30 minutos O sube el pin _alarm
salta a la rutina siguiente.



si en su lugar escribo


 while ((minuter!=30) || (input(!_alarm)));  ( utilizo el operador O )


 y corro el programa en el micro, hasta que no se cumplen los treinta minutos,
el pin puede hacer lo que le de la gana que no se sale de ahi, y el ASM lo dice clarito, la verdad si que estoy epeso o soy muy bruto.

gracias de nuevo..

ARIEL





saludos
PikMan

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
RE: Una duda me ayudan? miren que pasa!
« Respuesta #10 en: 16 de Febrero de 2006, 00:21:00 »
Escrito originalmente por pikman

Sin embargo el codigo generado para


while ((minuter!=30) && (!input(_alarm)));

es una OR

0676:  MOVF   58,W  
0678:  SUBLW  1E        ; resta para comparar si es igual
067A:  BZ    0680         ; sale del bucle
                                    ; "OR"
067C:  BTFSC  00.0      ; Si la entrada es 0 a cero salta y sale del bucle
067E:  BRA    0676       ; si no sigue en el while  

0680:  BRA    0590

Por lo tanto lo que yo entiendo es que si se cumplen 30 minutos "O" que la
entrada es cero sale del bucle y salta a la linea 590, no hay dudas que se cumple
una condicion "O" y el operador empleado en el codigo es AND.


Correcto, Pikman, el compilador ha simplificado tu condición transformándola de un AND sobre dos negaciones a un OR sobre dos afirmaciones. Técnicamente es lo mismo

Escrito originalmente por pikman

Esto seria lo mismo?, odeberia generar el mismo codigo?

while ((minuter==30) || (input(_alarm));

esto es lo que genera el compilador



0676:  MOVF   58,W
0678:  SUBLW  1E      ; resta para comparar el valor
067A:  BZ    0676       ; y se queda esperando que sea 30!!??

                                      "AND" y
067C:  BTFSC  F81.3  ; espera que la
067E:  BRA    0676     ; entrada se convierta en cero

0680:  BRA    0590


Por lo tanto hasta que no se cumplan los 30 minutos no revisa la entrada
entonce es SI se cumplen 30 minutos "AND" la entrada es un bajo sale del
WHILE???, es correcto, entonces porque se utiliza el operador logico OR
en el codigo, ademas el comportamiento de

while ((minuter!=30) && (!input(_alarm)));

y

while ((minuter==30) || (input(_alarm));

no es el mismo, el compilador NO genera el mismo codigo.


Exactamente, esa condición es la misma. De hecho, has traducido mal el salto BZ en tus comentarios del ASM, porque no se queda esperando que sea 30, sino que se queda sólo cuando es 30.


Escrito originalmente por pikman

si en su lugar escribo


 while ((minuter!=30) || (input(!_alarm)));  ( utilizo el operador O )


 y corro el programa en el micro, hasta que no se cumplen los treinta minutos,
el pin puede hacer lo que le de la gana que no se sale de ahi, y el ASM lo dice clarito, la verdad si que estoy epeso o soy muy bruto.

gracias de nuevo..

ARIEL


Esa condición no es la misma, y no tiene nada que ver con lo que tú buscas.





Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
RE: Una duda me ayudan? miren que pasa!
« Respuesta #11 en: 16 de Febrero de 2006, 13:08:00 »
Joe, macho, llevo todo el día dándole vueltas al problema que planteas Pikman, y finalmente tengo que decir que estaba equivocado.
Cuando dije que estas sentencias son equivalentes:
(NOT A) AND (NOT B)
y
(A OR B)

me confundí
La segunda debía ser:
NOT (A OR B)

Así que tu condición while podría ser:
while !((minuter==30) || input(_alarm))

Disculpa tanto lío, Pikman, pero entre unos y otros menuda ayuda te hemos dado... loco

Desconectado pikman

  • Moderador Local
  • PIC24F
  • *****
  • Mensajes: 679
RE: Una duda me ayudan? miren que pasa!
« Respuesta #12 en: 19 de Febrero de 2006, 12:09:00 »
OK, no hay problemas, Sonrisa GiganteSonrisa GiganteSonrisa Gigante , gracias de todos modos.

saludos

ARIEL
saludos
PikMan

Desconectado Chaly29

  • Moderador Global
  • DsPIC33
  • *****
  • Mensajes: 4315
RE: Una duda me ayudan? miren que pasa!
« Respuesta #13 en: 19 de Febrero de 2006, 16:04:00 »
Despues nocturno66 dice por hay que no sabe nada de .asm, pa" mí es que no nos quiere enseñar Muchas risas Muchas risas Muchas risas

Un saludo.
La teoría es cuando se sabe todo y nada funciona. La práctica es cuando todo funciona y nadie sabe por qué.

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
RE: Una duda me ayudan? miren que pasa!
« Respuesta #14 en: 19 de Febrero de 2006, 16:15:00 »
Que no, que no, que el asm me da repeluco...