TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: Juan_PIC en 11 de Mayo de 2007, 23:38:15
-
XORWF Exclusive OR W with f
Syntax: [ label ] XORWF f,d
Operands: 0 ≤ f ≤ 127
d ∈ [0,1]
Operation: (W) .XOR. (f) → (destination)
Status Affected: Z
Description: Exclusive OR the contents of the
W register with register 'f'. If 'd' is
0, the result is stored in the W
register. If 'd' is 1, the result is
stored back in register 'f'.
Hola a todos. Mi pregunta es que es lo que indica los operands ya que en algunas instrucciones es 0 ≤ f ≤ 127 y en otras de 0 ≤ f ≤ 255. Arriba dejo un ejemplo. Sospecho que por esto no esta andando mi programa.
BAJAR
CALL DEL10MS ;ANTI-REBOTE
BCF STATUS,Z ;BORRO EL FLAG Z PARA QUE NO AFECTE LA OPERACION LOGICA
MOVLW CERO ;SI EL (cero equivale a el codigo para un display de 7 segementos)
XORWF DISPLAY,W ;DISPLAY ESTA
BTFSC STATUS,Z ;EN 0 NO
GOTO BAJAR_2 ;DECREMENTA (Z=1)
BSF PORTD,7 ;TEST
DECF NUM,F ;DECREMENTA NUM DE MANERA (Z=0)
CALL TABLA ;QUE VALGA LO QUE EL DISPLAY
MOVWF DISPLAY ;TIENE QUE MOSTRAR
BAJAR_2 CALL TOGLELED ;ALTERNA EL ESTADO DEL LED VERDE
BTFSS BOTON2 ;ESPERA A QUE SE DEJE DE PULSAR BOTON2
GOTO $-1 ;PARA QUE NO SIGA DECRMENTANDO
CALL DEL10MS ;ANTI-REBOTE
GOTO PPAL ;RUTINA FINALIZADA
El problema es que aparentemente el bit Z no se pone en 1 y por lo tanto no ejecuta la linea GOTO BAJAR_2 sospecho que es por la xorwf porque otra cosa no se me ocurre. Espero que me puedan ayudar. Gracias! :-/
-
¿Tu variable DISPLAY que tamaño tiene?
Suerte!!! ;)
-
Estoy trabajando con el portb.
Tengo de los bits 7 al 1 como salida para display, y el bit 0 como uno de los pulsadores.
Cuando escribo a DISPLAY escribo el portb entero, total no pasa nada con la entrada.
Espero que sirva.
PD: miren esto. en la hoja de datos del pic da como ejemplo (primer ejemplo) para la XORWF un numero de 8 bits.
Example XORWF REG 1
Before Instruction
REG = 0xAF <-----------Este es el numero, no concuerda con "Operands: 0 £ f £ 127" si es eso a lo que se refiere.
W = 0xB5
After Instruction
REG = 0x1A
W = 0xB5
Gracias a todos.!
-
podrias postear todo tu codigo? faltan datos para entender porque te falla :-/ exitos!!!!!!!!!!!!!!!!!!
-
;************************************************************************************************************************************************************
;------------------------------------------------EJERCICIO 2 (MANEJO DE UN DISPLAY DE 7 SEGMENTOS)-----------------------------------------------------------
;************************************************************************************************************************************************************
#include <P16F877A.inc>
cblock 0x20
CONT1
CONT2
NUM
DIGITO
endc
#define DISPLAY PORTB
#define BOTON1 PORTB,0
#define BOTON2 PORTC,0
#define LED_VER PORTD,6
#define BANCO0 BCF STATUS,RP0
#define BANCO1 BSF STATUS,RP0
#define CERO b'11111100'
#define UNO b'01100000'
#define DOS b'11011010'
#define TRES b'11110010'
#define CUATRO b'01100110'
#define CINCO b'10110110'
#define SEIS b'10111110'
#define SIETE b'11100000'
#define OCHO b'11111110'
#define NUEVE b'11110110'
ORG 0x00
GOTO INICIO
ORG 0x05
;---------------------------------------------------------------------INICIO---------------------------------------------------------------------------------
INICIO
BANCO1
MOVLW b'00000001' ;7 SEGMENTOS SALIDAS
MOVWF TRISB ;BOTON1 ENTRADA
BSF TRISC,0 ;BOTON2 ENTRADA
BCF TRISD,6 ;LED VERDE SALIDA
BCF TRISD,7 ;TEST
BANCO0
CLRF NUM ;PONE NUM EN 0
BCF LED_VER ;APAGO LED VERDE
BCF PORTD,7 ;TEST
MOVLW CERO ;PONE UN 0 EN
MOVWF DISPLAY ;EL DISPLAY
;----------------------------------------------------------------PROGRAMA PRINCIPAL--------------------------------------------------------------------------
PPAL
BTFSS BOTON1
GOTO SUBIR
BTFSS BOTON2
GOTO BAJAR
GOTO PPAL
;-------------------------------------------------------------------SUBRRUTINAS------------------------------------------------------------------------------
SUBIR
CALL DEL10MS ;ANTI-REBOTE
BCF STATUS,Z ;BORRO EL FLAG Z PARA QUE NO AFECTE LA OPERACION LOGICA
MOVLW NUEVE ;SI EL
XORWF DISPLAY,W ;DISPLAY ESTA
BTFSC STATUS,Z ;EN 9 NO
GOTO SUBIR_2 ;INCREMENTA
INCF NUM,F ;INCREMENTA NUM DE MANERA
CALL TABLA ;QUE VALGA LO QUE EL DISPLAY
MOVWF DISPLAY ;TIENE QUE MOSTRAR
SUBIR_2 CALL TOGLELED ;ALTERNA EL ESTADO DEL LED VERDE
BTFSS BOTON1 ;ESPERA A QUE SE DEJE DE PULSAR BOTON1
GOTO $-1 ;PARA QUE NO SIGA INCRMENTANDO
CALL DEL10MS ;ANTI-REBOTE
GOTO PPAL ;RUTINA FINALIZADA
BAJAR
CALL DEL10MS ;ANTI-REBOTE
BCF STATUS,Z ;BORRO EL FLAG Z PARA QUE NO AFECTE LA OPERACION LOGICA
MOVLW CERO ;SI EL
XORWF DISPLAY,W ;DISPLAY ESTA
BTFSC STATUS,Z ;EN 0 NO
GOTO BAJAR_2 ;DECREMENTA (Z=1)
BSF PORTD,7 ;TEST ((((((led rojo))))
DECF NUM,F ;DECREMENTA NUM DE MANERA (Z=0)
CALL TABLA ;QUE VALGA LO QUE EL DISPLAY
MOVWF DISPLAY ;TIENE QUE MOSTRAR
BAJAR_2 CALL TOGLELED ;ALTERNA EL ESTADO DEL LED VERDE
BTFSS BOTON2 ;ESPERA A QUE SE DEJE DE PULSAR BOTON2
GOTO $-1 ;PARA QUE NO SIGA DECRMENTANDO
CALL DEL10MS ;ANTI-REBOTE
GOTO PPAL ;RUTINA FINALIZADA
TOGLELED
MOVLW b'01000000' ;CAMBIA EL ESTADO DE LOS BITS ENMASCARADOS
XORWF PORTD,F ;CON 1 (LED VERDE) (RD6)
RETURN
TABLA
MOVF NUM,W ;CARGA EN W EL VALOR DE NUM
ADDWF PCL,F ;SUMA W A PCL Y SELECCIONA UN VALOR DE DISPLAY
RETLW CERO
RETLW UNO
RETLW DOS
RETLW TRES
RETLW CUATRO
RETLW CINCO
RETLW SEIS
RETLW SIETE
RETLW OCHO
RETLW NUEVE
DEL10MS ;DEMORA UTILIZADA PARA ELIMINAR REBOTE MECANICO DEL PULSADOR
MOVLW d'20'
MOVWF CONT2
DEM1 MOVLW d'166'
MOVWF CONT1
DECFSZ CONT1,F
GOTO $-1
DECFSZ CONT2,F
GOTO DEM1
RETURN
;--------------------------------------------------------------------------FIN-------------------------------------------------------------------------------
END
Bueno este es el programa completo. Lo que tendria que hacer es: cuando se pulse el boton1 subir un digito en el display de 7 segmentos e intercambiar el estado del led verde. cuando se pulse el boton2 bajar un digito en el display de 7 segmentos y tambien intercambiar el estado del led verde. si se trata de pasar de nueve, el display tiene que seguir en nueve, pero intervambiar el estado del led verde tambien, y cuando se trate de bajar del cero, dejar el display en cero e intercambiar el estado del led verde. El programa empieza con el display en cero y el led verde apagado. Anda todo salvo cuando trato de bajar un digito estando en cero, en donde se me "cuelga" el programa.
El led rojo que lo comente como "test" lo puse para darme cuenta de que la linea goto bajar_2 no se esta ejecutando (quizas no se este seteando el flag Z)
Saludos a todos.!!
-
wouuu que programon! :mrgreen: jeje
-
XORWF Exclusive OR W with f
Syntax: [ label ] XORWF f,d
Operands: 0 ≤ f ≤ 127
d ∈ [0,1]
Operation: (W) .XOR. (f) → (destination)
Status Affected: Z
Description: Exclusive OR the contents of the
W register with register 'f'. If 'd' is
0, the result is stored in the W
register. If 'd' is 1, the result is
stored back in register 'f'.
Hola a todos. Mi pregunta es que es lo que indica los operands ya que en algunas instrucciones es 0 ≤ f ≤ 127 y en otras de 0 ≤ f ≤ 255. Arriba dejo un ejemplo. Sospecho que por esto no esta andando mi programa.
PD: miren esto. en la hoja de datos del pic da como ejemplo (primer ejemplo) para la XORWF un numero de 8 bits.
Example XORWF REG 1
Before Instruction
REG = 0xAF <-----------Este es el numero, no concuerda con "Operands: 0 £ f £ 127" si es eso a lo que se refiere.
W = 0xB5
After Instruction
REG = 0x1A
W = 0xB5
Bueno.
Para comprender qué quiere decir ese "0 <= f <= 127" es necesario comprender a la perfección la arquitectura de esta familia de uC PIC.
El 16F877A posee su memoria RAM particionada en 4 bancos distintos.
Si mirás en el datasheet de este PIC, vas a poder ver una tabla donde muestra de manera resumida los 4 bancos de acceso a la RAM.
Entonces, podés observar que cada banco posee una cantidad de 0x80(128) registros de 8 bits cada uno.
¿Cómo se hace entonces, para acceder a cualquier registro en cualquier banco?
Bueno, debido a las limitaciones de los 14 bits de OPTCODE de esta familia y limitaciones en su arquitectura, para acceder a un registro, primero es necesario tener el banco correcto seleccionado.
Aquí intervienen los bits RP0 y RP1 del registro STATUS.
Entonces, en realidad, vos tenés por un lado 7 bits que pueden ser directamente declarados en la instrucción a utilizar, y dos bits que deben estar correctamente seteados antes de ejecutar dicha instrucción.
Resumiendo. Para acceder a cualquier registro de la RAM son necesarios 9 bits:
XXXXXXXXX
Donde:
X X XXXXXXX
RP1 RP0 F
Entonces, cuando utilizas una instrucción orientada a registro, como por ejemplo la XORWF el registro declarado son sólo los 7 bits menos significativos de esos 9 en total. Los otros dos se seleccionan mediante RP1 y RP0.
Vamos a los ejemplos:
Ejemplo 1:
BCF STATUS,RP1 ;indicar banco 0 (ó 1)
BCF STATUS,RP0 ;elegir banco 0 entre ambos
XORWF 0x60, 1 ;El XORWF afecta al registro 0x060 de la RAM.
Ejemplo 2:
BCF STATUS,RP1 ;indicar banco 0 (ó 1)
BSF STATUS,RP0 ;elegir banco 1 entre ambos
XORWF 0x60, 1 ;El XORWF afecta al registro 0x060 + 0x080 = 0x0E0 de la RAM.
Ejemplo 3:
BSF STATUS,RP1 ;indicar banco 2 (ó 3)
BCF STATUS,RP0 ;elegir banco 2 entre ambos
XORWF 0x60, 1 ;El XORWF afecta al registro 0x060+ 0x100 = 0x160 de la RAM.
Ejemplo 4:
BSF STATUS,RP1 ;indicar banco 2 (ó 3)
BSF STATUS,RP0 ;elegir banco 3 entre ambos
XORWF 0x60, 1 ;El XORWF afecta al registro 0x060+ 0x100 + 0x080 = 0x1E0 de la RAM.
Posible, pero no correcto:
BCF STATUS,RP1 ;indicar banco 0 (ó 1)
BCF STATUS,RP0 ;elegir banco 0 entre ambos
XORWF 0xF0, 1
Como 0xF0 > 127, entonces el MPASM elimina los bits que no "entran", quedandose solo con los 7 bits de menor peso. Entonces hacer:
XORWF 0xF0, 1
será tranformado por el MPLAB a:
XORWF 0x70, 1 ;(el MPLAB ignora el bit7 de 0xF0)
Otra cosa:
No confundamos:
Example XORWF REG 1
Before Instruction
REG = 0xAF <-----------Este es el numero, no concuerda con "Operands: 0 £ f £ 127" si es eso a lo que se refiere.
W = 0xB5
After Instruction
REG = 0x1A
W = 0xB5
----------------------------------
Este tema siempre produce confusiones en los que se inician a la programación.
NO HAY QUE CONFUNDIR LA POSICION DE MEMORIA DE UN REGISTRO CON SU CONTENIDO(VALOR).
Hacé de cuenta que tenés 4 galpones gigantes numerados del 0 al 3(los 4 bancos de memoria).
Dentro de cada galpón hay 128 tanques con agua numerados desde el 0 al 127(los 128 registros de cada banco)
A su vez, cada tanque tiene una capacidad máxima de 255 litros(el valor que puede adoptar un registro de 8 bits, entre 0 y 255).
Si yo te pido que vayas y agregues 25 litros de agua al tanque 89 del galpón 2. ¿Cómo harías?
Y...yo haría:
BSF STATUS,RP1 ;selecciono banco 2(ó 3)(galpón 2 ó 3)
BCF STATUS,RP0 ;elijo banco 2 entre ambos(elijo galpón 2)
movlw .25 ;cargo 25 litros en el balde
addwf .89, 1 ;y se los agrego a lo que ya tenía el tanque 89.
Entonces, volvamos a lo que escribiste:
REG = 0xAF <-----------Este es el numero, no concuerda con "Operands: 0 £ f £ 127" si es eso a lo que se refiere.
Ese signo = se está refiriendo al valor del registro. No a su posición de memoria(no confundas la ubicación del tanque con la cantidad de litros de agua que contiene).
Te voy a mostrar el mísmo ejemplo del datasheet pero con todos los recuados contemplados:
Example XORWF REG 1
;Before Instruction
REG EQU 0x7A ;Respeto que 0 <= f <= 0x7F ya que 0 <= 0x7A <= 0x7F
;Ese EQU hizo que cada vez que escriba REG en el programa, el MPASM lo reemplace por 0x7A( es decir que estoy "apuntando" a la posición de memoria 0x?7A del PIC. El signo de pregunta(?) es porque, como explique antes, los bits RP0 y RP1 pueden modificar la posición final de memoria afectada)
movlw 0xAF
movwf REG ;(REG = 0xAF)
movlw 0xB5 ;(W = 0xB5)
XORWF REG 1
Hagamos la XOR en hoja y papel(electrónico :D).
Entonces:
REG = 0xAF = 10101111
W = 0xB5 = 10110101
Hagamos entonces bit a bit la XOR:
10101111
XOR
10110101
--------------------------------
00011010
Resultado: 00011010 = 0x1A. Como "d(destino)" = 1, entonces el resultado se almacena en el registro REG. W permanece inalterado.
Resumiendo:
After Instruction
REG = 0x1A
W = 0xB5
¿Se comprendió?
Saludos.
-
BAJAR
CALL DEL10MS ;ANTI-REBOTE
BCF STATUS,Z ;BORRO EL FLAG Z PARA QUE NO AFECTE LA OPERACION LOGICA(!!!!!!!??NO ES NECESARIO. ELIMINALA).
MOVLW CERO ;SI EL
XORWF DISPLAY,W ;DISPLAY ESTA
ANDLW b'11111110'
BTFSC STATUS,Z ;EN 0 NO
GOTO BAJAR_2 ;DECREMENTA (Z=1)
BSF PORTD,7 ;TEST ((((((led rojo))))
DECF NUM,F ;DECREMENTA NUM DE MANERA (Z=0)
CALL TABLA ;QUE VALGA LO QUE EL DISPLAY
MOVWF DISPLAY ;TIENE QUE MOSTRAR
BAJAR_2 CALL TOGLELED ;ALTERNA EL ESTADO DEL LED VERDE
BTFSS BOTON2 ;ESPERA A QUE SE DEJE DE PULSAR BOTON2
GOTO $-1 ;PARA QUE NO SIGA DECRMENTANDO
CALL DEL10MS ;ANTI-REBOTE
GOTO PPAL ;RUTINA FINALIZADA
A ver si funciona ahora.
-
Anda muy bien! Muchas gracias BrunoF por tu explicacion!!!! te pasaste!
Ahora me queda una duda. Porque la XORWF no afectaba el bit Z en la rutina bajar y si en la rutina subir? :?
-
Miremos nuevamente tu circuito electronico:
#define BOTON1 PORTB,0
#define BOTON2 PORTC,0
Para subir funcionaba porque el pulsador que comanda la subida no está ubicado en el PORTB(la XOR es sobre el PORTB).
Ahora, tenés otro problema. La limitacion de subida(maximo 9) te está funcionando aparentemente bien de pura casualidad. PERO MUYYY PURA. Tuviste suerte.
Si mis cálculos no fallan, si presionas seguido 10 veces el pulsador de subida después de haber llegado al 9, se te debería reiniciar el PIC o bien colgarse.
Si mis profecías se cumplen, avisame que te digo dónde está el error.
Saludos.
-
Aprete el boton1 como unas 50 veces y el programa siguio funcionando bien. Estoy confundido :-)
-
OK. Perdoná. Dije las cosas al revés. Pensé que los pulsadores estaban asociados al reves con los algoritmos.
Recapitulo:
Miremos nuevamente tu circuito electronico:
#define BOTON1 PORTB,0
#define BOTON2 PORTC,0
Para subir funcionaba porque el pulsador que comanda la subida está ubicado en el PORTB(la XOR es sobre el PORTB).
Explico:
A la hora de hacerse la XOR, como el BOTON1 está en el PORTB, el bit0 del PORTB vale CERO(porque estas presionando el pulsador). Por lo que la XOR se cumple y funciona correctamente.
Fallaría si lográs presionar el BOTON1 y soltarlo antes de 10ms aprox.Para asegurarte el correcto funcionamiento en cualquier situación, deberias agregar la ANDLW b'11111110' al algoritmo de subida tambien.
En la bajada fallaba porque el BOTON2 está declarado en el PORTC, que nada tiene que ver con la XORWF PORTB,F.
Y justamente fallaba por eso. Porque no tiene nada que ver! Que loco, eh! Jaja
Explico:
Como el pulsador de bajada se encuentra declarado en el PORTC, cuando haces la XORWF PORTB, 1
el bit0 del PORTB se encuentra en alto(porque no estas presionando el boton1 de subir) entonces la XOR con CUALQUIER VALOR DE LA TABLA DE NUMEROS(fijate que en todos definiste el bit0 como 0) da como resultado un numero distinto a cero.
Cuando tenias el problema la XOR te daba siempre 1, por lo que no se afectaba el flag Z.
¿Se entendió?
Saludos.
Saludos.
-
Se entendio perfectamente!!! Mil gracias BrunoF!!!!!! :mrgreen: :mrgreen: :mrgreen:
-
De nada. Nos leemos por aca.
Saludos.