TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Thulsa Doom en 22 de Febrero de 2011, 15:22:15

Título: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: Thulsa Doom en 22 de Febrero de 2011, 15:22:15
Hola de nuevo.
Abro este hilo nuevo siguiendo con el tema anterior que se puede ver en este hilo:
http://www.todopic.com.ar/foros/index.php?topic=33895.0

Creo que es mejor abrir otro nuevo porque trato otro tema diferente, aunque sea una pregunta basada en el tema anterior, si la comunidad no considera que se deba abrir un tema nuevo, borren este hilo y ya hago la pregunta en el anterior hilo.

La duda que tengo ahora es, una vez tengo el dato de 16 bits metido en una variable, como puedo desechar los bits que no me interesan y como utilizar los que me interesa, no pido que me lo resuelvan pero si pido que me orienten para empezar a investigar sobre el tema y si no doy con la solución ya preguntare las dudas

Resulta que esa palabra no me vale toda, el dispositivo envía el dato desde MSB hasta LSB.

Por ejemplo, el bit 15 es un bit tonto no me vale porque no tiene información igual que el bit 0 , el bit 1 y 2 tiene un tipo distinto de información cada uno, juntos no me valen pero por separado si, y los bits del 14 al 3 corresponden a un dato float.

Gracias de ante mano
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: Nocturno en 22 de Febrero de 2011, 15:55:57
Lo puedes hacer con máscaras de bit, usando los operadores AND (&) y OR (|) que trabajan con los datos a nivel lógico.

La wikipedia no dice mucho, pero seguro que si buscas por ahí encontrarás más info: http://es.wikipedia.org/wiki/M%C3%A1scara_(inform%C3%A1tica)
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: Thulsa Doom en 22 de Febrero de 2011, 16:13:53
¿pero eso funcionará?, es que los datos no son fijos si no que cambian, date cuenta que un and es.

   AND
 
 00 | 0   
 01 | 0
 10 | 0
 11 | 1

con lo cual si son 1 si me los pillara pero si son 0 los desechara

  OR

 00 | 0
 01 | 1
 10 | 1
 11 | 1

estas técnicas las he utilizado para hacer que en un mismo puerto tenga patillas de entrada y patillas de salida.
pero si dices que funciona....estudiaré el tema.
gracias
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: Nocturno en 22 de Febrero de 2011, 16:37:59
Ponme un ejemplo de lo que necesitas, verás cómo lo entiendes rápidamente.
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: Suky en 22 de Febrero de 2011, 17:06:54
Puedes aplicar la mascara utilizando el operador & para solo dejar los bits que te interesan y luego rotarlos para guardarlos en una variable.


Saludos!
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: Thulsa Doom en 22 de Febrero de 2011, 18:53:42
Una de las cosas que necesito es, separar la palabra desde el bit 15 al 3, ahí hay un valor en float, hay más bits que sirven para hacer otras cosas pero si entiendo uno los demás son iguales.

-¿Lo de rotarlos lo hago con un shift rigth?.
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: Nocturno en 22 de Febrero de 2011, 19:02:29
Lo podrías hacer así:

resultado = (palabra & 0b1111111111111000) >> 3;

aunque, puesto que la rotación rellena con ceros, obtendrías el mismo resultado haciendo así:

resultado = palabra >> 3;
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: Thulsa Doom en 22 de Febrero de 2011, 19:07:07
Vaya, no tengo palabras para agradecer toda la ayuda.

ya que estoy me aprobecho  :)

¿el >>3 que hace?, creo que dices rodar a la derecha 3 posiciones, ¿cuales son?, ¿sería para eliminar los 3 ceros del final y dejarlo así?

0b001111111111111
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: Nocturno en 22 de Febrero de 2011, 19:10:51
Exacto, "empuja" los bits hacia la derecha. Los bits menos significativos que salen, se pierden. Y por el lado izquierdo entran ceros.
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: Thulsa Doom en 22 de Febrero de 2011, 19:46:10
Y por último si no es abusar,
si quisiera cambiar el orden de los bits, como lo haría.

me refiero a esto:
imagina que el dato de 16 bis me entra desde el dispositivo así: (lo pongo con números para que se entienda, si lo pongo en binario es más lioso)

