使用“& =〜(1<< PINXX)”重置引脚

时间:2015-05-22 13:56:41

标签: avr

健康警告:初学者总数

为什么这是重置引脚的标准方法:

REGISTER_NAME& =〜(1<<< PINXX);

而不是直截了当:

REGISTER_NAME& =(0<< PINXX);

提前感谢时间,答案&书目提示

5 个答案:

答案 0 :(得分:2)

需要了解每个符号在

中的含义
REGISTER_NAME &= ~(1 << PINXX);

1)&lt;&lt; - 这是合乎逻辑的左移。这意味着左侧的数字向右移动了二进制位置的数字,这位于右侧。

例如。 1&lt;&lt; 5 表示 0b00000001 左移5次(右边出现零)。即结果将 0b00100000 == 32。

换句话说, 1&lt;&lt; X 表示“给出一个数字,其中只有#X位设置,其他位为零”

确定。此时,您可以看到 0&lt;&lt;任何总是为零,

2) - 这是按位否定。它以二进制表示的数字反转每个位置的每个位的值。

即。 ~0b00100000 (或〜(1 <&lt; 5))== 0b11011111

结论,〜(1&lt;&lt; X)表示“给出一个数字,其中所有位都被设置,除了#X位,它将变为零”

3)&amp; = - 这是与按位AND结合的赋值。即 X&amp; = Y X = X&amp; ÿ;

4)&amp; - 这是按位AND。该操作的结果是数字,其中仅设置那些在两个操作数中设置在相同位置的位,否则为零。

这意味着,如果设置了一个操作数中的特定位,则结果中的相同位将等于另一个操作数的相同位的位。如果任一操作数中该位为零,则结果中的相同位将为零。

你可以用这种方式改写 X&amp; = Y :“如果Y中的位是1,则将X中的位保持不变(无论它是什么 - 一个或零)如果Y中的位为零,则清除X中的相同位。“

如上所述,除了N之外,〜(1 给出了设置每个比特的数字。所以 X&amp; =〜(1&lt; 1&lt; 1&lt; 1&gt; &lt; N)表示“清除位#N,并保持所有其他位不变”。

现在你可以看到,

REGISTER_NAME &= (0 << PINXX); 

是无稽之谈,因为它意味着“清除所有位”。它与 REGISTER_NAME = 0;

相同

顺便说一下,如果您使用此表单中的作业:

REGISTER_NAME | =(0&lt;&lt;&lt; PINXX)| (1&lt;&lt; PINYY);

这并不意味着“设置位PINYY,清除位PINXX”,这意味着“设置位PINYY并且不会对位PINXX执行任何操作(与所有其他位一样)”

答案 1 :(得分:0)

第一条指令将复位引脚XX,第二条指令将复位与该寄存器相关的所有引脚

答案 2 :(得分:0)

为什么将零转移更“直截了当”?这完全没有意义,它只是0,当按位时会清除整个寄存器。根本不是你想要的。

请记住:

REGISTER &= ~(1 << PIN);

装置

REGISTER = REGISTER & ~(1 << PIN);

即。它将按位 - 并且寄存器的常量在除了位号PIN之外的所有位置都有1。特别是~运算符适用于移位的值,而不仅仅适用于1

这具有将该位设置为0而不触及任何其他位的效果。正是你想要的,这当然是为什么它是你总是看到的代码。 :)

答案 3 :(得分:0)

我认为之所以会出现混乱,是因为您已经对&#34;标准&#34;中的内容进行了不准确的描述。方式。

我怀疑当你这样做时,你被告知:

REGISTER_NAME &= ~(1 << PINXX);

它意味着&#34;逻辑地将PINXX的引脚与~1对齐,即0&#34;。

但这并不意味着。实际意味着什么取决于寄存器的大小。我假设它是16位,PINXX是8。

然后标准方式实际上是:

REGISTER_NAME &= ~(1 << 8)

或(假设您的编译器接受0b二进制数)

REGISTER_NAME &= ~(0b0000000100000000)

REGISTER_NAME &= 0b1111111011111111

也就是说,命令不仅仅在一个引脚上运行 - 它在所有引脚上运行。 (除了要更改的引脚之外的所有内容的操作都是&#34;逻辑上与1&#34;并且这意味着它保持不变)。表达式~(1 << PINXX)只是一种构建一个数字的方法,该数字是您 想要触摸的地方的所有1,而{{0 1}}你在现场。

您建议的&#34;更简单&#34;版本将相当于:

REGISTER_NAME &= 0b0000000000000000

这会重置该寄存器控制的所有引脚。

答案 4 :(得分:0)

设置一点,你variable |= (1 << position)。这将生成类似0000100的内容,假设为position = 2 若要取消设置,请执行相反的操作:AND而不是OR,并且掩码与另一个相反。

假设position = 2,

  1. 1 << position00000100和以前一样。
  2. 按位而不是{~):11111011
  3. 按位AND应用。例如,如果它是`11011100,则得到:

    11011100 &
       11111011 =
       -----------
       11011000
       _____^____

  4. 为了达到目的,我假设了8位值,但程序没有随着宽度更长而改变。第一次看起来有点困难但是,如果你自己做微积分,它背后的逻辑应该出现;毕竟,这是数学。​​