7 votos

La forma más eficiente de crear una matriz de bool en C - AVR

Estoy usando un Atmega32 a leer varios sensores usando su ADC.

El uso de la lógica digital y un par de multiplexores, he multiplexado la totalidad de PORTA, el uso de PA0:6 para la dirección y PA7 como la de entrada. Por lo tanto, puede tener un máximo de 128 entradas de un solo PUERTO.

Ahora, desde el usuario será el funcionamiento del sistema a través de un ordenador (mediante RS232), será posible añadir o eliminar los sensores, por lo que el sistema debe hacer un seguimiento de que las direcciones son libres de añadir sensores y que se dirige a la lectura.

Yo estaba pensando en usar una de 128 bits arreglo booleano como bandera para indicar si hay un sensor en una dirección determinada.

Mientras que C no tiene soporte nativo para los bits variables, es posible el uso de campos de bits para empaquetar juntos hasta 8 "bool variables" en un solo unsigned char.

Por lo tanto, he creado la siguiente estructura:

typedef struct bool_s{
      uint8_t bit1:1;
}bool_t;

A continuación, he creado un array de tipo bool_t con un tamaño de 128, con la esperanza de que todo iba a estar bien juntos, pero sizeof() me dice que el tamaño de la matriz es de 128 bytes en lugar de los 16 bytes que yo estaba esperando.

Técnicamente, podría crear una sola estructura con 128 bit 1 variables:

typedef struct Flag_s{
      uint8_t F1:1;
      uint8_t F2:1;
      uint8_t F3:1;
      [...]
      uint8_t F128:1;
}Flag_t;

El problema con este enfoque es que mientras lo hace reducir el uso de memoria, no es muy práctico de usar y ocupa demasiado de bienes raíces en el código.

¿Hay alguna forma fácil de crear una gran cantidad de banderas o estoy pidiendo demasiado? Quiero decir, no es como el ahorro de 112 bytes va a hacer una gran diferencia cuando usted tiene 2K disponibles, pero lo que si necesitaba aún más banderas?

13voto

Al pacino Puntos 415

Los campos de bits no funcionan así. Cventu la respuesta muestra una forma correcta de usarlos, pero en este caso, recomiendo evitarlos por completo.

En su lugar, cree una matriz de 8-bit de valores y cambio de uso de máscara y para acceder a ella:

uint8_t flags[16];

//Initialize the flags
void init_flags(void)
{
    for (i = 0; i < 16; i++)
    {
        flags[i] = 0x00;
    }
}

//Set one flag based on the address
void set_flag(uint8_t address)
{
    flags[address/8] |= 0x1 << (address % 8);
}

//Clear one flag based on the address
void clear_flag(uint8_t address)
{
    flags[address/8] &= ~(0x1 << (address % 8));
}

//Check whether a flag is set
bool get_flag_state(uint8_t address)
{
    return (flags[address/8] & (0x1 << (address % 0x8))) != 0x00;
}

Esto es probablemente lo que el compilador va a hacer con campo de bits de accesos de todos modos, y es más fácil trabajar con. Algunos optimizadores son malas en la optimización de los campos de bits, por lo que el compilador incluso podría hacerlo peor. Todos los compiladores he visto girar a la división y módulo por una potencia constante de dos en derecho de desplazamiento y Y las instrucciones. Se pueden utilizar las operaciones directamente, si te sientes paranoico:

flags[address>>3] |= 0x1 << (address & 0x7);

Los campos de bits son más como las estructuras de las matrices. En mi experiencia, son sólo útiles para las cosas que tienen nombres, como campos del registro.

9voto

cventu Puntos 168

Suena un poco confuso, pero tal vez algo como esto puede ayudar a:

struct bits_field {
                       unsigned char bit_7 :1;
                       unsigned char bit_6 :1;
                       unsigned char bit_5 :1;
                       unsigned char bit_4 :1;
                       unsigned char bit_3 :1;
                       unsigned char bit_2 :1;
                       unsigned char bit_1 :1;
                       unsigned char bit_0 :1;

                   };

union dt {
             struct bits_field a;
             unsigned char b;
         };

Después de definir los, declarar la variable siguiente:

union dt my_data;

Usted será capaz de escribir todo un grupo de ocho bits regalaron el uso de: my_data.b

O usted puede escribir cada bit individual mediante: my_data.una.bit_7 (o 6,5,4,3,2,1,0)

En caso de que el trabajo para usted, replicar este 16 veces (el uso de una matriz o estructura) y usted será capaz de manejar 128 bits de forma individual.

Háganos saber si funcionó! Buena suerte

0voto

Bernd Puntos 61

Cree una estructura donde se declaran banderas de ocho bits que terminan siendo un byte. A continuación, cree una matriz de estas estructuras de 8 bits.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X