TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: ochi en 11 de Abril de 2008, 05:03:51

Título: utilizar los bits de un byte.
Publicado por: ochi en 11 de Abril de 2008, 05:03:51
hola, estoy intentando conseguir mirar cada bit independiente de un char, según veo en otros foros, y en la  definición de la librería p30f4013.h (fijandome por ejemplo en PORTB) se debe hacer de este modo:

Me he creado una librería bits.h donde pongo:

/* Registro de ocho bits */
extern volatile unsigned int REGISTRO8 __attribute__((__sfr__));
typedef struct tagREGISTRO8BITS {
        unsigned BIT0    :1;
        unsigned BIT1    :1;
        unsigned BIT2    :1;
        unsigned BIT3    :1;
        unsigned BIT4    :1;
        unsigned BIT5    :1;
        unsigned BIT6    :1;
        unsigned BIT7    :1;
} REGISTRO8BITS;
extern volatile REGISTRO8BITS REGISTRO8bits __attribute__((__sfr__));


#define _BIT80 REGISTRO8bits.BIT80
#define _BIT81 REGISTRO8bits.BIT81
#define _BIT82 REGISTRO8bits.BIT82
#define _BIT83 REGISTRO8bits.BIT83
#define _BIT84 REGISTRO8bits.BIT84
#define _BIT85 REGISTRO8bits.BIT85
#define _BIT86 REGISTRO8bits.BIT86
#define _BIT87 REGISTRO8bits.BIT87

en mi programa incluyo la librería y llamo a REGISTRO8 me dice que no está declarada la variable. ¿alguien sabe que hago mal?


Muchass gracias
Título: Re: utilizar los bits de un byte.
Publicado por: migsantiago en 11 de Abril de 2008, 23:28:56
Hola

No conozco la forma de declaración de tu librería, no puedo revisarla  :mrgreen:

Pero te puedo recomendar que hagas máscaras para hacer test de bits...

Código: [Seleccionar]
bool test_bit(char variable, int bit) //bit puede ser de 0 a 7
{
if((variable>>bit)&0b00000001) //multiplica por 1 el bit a checar, si es 1 regresa un 1
   return 1;
else //si fue cero regresa un cero
   return 0;
}

Y ya usándola...

Código: [Seleccionar]
char variable;
bool valor;

...

variable=0b01011010;

//checando bit 1
valor=test_bit(variable,1); //esto va a entregar un 1

Ojo... la acabo de escribir, no sé si funciona en tu compilador en específico  :mrgreen: Puede lograrse de una mejor forma con otras funciones, pero esa es la que se me ocurre  :P
Título: Re: utilizar los bits de un byte.
Publicado por: Nocturno en 12 de Abril de 2008, 02:54:46
Yo particularmente me vuelvo un poco tarumba con tantos atributos alrededor de las estructuras y variables.
Mi consejo es que pruebes a declarar la estrutura y la variable en tu propio programa, y cuando consigas que funcione bien así, hagas la prueba de sacarlo a una librería externa y ponerle el resto de atributos.
O sea, yo haría esto dentro de tu programa principal:


/* Registro de ocho bits */

typedef struct tagREGISTRO8BITS {
        unsigned BIT0    :1;
        unsigned BIT1    :1;
        unsigned BIT2    :1;
        unsigned BIT3    :1;
        unsigned BIT4    :1;
        unsigned BIT5    :1;
        unsigned BIT6    :1;
        unsigned BIT7    :1;
} REGISTRO8BITS;

REGISTRO8BITS REGISTRO8bits;

Luego, para acceder a cada uno de los bits de la variable, en tu programa tendrás que hacer referencia a:
REGISTRO8bits.BITn

Una vez que consigas que eso funcione, si quieres puedes sacarlo a librería fuera y añadirle lo que quieras mientras siga funcionando.
Título: Re: utilizar los bits de un byte.
Publicado por: ochi en 15 de Abril de 2008, 08:47:48
Hola, acabo de ver las formas que me decis, y me gustaría hacerla con una librería. Empiezo a hacerlo como me dice nocturno, y puedo coger bit a bit, pero no puedo definir el registro completo.

Es decir, lo que pretendo hacer es dar un valor al registro completo y luego

