TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: migsantiago en 30 de Enero de 2007, 20:50:06

Título: Alternativa a arreglos de 1 bit
Publicado por: migsantiago en 30 de Enero de 2007, 20:50:06
Hola

Estoy haciendo un programa en el que necesito guardar muchos unos y ceros en variables de 1bit. La mejor solución es generar un arreglo de 1bit pero en la v3.245 de CCS todavía no se permite hacerlo.

Por ahora no puedo empezar a usar la 4 por todos los bugs que todavía tiene, por eso recurro a ustedes para que me ofrezcan alguna alternativa.

Gracias
Título: Re: Alternativa a arreglos de 1 bit
Publicado por: Nocturno en 31 de Enero de 2007, 02:35:15
¿A qué te refieres con "arreglo de 1 bit"?

Yo en CCS sé que funciona lo siguiente:
#bit  led         = PORTB.RB2

pero no sé si será lo que buscas.
Título: Re: Alternativa a arreglos de 1 bit
Publicado por: RedPic en 31 de Enero de 2007, 03:21:08
Traductor simultáneo  :mrgreen:

arreglo = matriz ó tabla. Arreglo es una traducción literal de la inglesa array

CCS C solo permite arreglos, matrices o tablas de bytes, no de bits.
Título: Re: Alternativa a arreglos de 1 bit
Publicado por: migsantiago en 31 de Enero de 2007, 11:45:51
Sí, es que necesito algo así...

int1 bateria[40];

pero ccs 3 no acepta esos arreglos buuu

ya había pensado en lo de #bit pero para acceder secuencialmente a los bits hay que escribir mucho código, se me ocurrió...

int8 bat;

#bit b01 bat.0
#bit b02 bat.1
#bit b03 bat.2
.....

