AVR按位C操作

Dov*_*das 2 c gcc avr bit-manipulation

我对Atmel Studio 6.1中的ATMEGA328P编程有疑问.

将二进制文件分配给寄存器比进行移位操作更快吗?

如果我理解正确,但请更正此!!

让我们说:

DDRC = 0b11001100;
Run Code Online (Sandbox Code Playgroud)

我必须在进行按位操作之前检查初始位条件,然后才能将任何位置移位到位置?例如

DDRC |= (1<<DDRC0);
Run Code Online (Sandbox Code Playgroud)

我们得到:

11001100
10011001
Run Code Online (Sandbox Code Playgroud)

=

11011101
Run Code Online (Sandbox Code Playgroud)

这样对吗?如果我们知道一点点组合简单地写,也许它更快更简单?:

0b11001101
Run Code Online (Sandbox Code Playgroud)

zmo*_*zmo 6

为了示范:

这里有两个用avr-gcc-4.7.2编译的代码:

void main() {
    DDRC |= (1<<5);
}

and another:

void main() {
    DDRC |= 0b100000;
}

 % diff -s t2.s t.s
Files t2.s and t.s are identical
Run Code Online (Sandbox Code Playgroud)

这是因为1<<N在编译时检测到,并转换为其常量等效,使得两个表达式在发送到微控制器时都相同.

关于运营,请看一下真值表:

| a b -> a&b |        | a b -> a|b |
| 0 0    0   |        | 0 0    0   |
| 0 1    0   |        | 0 1    1   |
| 1 0    0   |        | 1 0    1   |
| 1 1    1   |        | 1 1    1   |
Run Code Online (Sandbox Code Playgroud)

记住两个真值表的提示如下:

  • 如果其中一个操作数是a 0并且你正在做a &,那么结果将是0 (强制为0)
  • 如果其中一个操作数是a 1并且你正在做a |,那么结果将是1 (强制为1)

所以如果你举一个例子有点复杂:

101010 | 010101 = 111111
101010 & 010101 = 000000
Run Code Online (Sandbox Code Playgroud)

最后,当你想设置一点:

REGISTER = 00000001
REGISTER |= 1<<5      <=> REGISTER = 00000001 | 00100000
REGISTER == 00100001
Run Code Online (Sandbox Code Playgroud)

如果你想重置那个位:

REGISTER &= ~(1<<5)   <=> REGISTER = 00100001 & ~(00100000)  <=> REGISTER = 00100001 & 11011111
REGISTER == 00000001
Run Code Online (Sandbox Code Playgroud)

我希望它更有意义......虽然你最好查找一个关于组合逻辑的课程,这是在进行嵌入式编程时完美处理的基础.

现在回答你的问题:

如果我们知道一点点组合简单地写,也许它更快更简单?:

它不一定更快,也不是更简单.

考虑以下组成的寄存器FOO:

  7   6   5   4   3   2   1   0
[ A | B | C | D | W | X | Y | Z ]
Run Code Online (Sandbox Code Playgroud)

现在考虑我们已经构建了一个具有正确值的预处理器变量的头:

FOOZ = 0
FOOY = 1
FOOX = 2
FOOW = 3
FOOD = 4
FOOC = 5
FOOB = 6
FOOA = 7
Run Code Online (Sandbox Code Playgroud)

现在我们需要设置A,C和"X"位,这可以如下进行:

FOO |= 1<<FOOA | 1<<FOOC | 1<<FOOX
Run Code Online (Sandbox Code Playgroud)

代替:

FOO |= 0b10100100
Run Code Online (Sandbox Code Playgroud)

这可能更容易导致错误.