15,14,13,12,10,9,8,7,6,5,4,3,2,1,0

que utilizaría para invertirlos y dejar así

0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

¿podría ser con la función shift right?
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: MLO__ en 22 de Febrero de 2011, 20:56:49
Hola.

Se podria con SWAPF a cada byte?
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: Suky en 22 de Febrero de 2011, 23:11:52
 :?

algo así?


Código: C
  1. for(k=0;k<16;k++){
  2.     shift_left(VarOut,2,bit_test(VarIn,k));
  3. }

Saludos!
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: pocher en 23 de Febrero de 2011, 03:43:48
Con swap no se podria, no quedarian en el orden deseado.

a=0111 1101

Deberia de quedar como: b=1011 1110 y queda con swap como: b=1101 0111

Conforme lo tiene Suky si que esta bien.
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: PalitroqueZ en 23 de Febrero de 2011, 13:09:33
yo una vez utilicé el desplazamiento y los operadores lógicos para tomar bits de diferentes puertos.

Código: [Seleccionar]
//**************************************************************
// Aquí se agrupa los bits concerniente a las columnas 1-4 junto
// con RB[7-4] en un solo registro para manejarlo a posteriori
// iPuerto_compuesto = [RB7,RB6,RB5,RB4,columna3,columna2,columna1,columna0]
//**************************************************************
void  Configurar_iPuerto_compuesto(void){
  iPuerto_compuesto=0;
  iPuerto_compuesto = input_b() & iLos_Cuatro_MSB_PORTB;
  iPuerto_compuesto |= (input_state(iColumna3) << 3);
  iPuerto_compuesto |= (input_state(iColumna2) << 2);
  iPuerto_compuesto |= (input_state(iColumna1) << 1);
  iPuerto_compuesto |= input_state(iColumna0);
}

necesitaba tomar el estado de RB[7-4] y un bit del un puerto cualquiera, después los juntaba todos en un Integer de 1Byte al que llamé iPuerto_compuesto

Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: Thulsa Doom en 23 de Febrero de 2011, 14:20:23
Pues la verdad es que no sé cómo utilizar el shift_left, el ejemplo que ha puesto Suky no me funciona, el proteus me da muchos mensajes como estos:

