Эффективное нахождение положения единиц в битовом массиве

Я подключаю программу, которая проверяет набор проводов на обрыв или короткое замыкание. Программа, работающая на AVR, запускает тестовый вектор (ходящую «1») по проводам и возвращает результат. Он сравнивает этот результирующий вектор с ожидаемыми данными, которые уже сохранены на SD-карте или внешней EEPROM.

Вот пример, предположим, что у нас есть набор из 8 проводов, все из которых являются прямыми, т.е. у них нет соединений. Итак, если мы вбиваем 0b00000010, мы должны получить 0b00000010.

Допустим, мы получили 0b11000010. Это подразумевает короткое замыкание между проводом 7,8 и проводом 2. Я могу определить, какие биты меня интересуют, с помощью 0b00000010 ^ 0b11000010 = 0b11000000. Это ясно говорит мне, что провода 7 и 8 виноваты, но как мне найти положение этих единиц в большом битовом массиве. Это легко сделать всего для 8 проводов с использованием битовых масок, но разрабатываемая мной система должна обрабатывать до 300 проводов (бит). Прежде чем я начал использовать макросы, подобные приведенным ниже, и тестировать каждый бит в массиве размером 300 * 300 бит, я хотел спросить здесь, есть ли более элегантное решение.

 #define BITMASK(b) (1 << ((b) % 8))
 #define BITSLOT(b) ((b / 8))
 #define BITSET(a, b) ((a)[BITSLOT(b)] |= BITMASK(b))
 #define BITCLEAR(a,b) ((a)[BITSLOT(b)] &= ~BITMASK(b))
 #define BITTEST(a,b) ((a)[BITSLOT(b)] & BITMASK(b))
 #define BITNSLOTS(nb) ((nb + 8 - 1) / 8)

Просто чтобы показать, как обнаружить обрыв цепи. Ожидаемые данные: 0b00000010, полученные данные: 0b00000000 (провод не натянут). 0b00000010 ^ 0b00000000 = 0b0b00000010 - провод 2 открыт.

ПРИМЕЧАНИЕ. Я знаю, что тестирование 300 проводов - это не то, с чем может справиться крошечная оперативная память внутри AVR Mega 1281, поэтому я разделю это на группы, то есть протестирую 50 проводов, сравните, отобразите результат и затем продолжу.

5
задан saad 15 February 2012 в 15:21
поделиться