Я пишу программу, которая проверяет набор проводов на обрыв или короткое замыкание. Программа, которая работает на 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 проводов, сравню, отобразлю результат и затем продвинусь вперед.