if(REGISTRO8bits.BIT0==1){} (por ejemplo) pero lo consigo de ninguna manera. ¿alguna idea?. Gracias.
Título: Re: utilizar los bits de un byte.
Publicado por: maunix en 15 de Abril de 2008, 09:32:02
Podrías usar lo que se llama una unión en C

typedef union {
    unsigned char value;
    struct {
       unsigned bit0:1;
       unsigned bit1:1;
       unsigned bit2:1;
       unsigned bit3:1;
       unsigned bit4:1;
       unsigned bit5:1;
       unsigned bit6:1;
       unsigned bit7:1;
    } bits;
} Tmibyte;

bits sería el nombre de la estructura el cual es exigido por algunos compiladores.  NO todos, por ejemplo en C18 no hace falta pero en Hitech si.

La forma de usarlo sería algo asi


   Tmibyte mivariable;

   mivariable.value = 20;
   if (mivariable.bits.bit0 ==1 ) { ...}



Y cuantas combinaciones se te ocurran  :)
Título: Re: utilizar los bits de un byte.
Publicado por: ochi en 15 de Abril de 2008, 11:23:09
Perfecto! si meto eso que me dices en una librería funciona justo como quiero. Muchas gracias
Título: Re: utilizar los bits de un byte.
Publicado por: Marttyn en 18 de Abril de 2009, 10:11:51
Podrías usar lo que se llama una unión en C

typedef union {
    unsigned char value;
    struct {
       unsigned bit0:1;
       unsigned bit1:1;
       unsigned bit2:1;
       unsigned bit3:1;
       unsigned bit4:1;
       unsigned bit5:1;
       unsigned bit6:1;
       unsigned bit7:1;
    } bits;
} Tmibyte;

bits sería el nombre de la estructura el cual es exigido por algunos compiladores.  NO todos, por ejemplo en C18 no hace falta pero en Hitech si.

La forma de usarlo sería algo asi


   Tmibyte mivariable;

   mivariable.value = 20;
   if (mivariable.bits.bit0 ==1 ) { ...}



Y cuantas combinaciones se te ocurran  :)

Estoy haciendo un programa que necesito hacer exactamente eso. Poder acceder a cada bit de una variable INT y tambien poder leer la variable entera.
Mi duda es si hace falta crear la union, o solo con la estructura me llega.
Con la union puedo hacer como dice Maunix para leer o escribir en la variable entera: mivariable.value = 20;
Pero si no creo la union, podria crear "mivariable" como estructura, y luego hacer mivariable = 20?
De esa manera podria acceder tanto a los bits, como al byte completo, sin tener que crear la union... siempre y cuando sea posible, claro  :mrgreen:
Título: Re: utilizar los bits de un byte.
Publicado por: Nocturno en 18 de Abril de 2009, 14:24:50
Si no haces la unión no podrás asignar un valor a la variable completa de una sóla tacada.
Título: Re: utilizar los bits de un byte.
Publicado por: PHLAKO en 05 de Mayo de 2009, 15:11:40
no me funciona :(, no puedo asignarle valores al registro.

bue...como voy a trabajar esta vez con registro de 8 bits, le puse 3 lineas de ASM y listoco :mrgreen:

no puedo creer que no exista algo sencillo como VARIABLEbits.B0 = 1/0 y VARIABLEbits.B0 == 1/0 (como el BSF y BTFSS de ASM)

ASM 1 / C18 0

saludos,

chaos :)
Título: Re: utilizar los bits de un byte.
Publicado por: Nocturno en 05 de Mayo de 2009, 15:20:52
Sí, claro que existe, se llaman bit_set y bit_clear. E incluso existe el bit_test que te devuelve el estado.
Título: Re: utilizar los bits de un byte.
Publicado por: PHLAKO en 05 de Mayo de 2009, 19:06:50
pues quedo mas confundido aun, si existe eso que nombras, para que usar lo de las estructuras? si eres tan amable me lo explicas, porque prefiero evitar usar ASM dentro de C,  :-/

saludos,

chaos :)
Título: Re: utilizar los bits de un byte.
Publicado por: Nocturno en 05 de Mayo de 2009, 20:03:42
Hay muchas soluciones para un mismo problema, por suerte. Así cada cual escoge la que más le convenga.

Yo particularmente veo mucho más legible el código con estructuras, pero es cuestión de gustos.
Título: Re: utilizar los bits de un byte.
Publicado por: Duende_Azul en 05 de Mayo de 2009, 23:09:03
Que tal esto:


