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)
为了示范:
这里有两个用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)
记住两个真值表的提示如下:
0
并且你正在做a &
,那么结果将是0
(强制为0)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)
这可能更容易导致错误.
归档时间: |
|
查看次数: |
5522 次 |
最近记录: |