Перейти к содержанию
    

как создать массив из bit?

Добрый день.

Я собираюсь программировать контроллер AT90S8515 в CodeVision.

Возник вопрос.

Можно ли создать массив с типом bit?

И обращаться к отдельным битам этого массива.

 

Я пробовал вот так

typedef struct {

char mybit:1;

} b;

b Bit[127];

…..

 

Bit[counter].mybit=PINA.0;

 

Но запись в память происходит, по типу char. Массив занимает много места.

Пожалуйста, плдскажите другие варианты.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Добрый день.

Я собираюсь программировать контроллер AT90S8515 в CodeVision.

Возник вопрос.

Можно ли создать массив с типом bit?

И обращаться к отдельным битам этого массива.

 

Я пробовал вот так

typedef struct {

char mybit:1;

} b;

b Bit[127];

…..

 

Bit[counter].mybit=PINA.0;

 

Но запись в память происходит, по типу char. Массив занимает много места.

Пожалуйста, плдскажите другие варианты.

 

Как вариант, посмотрите в сторону UNION, в купе с вашим вариантом, может быть поможет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Добрый день.

Я собираюсь программировать контроллер AT90S8515 в CodeVision.

Возник вопрос.

Можно ли создать массив с типом bit?

И обращаться к отдельным битам этого массива.

 

Я пробовал вот так

typedef struct {

char mybit:1;

} b;

b Bit[127];

…..

 

Bit[counter].mybit=PINA.0;

 

Но запись в память происходит, по типу char. Массив занимает много места.

Пожалуйста, плдскажите другие варианты.

 

Так сохраняйте в структуре состояние всего порта (ну т.е. состояние его пинов)

а потом в программе анализируйте необходимый бит

 

typedef struct { 
  char  pin_state;
} ps;
ps PinState[4]; //например будете хранить состояния пинов 4х портов

#define port_a 0
#define port_c 1
#define port_b 2
#define port_d 3

#define bit_0  1<<0
.........................
#define bit_7  1<<7

PinState[port_a].pin_state = PINA;

if(PinState[port_a].pin_state&bit_0) //проверка пина 0 порта А
{
}

Изменено пользователем mempfis_

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

примерно так:

char getBit(char* array, int n)
{
  return array[n/8] & (1<<(n%8));
}

void setBit(char* array, int n, char val)
{
   char *p = &array[n/8];
   if (val)
    *p |= 1<<(n%8);
   else
     *p &= ~(1<<(n%8));
}

char array[50]; // размер 50*8

setBit(array, 10, 0);
setBit(array, 11, 1);

char t = getBit(array, 10);

 

Если с++ - можно обернуть это в класс с перегруженным оператором []

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поройтесь в заголовочных файлах CV там где порты описаны, там уже есть готовые макросы для подобного описания

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так сохраняйте в структуре состояние всего порта (ну т.е. состояние его пинов)

а потом в программе анализируйте необходимый бит

 

typedef struct { 
  char  pin_state;
} ps;
ps PinState[4]; //например будете хранить состояния пинов 4х портов

#define port_a 0
#define port_c 1
#define port_b 2
#define port_d 3

#define bit_0  1<<0
.........................
#define bit_7  1<<7

PinState[port_a].pin_state = PINA;

if(PinState[port_a].pin_state&bit_0) //проверка пина 0 порта А
{
}

 

 

я бы перефразировал

 

typedef union
{ 
  struct
  {
    unsigned char  _0:1;
    unsigned char  _1:1;
    unsigned char  _2:1;
    unsigned char  _3:1;
    unsigned char  _4:1;
    unsigned char  _5:1;
    unsigned char  _6:1;
    unsigned char  _7:1;
  } pin;

  unsigned char port;
} ps;


ps PinState[4]; //например будете хранить состояния пинов 4х портов

#define port_a 0
#define port_c 1
#define port_b 2
#define port_d 3


PinState[port_a].port = PINA;