(http://img576.imageshack.us/img576/4771/dibujolbx.png) (http://img576.imageshack.us/i/dibujolbx.png/)

Y en el display no aparece datos si no 0000 o números que no coinciden con los que debiera de haber

La verdad es que no hay mucha documentación al respecto y los ejemplos que he encontrado están poco claros

Alguien me lo puede explicar, así como para tontos.
gracias
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: AngelGris en 23 de Febrero de 2011, 14:48:39
  Que pena pero no puedo ver la captura de imagen.

  El shift es sencillo de entender, tenés que verlo del punto de vista de un desplazamiento. Veamos un ejemplo con 4 bits para que sea más entendible

  Número original  (binario) 1110, (decimal) 14, (hexadecimal) 0x0E

  Al aplicar un shift right (desplazamiento a la derecha) el valor 1110 pasa a ser 0111. Esto es desplazar los bits a la derecha, se mueven todos un lugar. El Bit 3 quedaría vacío, y en su lugar se coloca un 0.
  Otro ejemplo (binario) 1001, después del shif 0100. Se desplazan todos una posición hacia la derecha (el bit de menor peso se pierde) y el bit de mayor peso queda en 0.

  El mismo criterio se emplea para el shift left, solo que el desplazamiento es hacia la izquierda.

  ¿Qué compilador estás usando y cuales son los errores que aparecen? (pnelo en modo texto para que los podamos ver, o en todo caso algún otro servidor de imágnes) Creo que el ejemplo que puso Suky funciona en CCS
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: ppyote en 23 de Febrero de 2011, 14:51:13
void main(){
   int cuenta;
   long valor1=0b1100101110001010;
   long valor2=0;

   for(cuenta=15;cuenta<=15;cuenta--){
      if(bit_test(valor1,cuenta))bit_set(valor2,15-cuenta);
      else bit_clear(valor2,15-cuenta);
   }
}

yo lo hago asi...
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: Thulsa Doom en 23 de Febrero de 2011, 15:00:13
El compilador es CCS pero me lo compila bien y no da error, el error lo da en el simulador proteus, y esos datos yo los saco por pantalla LCD para comprobar que esta haciendo bien el desplazamiento.

Yo entiendo lo de desplazar a la izquierda y derecha, lo que no entiendo es la sintaxis de la función, por ejemplo en el manual de ccs c pone esto:
(http://img217.imageshack.us/img217/1788/shiftleft.png) (http://img217.imageshack.us/i/shiftleft.png/)
Tiene un ejemplo y todo pero lo aplico y no me funciona, lo que he dicho error de memoria en el proteus, buscando por la red he encontrado otros ejemplos utilizando punteros pero no lo entiendo.
me esta costado de entender el C, porque aplico lo que leo en los libros y foros y no me funciona,(estoy frustrado). a ver si con el tiempo y la ayuda lo voy comprendiendo
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: AngelGris en 23 de Febrero de 2011, 16:04:38
  Por lo que yo entiendo de la sintaxis, address es la la variable a la cual le quieras hacer el shift, bytes es la cantidad de bytes que tiene tu variable y value es el valor que se va a utilizar en los lugares "vacios" (o sea, el relleno que se va agregando)
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: Thulsa Doom en 23 de Febrero de 2011, 18:46:27
¿Y donde se supone que se guarda el resultado?
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: AngelGris en 23 de Febrero de 2011, 19:04:00
¿Y donde se supone que se guarda el resultado?

  En la propia variable que se le pasa a la función shift
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: Thulsa Doom en 24 de Febrero de 2011, 19:07:30
void main(){
   int cuenta;
   long valor1=0b1100101110001010;
   long valor2=0;

   for(cuenta=15;cuenta<=15;cuenta--){
      if(bit_test(valor1,cuenta))bit_set(valor2,15-cuenta);
      else bit_clear(valor2,15-cuenta);
   }
}

yo lo hago asi...

Gracias , esto si me funciono.

 En la propia variable que se le pasa a la función shift

Gracias AngelGris por la respuesta



Hay una cosa que no entiendo, es lo de la marcara, si yo le hago a un palabra esto:

Código: [Seleccionar]
int16 dato1 = 0b0011111111111111;
dato = (dato1 & 0b00000011111111);

como el dato1 no es una palabra constante si no que cambia dependiendo del momento que este midiendo (el dispositivo conectado es un detector de temperatura que pasa el dato a digital automáticamente generando el dato de 16 bits) si la palabra cambia por ejemplo dato1 = 0b0001111000000000; como le está haciendo un and continuamente al dato1 y como todos sabemos que

   AND
00 | 0
01 | 0
10 | 0
11 | 0
¿Al cambiar los 1 por los 0 en dato1, ese o esos bits no se anula al pasar a 0, quedando el dato incompleto?
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: ppyote en 24 de Febrero de 2011, 19:28:04
void main(){
   int cuenta;
   long valor1=0b1100101110001010;
   long valor2=0;

   for(cuenta=15;cuenta<=15;cuenta--){
      if(bit_test(valor1,cuenta))bit_set(valor2,15-cuenta);
      else bit_clear(valor2,15-cuenta);
   }
}

yo lo hago asi...

Gracias , esto si me funciono.


me alegro que te funcionase... un saludo
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: AngelGris en 24 de Febrero de 2011, 20:00:16
  No entiendo bien el planteo respecto de las máscaras. Que un bit sea 0 no significa que se anule. Veamos si con un par de ejemplos se entiende mejor el tema

  Imaginemos que se reciben 16 bits pero sólo nos interesan desde el 0 hasta el 11.. Llamaremos "dato1" a la variable en la cual se almacena lo recibido y "dato_con_mascara" (que original!  :D ) a la variable a la cual ya le apliqué la máscara. La máscara tiene que ser 0b0000111111111111 (sólo tienen que estar en 1 los bits que nos interesen).

  En primera instancia dato1 = 0b1010101010101010. Ahora, al aplicar la máscara quedaría así....

dato_con_mascara = dato1 & 0b0000111111111111 --> dato_con_mascara = 0000101010101010

dato1                   0b1010101010101010
mascara               0b0000111111111111
dato_con_mascara 0b0000101010101010        // lo puse en esa forma para que se lea mejor el resultado de la AND

como verás los bits 0..11 siguen manteniendo el valor original de la variable dato1

si ahora dato1 = 1111000011001100

dato_con_mascara = dato1 & 0b0000111111111111 --> dato_con_mascara = 0b0000000011001100

dato1                   0b1111000011001100
mascara               0b0000111111111111
dato_con_mascara 0b0000000011001100

como verás los bits 0..11 siguen manteniendo el valor original de la variable dato1
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: Thulsa Doom en 24 de Febrero de 2011, 20:07:11
aa vale, yo lo veía desde el punto de vista de puertas lógica, de que cuando multiplicabas dos números binarios el resultado que daba es  de una puerta AND, por eso puse los valores de una AND en mensajes anteriores, no lo había visto como una formula en un compilador.
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: AngelGris en 24 de Febrero de 2011, 20:11:23
aa vale, yo lo veía desde el punto de vista de puertas lógica, de que cuando multiplicabas dos números binarios el resultado que daba es  de una puerta AND, por eso puse los valores de una AND en mensajes anteriores, no lo había visto como una formula en un compilador.

  Es que justamente hace una AND, no es que sea una fórmula del compilador. El problema es que, al menos en la última tabla que mostrás, está mal.... La tabla de verdad de una AND es..

00 0
01 0
10 0
11 1

 Es decir que el resultado será 1 sólo cuando todas sus entradas sean 1.
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: Thulsa Doom en 24 de Febrero de 2011, 20:22:16
¿pero eso funcionará?, es que los datos no son fijos si no que cambian, date cuenta que un and es.

   AND
 
 00 | 0    
 01 | 0
 10 | 0
 11 | 1

con lo cual si son 1 si me los pillara pero si son 0 los desechara

  OR

 00 | 0
 01 | 1
 10 | 1
 11 | 1

estas técnicas las he utilizado para hacer que en un mismo puerto tenga patillas de entrada y patillas de salida.
pero si dices que funciona....estudiaré el tema.
gracias

Si es cierto, estoy un poco cansado y se me fue el dedo, pero en otras tablas anteriores si lo pongo bien

Lo que dije anteriormente es por que si tu haces na multiplicación de dos valores por ejemplo

                                     001101
                                 x  000111
                                    -------------
                                     010100  creo que este es el resultado de una multiplicación lógica
con lo cual si cambias el numerador o el denominador el resultado es diferente, por eso decía que como el dato capturado cambia y el dato que introducimos a mano para hacer el and permanece fijo, pues no entendía como cambiando una de las dos palabras, permanecía fijo la cantidad de bits que designaba con la palabra que introducimos a mano.

Uffff que rollo al igual estoy liandolo un poco mas de lo debido  :)
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: AngelGris en 24 de Febrero de 2011, 20:30:00
  Ah perdón, pensé que capaz tu confusión venía por ese lado.
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: pocher en 25 de Febrero de 2011, 08:28:27
Lo que has hecho aquí es una suma logica:

                                     001101
                                 x  000111
                                    -------------
                                     010100

... no una multiplicación a nivel de bits cuyo resultado seria:

                                     001101
                                 x  000111
                                    -------------
                                     000101
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: Thulsa Doom en 25 de Febrero de 2011, 12:50:04
Jo es verdad, uyyy estoy oxidado.
bueno pero mi pregunta sigue siendo la misma
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: Thulsa Doom en 28 de Febrero de 2011, 19:50:14
Hola a todos, pues quiero agradecer a todos los que me han ayudado, al final he conseguido mi propósito gracias a vuestra ayuda, el dispositivo que diseñe está funcionando a la perfección, me falta añadirle varias cositas pero el protocolo spi + el max6675, esta midiendo bien. La verdad es que no tengo palabras, seguro que para mucho de ustedes lo que he hecho es una chorrada pero a mi me ha costado mas de 6 mese, he aprendido C desde 0 y poco a poco y gracias a la ayuda que he encontrado en este foro lo he logrado.

GRACIASS
Título: Re: ¿Como puedo seleccionar los bits que me interesan dentro de una palabra?
Publicado por: Nocturno en 01 de Marzo de 2011, 02:46:46
Me alegro que lo hayas conseguido.