switch(bateriaactual)
{
case 0x01:
b01=1;
break;
case 0x02:
b02=1;
break;
case 0x03:
b03=1;
break;
......

Y si fuera con un arreglo de 1bit...

bateria[bateriaactual]=1;

 :D

Por ahora solucionaré esto con arreglos de 8 bits... aunque desperdiciaré memoria ram (7 bits por byte), pero ahorraré memoria ROM  (http://www.todopic.com.ar/foros/Themes/babylon/images/post/thumbup.gif)


Título: Re: Alternativa a arreglos de 1 bit
Publicado por: Nocturno en 31 de Enero de 2007, 14:13:36
Creo que tampoco es tanto código.

Código: [Seleccionar]
int8 bateria[5]; //esto es un array de 5 bytes, o lo que es lo mismo, 40 bits
int8 PosicionALeer; // nº índice del bit a leer
int1 BitLeido; // resultado

BitLeido = bateria[PosicionALeer / 8] >> (PosicionALeer % 8);

Conste que no lo he probado, pero se me ocurre que podría funcionar.
Título: Re: Alternativa a arreglos de 1 bit
Publicado por: migsantiago en 31 de Enero de 2007, 14:43:44
Wow Manolo... lo malo es que no entiendo lo de >>... ¿eso qué función hace?

Código: [Seleccionar]
BitLeido = bateria[PosicionALeer / 8] >> (PosicionALeer % 8);
 :oops:
Título: Re: Alternativa a arreglos de 1 bit
Publicado por: maunix en 31 de Enero de 2007, 14:55:42
Wow Manolo... lo malo es que no entiendo lo de >>... ¿eso qué función hace?

Código: [Seleccionar]
BitLeido = bateria[PosicionALeer / 8] >> (PosicionALeer % 8);
 :oops:

>> es rotar a la derecha y agrega ceros en el bit más significativo.

<< es rotar a la izquierda y agrega ceros en el bit menos significativo.






Título: Re: Alternativa a arreglos de 1 bit
Publicado por: migsantiago en 31 de Enero de 2007, 15:22:32
eeemmmm...

¿entonces rota a la derecha batería? no entiendo todavía  :oops:  :(
Título: Re: Alternativa a arreglos de 1 bit
Publicado por: maunix en 31 de Enero de 2007, 15:30:25
eeemmmm...

¿entonces rota a la derecha batería? no entiendo todavía  :oops:  :(

Vamos con un ejemplo.


El byte bateria[n] tiene 8 bits.

Si n = 0, sería el primer elemento de tu arreglo de bits.

Por otra parte, si uno quiere el bit nro 12 (que sería la posición 11 ya que el arreglo de bits hacemos que empiece de 0), la función sería así

Bitleido = bateria[11/8] >> (11 % 8)
Bitleido = bateria[1] >> (3)

Si bateria[1] = 0b10001011

// ahora se corre 3 lugares a la derecha
hacer bitleido >> 3 = 0b00010001   


Eso hace que

bitleido = 1






Título: Re: Alternativa a arreglos de 1 bit
Publicado por: migsantiago en 31 de Enero de 2007, 16:27:04
 :shock:

qué ingenioso se vio Manolo  :mrgreen:

Gracias por la explicación Maunix...

solo un detalle... si se asigna un int8 a un int1, ¿siempre asigna el bit menos significativo (bit0)?
Título: Re: Alternativa a arreglos de 1 bit
Publicado por: PalitroqueZ en 31 de Enero de 2007, 16:44:33
:shock:

qué ingenioso se vio Manolo  :mrgreen:

Gracias por la explicación Maunix...

solo un detalle... si se asigna un int8 a un int1, ¿siempre asigna el bit menos significativo (bit0)?

para decir un poquito de teoría:

en CCS se puede declarar una variable de 1 bit, sería por ejemplo

short variable

en el manual ccs_c_manual.pdf (actualizado) página 33, dice:

int1 = Defines a 1 bit number  -> short = int1
...
Código: [Seleccionar]
SHORT is a special type used to generate very efficient code for bit operations and I/O.
Arrays of bits (INT1 or SHORT) in RAM are now supported. Pointers to bits are not permitted.

estas variables se pueden usar como señalizadores (true, false).

Salu2
Pedro
Título: Re: Alternativa a arreglos de 1 bit
Publicado por: migsantiago en 31 de Enero de 2007, 19:08:41
Hola Pali

No me refería a qué es un int1 o un bool...  :mrgreen: me refería a si cuando se hace esto...

int8 variable;
int1 variablechica;

variable=0b00000011;
variablechica=variable;

que si variablechica siempre va a almacenar el bit menos significativo, en este caso el 1

Título: Re: Alternativa a arreglos de 1 bit
Publicado por: Nocturno en 31 de Enero de 2007, 19:37:17
No sé cuál será el tratamiento que hará CCS de eso, supongo que sí. Pero es fácil comprobarlo.

Lo que sí sé es que cuando haces un int8 = int16 se queda con el byte menos significativo.
Título: Re: Alternativa a arreglos de 1 bit
Publicado por: migsantiago en 31 de Enero de 2007, 19:44:13
Vientos gracias a todos  :-/
Título: Re: Alternativa a arreglos de 1 bit
Publicado por: PalitroqueZ en 01 de Febrero de 2007, 12:56:16
No sé cuál será el tratamiento que hará CCS de eso, supongo que sí. Pero es fácil comprobarlo.

Lo que sí sé es que cuando haces un int8 = int16 se queda con el byte menos significativo.

tal como dice Nocturno, habrá que hacer algunas comprobaciones, en el ejemplo prueba a ver si funciona:

Código: [Seleccionar]
variablechica=short(variable)

Salu2
Pedro
Título: Re: Alternativa a arreglos de 1 bit
Publicado por: maunix en 01 de Febrero de 2007, 13:33:23
No sé cuál será el tratamiento que hará CCS de eso, supongo que sí. Pero es fácil comprobarlo.

Lo que sí sé es que cuando haces un int8 = int16 se queda con el byte menos significativo.

Es así porque el estándar ansi así lo especifica.  Una variable mayor dentro de una menor, se asigna por 'truncamiento'.

Lo mismo ocurre en delphi, etc.  De no ser así sería un caos.

Una variable de 1 bit, a la cual se le asigna un byte, de seguro toma el último bit.  Es muy probable que haya un simple BTF del último bit que sería lo más eficiente.


Saludos



Título: Re: Alternativa a arreglos de 1 bit
Publicado por: pikman en 01 de Febrero de 2007, 22:57:49
hola a todos, migsantiago yo uso una estructura, asi si quiero resetear todas las banderas hago en en este caso flag=0; no se cual sea tu caso pero yo encotre esta forma no se si va con tu aplicacion.

Código: [Seleccionar]
   struct {
           int1 mostrar;
           int1 grabar_tarjetas;
           int1 leer_fichado;
           int1 ack;
           int1 reenviar_trama;
           int1 conectar;
           int1 desconectar;
           int1 conectado;
           int1 ajustar_reloj;
           int1 beep;
           int1 sincronizar;
           int1 valid_data;
           int1 send_ack;
           int1 clean_memory;
           int1 trama_ok;
           int1 timer_luz;
           int1 power_ok;
           int1 full_memory;
           } flag;



En otro caso el amigo Sispic uso esto, que tambien es una forma poder direccionar los bits de un byte, usando tambien una estructura, me parece que esto te puede servir mas aun.


Código: [Seleccionar]
typedef struct  {
     int1 b0:1; int1 b1:1; int1 b2:1;  int1 b3:1;  int1 b4:1;  int1 b5:1;  int1 b6:1;  int1 b7:1;
} Los_bits_de_un_Byte;

Título: Re: Alternativa a arreglos de 1 bit
Publicado por: maunix en 02 de Febrero de 2007, 08:25:59
pikman, la estructura te sirve para el paso final de elegir cual bit dentro del byte es el que deberás seleccionar.  No hay forma de que programáticamente definas el bit a elegir dentro de la estructura.  Osea, en algún momento debes terminar en un IF o CASE. 

De todas formas no te evitas de tener que hacer un 'case' lo cual también se haría lento.  Una rotación a la derecha de un byte es realmente rápida y se hace en 1 ciclo de instrucción.

Saludos
Título: Re: Alternativa a arreglos de 1 bit
Publicado por: migsantiago en 02 de Febrero de 2007, 12:12:35
No cabe duda que aquí en el foro hay puro programador experto... yo ni idea tenía de que el arreglo de 1 bit tuviera tantas soluciones  :D

Gracias Pikman
Título: Re: Alternativa a arreglos de 1 bit
Publicado por: BrunoF en 02 de Febrero de 2007, 12:28:10
Tilin Tilin...llego tarde?

Fijate que en esta formula que hice recorro un array de char's bit a bit...
En este caso, recorro bit a bit en una matriz que pertenece a R2, es decir: una matriz bidimensional.

http://www.todopic.com.ar/foros/index.php?topic=14805.msg91248#msg91248

Saludos.
Título: Re: Alternativa a arreglos de 1 bit
Publicado por: pikman en 02 de Febrero de 2007, 13:21:44
Hola, OK, Maunix, bueno no entiendo bien, no entiendo como es que no puedo elegir el bit dentro de la estructura?, si yo tengo un defino por ejemplo int8  cadena[40]; y quiero saber que hay en el byte 39 seguro voy a tener que hacer un IF o un CASE, o  copiar esa posicion de cadena en una variable temporal para extraerla,  temp=cadena[39]; lo que entiendo que migsantiago quiere hacer saber que bit esta en 1, por lo que si tuviese la posibilidad CCS de hacer lo que el pretender deberia tambien verificar bit por bit, para saber cual esta en 1, lo otro que no entiendo que el pretende 40 bits por lo que la variable deberia ser un int32, en tu ejemplo direcciona al bit 12 de una variable de 8 bits?, bueno creo que se me ha hecho una ensalada, pero me interesa de sobre manera el manejo de bits que siempre es un problema dificil de solucionar, desde ya gracias por tu explicacion.

Título: Re: Alternativa a arreglos de 1 bit
Publicado por: Nocturno en 02 de Febrero de 2007, 13:28:13
Pikman, creo que Maunix se refiere a una solución que propuse al principio del hilo, y que viene bien explicada por el propio Maunix algo más tarde.
Título: Re: Alternativa a arreglos de 1 bit
Publicado por: migsantiago en 02 de Febrero de 2007, 13:38:23
Hola originalmente quería poner a uno o cero cualquier bit de un arreglo de 40 bits. Luego poder leer cualquier bit de ese mismo arreglo.

Hasta ahora Manolo ha propuesto una función para leer el bit de ese arreglo de 40... propongo unas mejoras... aún no probadas

Código: [Seleccionar]
int8 bateria[5]; //40bits
int8 posicion; //no. de bit del arreglo de 40 a leer o escribir
int1 soyunbit; //él es un bit

//para poner a 1 cualquier bit
bit_set(bateria[posicion/8],(posicion%8));

//para poner a 0 cualquier bit
bit_clear(bateria[posicion/8],(posicion%8));

//para leer cualquier bit
soyunbit=bit_test(bateria[posicion/8],(posicion%8));