Defines la variable cuyos bits deseas acceder y luego defines cada bit con un nombre..  ejemplo:

Código: [Seleccionar]
int8 banderas;  //Registro
#bit cero  = banderas.0  //define el bit o de banderas como "cero"
#bit signo = banderas.1  //define el bit 1 de banderas como "signo"
#bit parid = banderas.2  //etc....
#bit acarr = banderas.3
#bit a_aux = banderas.4


void main()
{
//asignas el valor de cada bit del registro banderas así:
   cero=1;  //bit 0 se pone a 1
   signo=1; //bit 1 se pone a 1
   parid=1; //etc...
   acarr=1;
   a_aux=1;
   
//puedes consultar el estado de un bit así:

   if(acarr==1)
      cero=0;

}



Título: Re: utilizar los bits de un byte.
Publicado por: Marttyn en 06 de Mayo de 2009, 00:08:22
Duende, lo que acabas de decir es una GENIALIDAD!!!
Lo utilizo siempre para darle nombre al puerto y a sus pines, pero no lo habia pensado para un byte.... QUE BUENO!!!!
Ya mismo me pongo a modificar el codigo donde tenia un typedef, una union entre el typedef y un byte, y una variable declarada como la union.... eso si que es simplificar!  :mrgreen:
Título: Re: utilizar los bits de un byte.
Publicado por: MGLSOFT en 06 de Mayo de 2009, 00:16:14
Yo lo uso asi en mis programas, solo que no lo puse porque crei que no aplicaba a la pregunta general... :(
Título: Re: utilizar los bits de un byte.
Publicado por: PHLAKO en 06 de Mayo de 2009, 09:21:36
Marttyn, me ganaste el comentario :mrgreen: creo que Duende respondio a la perfeccion, se agradece mucho, lo voy aprobar.....

Nocturno, gracias por los datos, de igual modo si puedes poner un ejemplillo de lo que indicaste mas arriba8, seria genial, o de todas formas necesito definir los bits de la variable?

saludos

chaos :)
Título: Re: utilizar los bits de un byte.
Publicado por: Marttyn en 06 de Mayo de 2009, 10:39:20
Hola phlaco, aqui tienes un ejemplo de como hacerlo con estructuras y uniones:

Código: C
  1. typedef struct{
  2. //a cada bit puse nombres "bitx" para que se vea mejor, pero realmente se puede usar cualquier nombre mas representativo, como "Led", "Motor", etc
  3.         short bit0;
  4.         short bit1;
  5.         short bit2;
  6.         short bit3;
  7.         short bit4;
  8.         short bit5;
  9.         short bit6;
  10.         short bit7;
  11. }Bits;          //nombre de mi estructura
  12.  
  13. typedef union{
  14.         int sByte;              //declaro un INT
  15.         Bits sBits;             //declaro una variable como estructura
  16. }Bits_Bytes;            //nombre de mi union
  17.  
  18. Bits_Bytes Indicadores;         //declaracion una variable como union
  19.  
  20. //Para leer o escribir el bit0 por ejemplo, te referiras a el como:
  21. Indicadores.sBits.bit0
  22.  
  23. //Para leer o escribir el byte completo usaras:
  24. Indicadores.sByte

Este codigo, casi tal cual lo ves lo puedes encontrar en el foro, yo lo encontre por aqui, pero lo modifique un poquito a mi gusto.
Salu2
Título: Re: utilizar los bits de un byte.
Publicado por: PHLAKO en 06 de Mayo de 2009, 10:58:24
al parecer no es C18, no me funciona :(

saludos

chaos :)
Título: Re: utilizar los bits de un byte.
Publicado por: Marttyn en 06 de Mayo de 2009, 11:08:20
perdon, no sabia que necesitabas C18....
la verdad que de eso aun no entiendo... tal vez los amigos te puedan ayudar
Salu2!
Título: Re: utilizar los bits de un byte.
Publicado por: PHLAKO en 06 de Mayo de 2009, 11:21:42
Marttyn, al contrario, muchas gracias por las ganas de ayudar. Yo aun no identifico bien cuando es C18 u otro compilador :mrgreen:

saludos