if(PinState[port_a].pin._0) //проверка пина 0 порта А
{
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Добрый день.

Я собираюсь программировать контроллер AT90S8515 в CodeVision.

Возник вопрос.

Можно ли создать массив с типом bit?

И обращаться к отдельным битам этого массива.

 

Я пробовал вот так

typedef struct {

char mybit:1;

} b;

b Bit[127];

…..

 

Bit[counter].mybit=PINA.0;

 

Но запись в память происходит, по типу char. Массив занимает много места.

Пожалуйста, плдскажите другие варианты.

 

Доброго времени суток!

 

Вот Вам, мой вариант:

#define BUFFER_BIT_SIZE 32

 

unsigned char buffer[bUFFER_BIT_SIZE/8+1]; // +1 для запаса. Если буфер кратен 8 то не нужно

 

void set_bit_buffer (unsigned char value)

{

unsigned char b,i;

 

b = value/8;

i = value%8;

 

buffer |= (0x80 >> i);

}

 

unsigned char get_bit_buffer (unsigned char value)

{

unsigned char b,i;

 

b = value/8;

i = value%8;

 

b = buffer;

b <<= i;

b &= 0x80;

 

return b; // Если бит = "1" возвращаем 0x80;

}

 

Такой вариант будет экономить память, но нагружать АЛУ (соответсвенно - потери в скорости).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот Вам, мой вариант:

 

b = value/8;

i = value%8;

 

Такой вариант будет экономить память, но нагружать АЛУ (соответсвенно - потери в скорости).

 

Плохой вариант. Лучше так:

 

b = value >> 3;

i = value & 0x7;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот Вам, мой вариант:

#define BUFFER_BIT_SIZE 32

 

unsigned char buffer[bUFFER_BIT_SIZE/8+1]; // +1 для запаса. Если буфер кратен 8 то не нужно

А вот Вам мой:
unsigned char buffer[(BUFFER_BIT_SIZE + 7)/8];//всегда выделяет столько, сколько нужно

И можно оформить это в виде макросов:

#ifndef    BIT_ARRAY_H__
#define    BIT_ARRAY_H__
#include    <stdint.h>

#define    BA_BASE    uint8_t                                // 8 bits
#define    BA_BASE_BITS    (CHAR_BIT * sizeof(BA_BASE))        // 8
#define    BA_BASE_MASK    (BA_BASE_BITS - 1)                    // 7 = 0x07

#define    BIT_ARRAY(name, size)    \
    BA_BASE name[ (size + BA_BASE_BITS - 1) / BA_BASE_BITS ]
//  Macro can be modified to functions to reduce code size
#define    BIT_SET(array, bit)        \
    do { array[ bit / BA_BASE_BITS ] |=  (1 << ( bit & BA_BASE_MASK)); } while (0)
#define    BIT_CLR(array, bit)        \
    do { array[ bit / BA_BASE_BITS ] &= ~(1 << ( bit & BA_BASE_MASK)); } while (0)
#define    BIT_TEST(array, bit)    \
    ( array[ bit / BA_BASE_BITS ] & (1 << ( bit & BA_BASE_MASK)) )

/*
// functions can be placed into separate .c file to reduce code size
void BIT_SET(BA_BASE *array, uint8_t bit) 
{
    array[ bit / BA_BASE_BITS ] |=  (1 << ( bit & BA_BASE_MASK));
}
void BIT_CLR(BA_BASE *array, uint8_t bit) 
{
    array[ bit / BA_BASE_BITS ] &=  ~(1 << ( bit & BA_BASE_MASK));
}
BA_BASE BIT_TEST(BA_BASE *array, uint8_t bit) 
{
    return array[ bit / BA_BASE_BITS ] & (1 << ( bit & BA_BASE_MASK));
}
*/
#endif    //BIT_ARRAY_H__

использование:
BIT_ARRAY(Array1, 50);
BIT_ARRAY(Array2, 16);
void test()
{
     BIT_SET(Array1, 45);
     if(BIT_TEST(Array1, 27))
          BIT_CLR(Array2, 5)
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Главное это идея, а как реализовать это дело вкуса =)

 

Хорошо было бы сравнить полученный ассемблерный код, да и вопрос нельзя решить однозначно, все зависит от задачи.

 

 

unsigned char buffer[(BUFFER_BIT_SIZE + 7)/8];//всегда выделяет столько, сколько нужно

 

хорошая мысль ....

 

b = value >> 3;

i = value & 0x7;

 

Опять же, кто-нибудь сравнивал ассемблерный код ?

Изменено пользователем Ph. Anatoliy

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

b = value >> 3;

i = value & 0x7;

 

Опять же, кто-нибудь сравнивал ассемблерный код ?

IAR, GCC при включенной оптимизации генерят идентичный код для обоих вариантов - заменяют деление на степень двойки сдвигом и взятие остатка наложением маски.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сергей Борщ - Спасибо за анализ ....

 

Опять таки вопрос оптимизации...

 

А спрашивали "как организовать битовый массив" а не "как оптимально написать код" =)

Изменено пользователем Ph. Anatoliy

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...