|
|
  |
как создать массив из bit?, CodeVision |
|
|
|
Sep 30 2008, 07:00
|
Местный
  
Группа: Свой
Сообщений: 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, в купе с вашим вариантом, может быть поможет.
|
|
|
|
|
Sep 30 2008, 07:05
|

Профессионал
    
Группа: Свой
Сообщений: 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
|
|
|
|
|
Sep 30 2008, 07:08
|
Знающий
   
Группа: Свой
Сообщений: 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); Если с++ - можно обернуть это в класс с перегруженным оператором []
|
|
|
|
|
Sep 30 2008, 08:09
|
Частый гость
 
Группа: Свой
Сообщений: 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 порта А { }
|
|
|
|
|
Oct 1 2008, 11:15
|
Участник

Группа: Участник
Сообщений: 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; } Такой вариант будет экономить память, но нагружать АЛУ (соответсвенно - потери в скорости).
|
|
|
|
|
Oct 1 2008, 14:56
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Oct 1 2008, 15:21
|
Участник

Группа: Участник
Сообщений: 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
|
|
|
|
|
Oct 1 2008, 20:33
|
Участник

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

|
Сергей Борщ - Спасибо за анализ ....
Опять таки вопрос оптимизации...
А спрашивали "как организовать битовый массив" а не "как оптимально написать код" =)
Сообщение отредактировал Ph. Anatoliy - Oct 1 2008, 20:37
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|