chaos :)
Título: Re: utilizar los bits de un byte.
Publicado por: RICHI777 en 06 de Mayo de 2009, 13:42:49
Hola, el ejemplo que puso Duende Azul seguramente es para CCS, si no estoy equivocado C18 es practicamente ANSI C con lo cual la definción #bit cero  = banderas.0 no es valida. Las definiciones correctas segun mi entender serian los post de Ochi y del maestro Nocturno, que en definitiva son campos de bits. Si queres acceder a cada bit y al byte completo deberas usar la definción de Maunix que suma una union a la definción del campo de bits.

Citar
Mi duda es si hace falta crear la union, o solo con la estructura me llega.
Con la union puedo hacer como dice Maunix para leer o escribir en la variable entera: mivariable.value = 20;
Pero si no creo la union, podria crear "mivariable" como estructura, y luego hacer mivariable = 20?
De esa manera podria acceder tanto a los bits, como al byte completo, sin tener que crear la union... siempre y cuando sea posible, claro
Si no declaras la union y te quedas con la estructura solo accederas a los miembros del campo de bits o a los bits en particular, con la union accedes a un bit en particular o al byte contendedor, tal cual no ejemplifico Maunix.
Título: Re: utilizar los bits de un byte.
Publicado por: PHLAKO en 06 de Mayo de 2009, 13:57:21
Pues si, gracias por recordarmelo, no habia agradecido a Maunix, lo que puso al principio, funciona a la perfccion. :-/

Pero no me deja de extrañar que se tenga que realizar esa operacion para manejar bits de un byte, ademas de mover el registro completa (ademas que se usa un byte enterito por cada bits y en mi opinion se desperdicia espacio)

Saludos,

Chaos :)
Título: Re: utilizar los bits de un byte.
Publicado por: Duende_Azul en 06 de Mayo de 2009, 14:08:13
Lo que puse antes es para CCS.
Título: Re: utilizar los bits de un byte.
Publicado por: RICHI777 en 06 de Mayo de 2009, 14:45:38
Hola, justamente un campo de bits permite manejar n bits en forma particular, lamentablemente es uno de los puntos oscuros del estandart ANSI C y por ende poco portable. Y justamente el uso de la union es definir un espacio que es igual al mayor de los miembros, con lo cual en este caso no se desperdicia nada, porque los 8 bits ocupan el mismo byte. Eso lo podes ver en al archivo map que genera el linker y ver como se comparte la memoria.

Saludos !
Título: Re: utilizar los bits de un byte.
Publicado por: PHLAKO en 06 de Mayo de 2009, 15:22:30
Hola, justamente un campo de bits permite manejar n bits en forma particular, lamentablemente es uno de los puntos oscuros del estandart ANSI C y por ende poco portable. Y justamente el uso de la union es definir un espacio que es igual al mayor de los miembros, con lo cual en este caso no se desperdicia nada, porque los 8 bits ocupan el mismo byte. Eso lo podes ver en al archivo map que genera el linker y ver como se comparte la memoria.

Saludos !

(http://img147.imageshack.us/img147/5932/struct.jpg)

yo lo veo tal cual un array con variables de 8 bits, dehecho cambian de 0 a 1, decimal. Por lo tanto se estaria ocupando un solo bit par cada uno de los bytes................toy mal?

Saludos,

chaos :)


ME AUTO CORRIJO, no habia visto que estan en la misma direccion :mrgreen: tienes toda la razon, es un solo byte :-/
Gracias por la explicacion.
Título: Re: utilizar los bits de un byte.
Publicado por: Braulio en 07 de Septiembre de 2010, 03:51:42
Amigos tengo un problema similar usando CCS
 
Resulta que tengo un vector de 64 bytes definido como

int8 dato[64]

del cual debo utilizar de forma indistinta algunos bytes y algunos bits específicos. Por ejm.:


La primera no es problema, manipulo directamente usando dato[3], o le pongo un nombre:

#DEFINE   byte_4to   dato[3]


Pero la segunda si es problemática, pues no me permite hacer lo que indica Duente_Azul:


int8 dato[64];
#bit  bandera = dato[2].0


Al compilar me salen 3 errores en la misma linea

Expecting a .
Expecting a declaration
Expecting a declaration


por favor ojala alguien pueda darme una idea de como solucionar esto. Manipular un bit directamente  por su nombre simplifica mucho el entendimiento del programa y el programa en si.

BRAULIO