TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: romarco en 16 de Diciembre de 2013, 19:09:02
-
Muchos saludos!
Tengo una pequeña duda, y me gustaría alguno de ustedes me ayudaran en el asunto...
Utilizando los primeros cuatro bits del puerto B, para imprimir el número UNO, con tablas, digo:
RETLW B'00010000'
Ahora bien, se que si voy a imprimir ese mismo número por los cuatro siguientes bits del puerto B digo:
RETLW B'00000001'
Pero, ¿qué sucedería si en los cuatro primeros (o en los últimos cuatro, da igual) bits del puerto B tengo conectado otras cosas como reles, leds o pulsadores a los que quiero dejar intactos? O sea, que quiero hacer algo como esto:
RETLW B'_ _ _ _0001' ;Quiero no modificar los primeros cuatros bits del port b
o bien sea:
RETLW B'0001_ _ _ _'; Quiero no modificar los ultimos cuatros bits del port b
No se si me doy a entender. Lo que quiero es trabajar solo con cuatro bits del puerto B, y los demás dejarlos intacto, no tocarlos porque lo estoy utilizando como entrada de pulsadores.
Gracias, espero no sea una molestia..
-
Hola,
acá tenés una posible solución. en tu caso la máscara sería 0x0F si querés afectar a los 4 bits de menor peso, y 0xF0 si querés afectar a los 4 bits de mayor peso.
http://www.todopic.com.ar/foros/index.php?topic=41603.msg346115#msg346115
Igualmente en pines configurados como entrada, la escritura no tiene efecto sobre ellos.
Para voltear el valor obtenido vas a tener que usar la instrucción swapf.
Saludos.
-
Podrias hacer un AND con lo que tienes en el puerto actualmente, es decir
primero lees el valor actual de todo tu puerto y luego aplicas un AND con el valor que tu quieras modificar y posteriormente vuelves a asigar ese valor al puerto
por ejemplo, si quieres modificar solo los últimos bits del puerto seria
PB = PB & B'11110010'
en este caso los 4 bits mas significativos de tu puerto b quedan como estaban, pero los bits menos significativos toman el valor de 0010 o el valor que quieras, solo expresa eso ensamblador
espero te sirva
-
Hola rivale,
lamento decir que la AND no va a funcionar bien si lo haces así. Los bits menos significativos van a tomar el valor 0010 sólo si el estado previo de PB era B'XXXXXX1X', donde 'X' significaría no relevante. Si PB valiese, por ejemplo, B'XXXXXX0X', luego de la operación que mencionaste, el valor del puerto sería B'XXXX0000', que es un resultado incorrecto.
Saludos.
-
:oops: Gracias por la correccion bruno.
Para que funcione tendrias que realizar un OR antes y posteriormente aplicar un and a tu registro para obtener el valor deseado.
en el caso de los bits menos significativos seria asi
PB = (PB | B'00001111') & B'11110010'
-
:oops: Gracias por la correccion bruno.
Para que funcione tendrias que realizar un OR antes y posteriormente aplicar un and a tu registro para obtener el valor deseado.
en el caso de los bits menos significativos seria asi
PB = (PB | B'00001111') & B'11110010'
Sí, las dos inmediatas que salen usando AND y OR son esa que mencionaste:
PB = (PB | B'00001111') & B'11110010'
movf PORTB,W
iorlw 0x0F
andwf newValue,W
movwf PORTB
y la otra
PB = (PB & B'11110000') | B'00000010'
movf PORTB,W
andlw 0xF0
iorwf newValue,W
movwf PORTB
Saludos.
-
Hola, muchas gracias por responder... Estuve observando y creo entender como va, pero cuando leí la expresión 'bits menos significativos' se me ocurrió hacer simplemente esto: RETLW B'0001', porque los bits que no quiero modificar son precisamente los menos significativos..
Ahora, no se si abrir otro tema o aprovecho y pregunto por aquí...
El RA4 (el raro como dicen) lo configuré como entrada. Lo conecté a +5v mediante una resistencia de 10k. Luego puse un pulsador abierto que va del RA4 a masa.
Para leer el estado de RA4 uso:
f_up BTFSC PORTA,4
GOTO f_exit1
.......Resto del código.....
Sin embargo no pasa nada, ¿Tengo que configurar algo antes de...?
Muchas gracias, y disculpen...
-
Si, claro que poner RETLW B'0001' es lo mísmo que RETLW B'00000001'. No creas que por declarar menos bits en esa sentencia vas a ahorrarte memoria o que no van a llenarse los 4 bits más significativos. El MPASM asume que serán ceros, pero siguen estando ahí.
La idea de aprovechar bien la memoria es que ya que sólo requieres 4 bits por valor, podrías utilizar cada RETLW para generar dos valores, no uno. De esa manera ahorras la mitad de instrucciones de ese tipo.
Por otro lado, con respecto al RA4, qué microcontrolador estás usando? Tal vez debas configurar la entrada como digital, dependiendo del uC en cuestión. Tampoco sé cuál es la lógica de tu código, pero así como lo mostras, cuando el pulsador no está pulsado, se ejecuta goto f_exit1.
Saludos.
-
Sí, la idea es que cuando no está pulsado el botón, se vaya a f_exit para retornar. El pic con el que estoy trabajando es el 16F84A.
Gracias
-
Si mal no recuerdo en el 16F84A con sólo configurarlo como entrada es suficiente. Podrías poner el código?
-
Aquí va... Te recuerdo que hay una resistencia entre la pata RA4 y +V. Entonces el pulsador está entre la RA4 y masa, de modo que cuando acciono el pulsador me deja pasar la corriente negativa para provocar el corto.
list p=16F84A
#INCLUDE <P16F84A.INC>
#DEFINE BANCO0 BCF STATUS,5
#DEFINE BANCO1 BSF STATUS,5
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_OFF & _XT_OSC
ORG 00h
GOTO f_init
ORG 05h
f_init BANCO1 ;Paso al banco 1 para realizar las configuraciones de los puertos.
MOVLW B'10000' ;0 indica que son salidas. 1 indica entradas. El orden es RA4, RA3, RA2, RA1, RA0
;el bit menos significativo del PORTA es el RA0
MOVWF TRISA
MOVLW B'01110000' ;0 indica que son salidas. 1 indica entradas. El orden es RB7, RB6, ..., RB0
MOVWF TRISB
BANCO0 ;Paso al banco 0 para comenzar a trabajar.
CLRF PORTA ;Limpio todo el puerto A.
CLRF PORTB ;Limpio todo el puerto B.
MOVLW .0
MOVWF 22h
MOVLW .0
MOVWF 23h
f_run CALL f_disc ; Verifica el estado de RA4
CALL f_up ;No coloqué estas rutinas para hacer el código más corto. Esto funciona perfectamente.
CALL f_down ;No coloqué estas rutinas para hacer el código más corto. Esto funciona perfectamente.
GOTO f_run ;Repito la rutina de f_run
f_disc BTFSC PORTA,4 ;Verifico si se ha pulsado RA4.
GOTO f_exit0
BSF PORTB,7 ;Enciendo LED
f_exit0 RETURN ;Vuelvo a f_run
-
No veo nada mal en el código, pese a que deberías haber publicado todo el código, o sino comentar las llamadas a f_up y f_down y probar si aún así no funciona el pulsador en RA4. Aunque parezca poco creíble, código de f_up o f_down pueden provocar un comportamiento general erróneo.
Estás usando el uC con un cristal de 4Mhz?
Saludos
-
Soy nuevo y es la primera vez que intento responder, no se si es así como se hace (aquí)
hecho de menos un retardo al leer el pulsador, para evitar los rebotes. Por lo demás no veo nada más.