以下C运算符如何组合

How does the following C operators combined

对于 EFR32FG14P231F256M32,我有以下 C 运算符组合。显示的描述 bellow.I 无法将描述与代码匹配。

但正在重新分级 | (1 << 5);我无法理解。

单行中这样的 C 运算符组合的逻辑含义是什么?

以下代码将端口 C 的引脚 5 配置为带上拉和滤波器的数字输入。来自 GPIO_PC_MODEL 的 MODE5 位域 寄存器必须设置为0b0011,GPIO_PC_DOUT寄存器中对应的位也必须设置为1来确定上拉 方向。可以使用 emlib 中可用的函数或直接写入寄存器来配置引脚:

GPIO->P[gpioPortC ].DOUT = GPIO->P[gpioPortC ].DOUT | (1 << 5); //Input enabled with pull up and filter
GPIO->P[gpioPortC ].MODEL = (GPIO->P[gpioPortC ].MODEL & ~_GPIO_P_MODEL_MODE5_MASK) |
GPIO_P_MODEL_MODE5_INPUTPULLFILTER;

<<运算符表示"shift bits left",其作用如下:

a << b

ab 位向左移动。 直接回答你的问题,1 << 5 将 0x01 中的位向左移动 5 次,结果是 0x20,即十进制表示法中的 32。这具有将数字乘以 2 n 次的效果(在您的情况下为 n=5)。结果值与 DOUT 中的值进行或运算,然后存储在 DOUT 本身中。

编辑: 回答 OP 在评论中添加的问题 -

您代码中的赋值与此类似:x = x + 5

-> 运算符对于 (*obj).field 是 shorthand。代码中的第一行指示如下:

  1. 取 ​​GPIO->P[gpioPortC].DOUT 内的值并与 0x10 进行或运算。
  2. 将结果赋给GPIO->P[gpioPortC].DOUT

第二行执行了一个非常相似的操作,只是不是执行按位或并将其存储在同一字段中,而是执行该字段的按位与与某个预定义值的取反形式,然后执行一个结果与另一个预定义值的按位或,然后将其存储在该字段中。

重要的是要理解,简单地在对象上使用 -> 运算符除了允许您访问存储在该对象中的字段(它们本身可能是指向内存中其他位置的指针,或原始变量)。

1 << 5 是具有二进制值 0b100000 的常量表达式。您可以简单地将其替换为文字常量值 0x20 或 32,但是该表达式的目的是创建一个设置了位 5 的 位掩码

这样表示是因为:

  • 它记录意图而无需写评论。它是自记录代码 - 它对 reader "this is a mask for bit 5",
  • 在编码的时候,让编译器计算5位掩码的常量值不容易出错。

所以:

x = x | ( 1 << 5) ;

设置变量的第 5 位(或在本例中 registerx。关于你的,也可以表示为:

x |= (1 <<5) ;

关于你的次要问题:

  • -> is a pointer. We have pointing directions on both sides?

我不清楚你在问什么,->但不是指针;它是 结构取消引用 运算符;它的左手操作数是一个指针,它的右手操作符是结构的成员,左手是一个指针 to (它可能是也可能不是指针。

在你问之前,你的片段的第二行有 形式:

x = x & ~mask ;

x 中所有在 mask 中为 1 的位设置为零。它是前一个成语的反转:

 x &= ~mask ;  // Clear mask bits
 x &= mask ;   // Set mask pits

在您的特定示例中,您有一个更复杂的表达式:

GPIO->P[gpioPortC].DOUT | (1 << 5)

这里需要理解operator precedence的概念。 -> 优先于 |,因此首先计算 GPIO->P[gpioPortC].DOUT 子表达式,以便 | (1 << 5); 应用于引用结构的 DOUT 成员。请注意,[] 也是一个运算符(优先级高于 ->。因此在一般形式中:

x | y ;

...

x =  GPIO->P[gpioPortC].DOUT 
y = (1 << 5)