【问题标题】:Enumerations and bitwise operators with Registers带寄存器的枚举和按位运算符
【发布时间】:2018-04-20 15:12:25
【问题描述】:

我们都习惯了这种操作寄存器:

SomeRegister |= (1 << What_ever_bit_I_wanna_change ) // we do this for changing a specific bit to one without changing the others.

SomeRegister &= ~(1 << What_ever_bit_I_wanna_change ) // we do this for changing a specific bit to zero without changing the others.

我打算使用相同的范例,但使用枚举,如下所示:

typedef enum  {
Acc_2g  (Something to change only the desired bits in the related register that I don't know how to do),
Acc_4g (Something to change only the desired bits in the related register that I don't know how to do)
}Res;

知道如何在枚举中使用位运算符吗?

【问题讨论】:

  • 您可以为枚举符号赋值,例如enum {x=(1&lt;&lt;3), y=(1&lt;&lt;4), ...} 如果这就是你要问的。
  • 您知道可以将枚举值初始化为任何整数吗?就像例如Acc_2g = 4?您可以使用任何编译时常量表达式进行初始化,例如Acc_2g = 1 &lt;&lt; 2。 A good beginners book 应该告诉你的。

标签: c embedded


【解决方案1】:

枚举只是一组整数常量,它们不能在运行时对数据进行操作。例如,虽然您可以定义:

typedef enum  
{
    Acc_2g = 1 << 2,
    Acc_4g = 1 << 4
} Res ;

这不会“更改”问题中要求的任何位。您仍然必须使用相同的成语:

SomeRegister |= Acc_2g ;
SomeRegister &= ~(Acc_4g) ;  

您可能需要的是一个带有位域的结构。但是请注意,如果目的是访问某些硬件寄存器中的特定位,您将需要查阅编译器的文档,了解它如何根据位顺序和填充来打包位字段 - 这些事情取决于实现/目标,但是这个当寄存器也是特定于目标时,不一定要避免。

例如,对于一些假设的 8 位寄存器:

typedef union
{
    uint8_t byte;

    struct
    {
         uint8_t bit012 : 3;
         uint8_t bit34  : 2;
         uint8_t bit5   : 1;
         uint8_t bit6   : 1;
         uint8_t bit7   : 1;
    } bits ;

} registerType;

那么这个类型可以用来创建一个指向寄存器的指针:

registerType *pReg = (registerType*)0x00008000;

寄存器可以作为位域访问:

pReg->bits.bit5 = 1;
pReg->bits.bit012 = 7;

或者作为一个完整的寄存器:

pReg->byte = 0x55;

例如,可以通过为单个外设的所有寄存器定义一个结构来更进一步。

【讨论】:

  • 而在 C11 中,您可以使用匿名内部结构(例如,从定义中删除 bits),然后您可以使用 pReg-&gt;bit5 = 0;。另请注意,该标准并未指定 bit012 将位于保存它的存储单元的最高有效端还是最低有效端。
  • @chux :我想我做到了:“请查阅编译器的文档,了解它如何根据位顺序和填充来打包位字段”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-28
  • 2023-03-14
  • 1970-01-01
相关资源
最近更新 更多