嵌入式C程序中的高效位检查

时间:2015-06-25 15:37:18

标签: embedded avr

我正在使用AVR控制器atmega328。 我需要检查两位的状态。我有两种方法,但不确定哪种方法效率最高。在下面的代码中的第一种情况下,我使用PIND命令两次读取端口(两次PIND访问)。这是一个问题,还是我必须使用第二个if语句?

#define SW1 2
#define SW2 5
//check if both are high
if((PIND&(1<<SW1))&&(PIND&(1<<SW2))) 
//Or
if((PIND&((1<<SW1)|(1<<SW2)))==((1<<SW1)|(1<<SW2))) 

3 个答案:

答案 0 :(得分:5)

I suppose PIND is a peripheral register (what do you mean by "command"?). The first check will read it once or twice, depending on the first comparison. This might generate a glitch, if SW1 changes between the first and second read. Presuming SW? are switches: In general, it is better to read such a register once (possibly to a variable) and test for the bits. That ensures you get a snapshot of all input bits at the same time. Also, the seconde version is not necessarily slower, as it safes a branch (IIRC AVR has no conditional instructions other than branch/jump).

答案 1 :(得分:3)

第一次读取PIND两次因此效率较低且可能出错 - 如果中断或线程上下文切换介入,则读取之间的时间可能很长。

第二个评估(1<<SW1)|(1<<SW2)两次,但在这种情况下它是一个编译时常量,所以应该对性能没有影响。但说实话,你可能会让那些担心这个级别的代码的小东西大汗淋漓。如果你真的需要知道;看看编译器生成的代码(在调试器反汇编中或通过让编译器输出汇编列表),但是如果你打算再次猜测每一行,那么编写代码需要很长时间,

答案 2 :(得分:1)

如果没有汇编程序的输出,很难说上面哪两个会更有效率。但是,我猜测性能差异很小。

在第2种情况下,您要避免两次读取寄存器,但是您正在执行2次额外操作。

如果我猜测,我会说选项1最有可能更快,因为PIND是一个AVR注册人,阅读成本会更低。

话虽如此,我建议使用第一个选项,因为它的可读性更高,即使它没有被发现比选项2更快。