我正在接线一个程序,该程序测试一组导线是否断路或短路。该程序在AVR上运行,将测试 vector (走“1”)驱动到导线上,并将结果返回。它将所得的 vector 与已存储在SD卡或外部EEPROM中的预期数据进行比较。

这是一个示例,假设我们有8条线的集合,所有这些线都是直通的,即它们没有结。因此,如果我们驱动0b00000010,我们应该收到0b00000010。

假设我们收到0b11000010。这意味着电线7,8和电线2之间存在短路。通过0b00000010 ^ 0b11000010 = 0b11000000,我可以检测到我感兴趣的位。这清楚地告诉我,导线7和8出现故障,但是如何在大型位阵列中有效地找到这些'1'的位置。使用位掩码仅用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内部微小的RAM可以处理的,这就是为什么我将其分成几组的原因,即测试50根线,比较,显示结果然后继续前进。

最佳答案

许多体系结构提供了用于在字中定位第一个置位或计数置位位数的特定指令。编译器通常为这些操作提供内部函数,因此您不必编写内联汇编。例如,GCC提供了__builtin_ffs__builtin_ctz__builtin_popcount等,它们中的每一个都应利用位级并行性映射到目标体系结构上的相应指令。

如果目标体系结构不支持这些,则编译器将发出有效的软件实现。在软件中一点一点地测试 vector 的幼稚方法不是很有效。

如果您的编译器没有实现这些,您仍然可以使用de Bruijn sequence编写自己的实现。

关于c - 在位数组中高效查找 '1'的位置,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9295938/

10-11 07:23