реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> как создать массив из bit?, CodeVision
zuuuuk
сообщение Sep 30 2008, 06:44
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 188
Регистрация: 26-04-07
Пользователь №: 27 334



Добрый день.
Я собираюсь программировать контроллер AT90S8515 в CodeVision.
Возник вопрос.
Можно ли создать массив с типом bit?
И обращаться к отдельным битам этого массива.

Я пробовал вот так
typedef struct {
char mybit:1;
} b;
b Bit[127];
…..

Bit[counter].mybit=PINA.0;

Но запись в память происходит, по типу char. Массив занимает много места.
Пожалуйста, плдскажите другие варианты.
Go to the top of the page
 
+Quote Post
VladimirYU
сообщение Sep 30 2008, 07:00
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 426
Регистрация: 5-04-07
Из: Санкт-Петербург
Пользователь №: 26 782



Цитата(zuuuuk @ Sep 30 2008, 10:44) *
Добрый день.
Я собираюсь программировать контроллер AT90S8515 в CodeVision.
Возник вопрос.
Можно ли создать массив с типом bit?
И обращаться к отдельным битам этого массива.

Я пробовал вот так
typedef struct {
char mybit:1;
} b;
b Bit[127];
…..

Bit[counter].mybit=PINA.0;

Но запись в память происходит, по типу char. Массив занимает много места.
Пожалуйста, плдскажите другие варианты.


Как вариант, посмотрите в сторону UNION, в купе с вашим вариантом, может быть поможет.
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Sep 30 2008, 07:05
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата(zuuuuk @ Sep 30 2008, 10:44) *
Добрый день.
Я собираюсь программировать контроллер 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_ - Sep 30 2008, 07:12
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Sep 30 2008, 07:08
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



примерно так:
Код
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);


Если с++ - можно обернуть это в класс с перегруженным оператором []
Go to the top of the page
 
+Quote Post
GDI
сообщение Sep 30 2008, 08:06
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



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


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
tag
сообщение Sep 30 2008, 08:09
Сообщение #6


Частый гость
**

Группа: Свой
Сообщений: 151
Регистрация: 21-02-06
Пользователь №: 14 561



Цитата(mempfis_ @ Sep 30 2008, 11:05) *
Так сохраняйте в структуре состояние всего порта (ну т.е. состояние его пинов)
а потом в программе анализируйте необходимый бит

Код
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 порта А
{
}
Go to the top of the page
 
+Quote Post
Ph. Anatoliy
сообщение Oct 1 2008, 11:15
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 14-12-07
Из: г. Таганрог, Ростовская обл.
Пользователь №: 33 310



Цитата(zuuuuk @ Sep 30 2008, 10:44) *
Добрый день.
Я собираюсь программировать контроллер 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[b] |= (0x80 >> i);
}

unsigned char get_bit_buffer (unsigned char value)
{
unsigned char b,i;

b = value/8;
i = value%8;

b = buffer[b];
b <<= i;
b &= 0x80;

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

Такой вариант будет экономить память, но нагружать АЛУ (соответсвенно - потери в скорости).
Go to the top of the page
 
+Quote Post
defunct
сообщение Oct 1 2008, 14:01
Сообщение #8


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Ph. Anatoliy @ Oct 1 2008, 14:15) *
Вот Вам, мой вариант:

b = value/8;
i = value%8;

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


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

b = value >> 3;
i = value & 0x7;
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 1 2008, 14:56
Сообщение #9


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Ph. Anatoliy @ Oct 1 2008, 14:15) *
Вот Вам, мой вариант:
#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)
}


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Ph. Anatoliy
сообщение Oct 1 2008, 15:21
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 14-12-07
Из: г. Таганрог, Ростовская обл.
Пользователь №: 33 310



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

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


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

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

b = value >> 3;
i = value & 0x7;

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

Сообщение отредактировал Ph. Anatoliy - Oct 1 2008, 15:25
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 1 2008, 16:14
Сообщение #11


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Ph. Anatoliy @ Oct 1 2008, 18:21) *
b = value >> 3;
i = value & 0x7;

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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Ph. Anatoliy
сообщение Oct 1 2008, 20:33
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 14-12-07
Из: г. Таганрог, Ростовская обл.
Пользователь №: 33 310



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

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

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

Сообщение отредактировал Ph. Anatoliy - Oct 1 2008, 20:37
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 5th July 2025 - 14:20
Рейтинг@Mail.ru


Страница сгенерированна за 0.01494 секунд с 7
ELECTRONIX ©2004-2016