1

We are all used to this kind of manipulating registers:

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.

I am planning to use the same paradigm, but with enumerations, something like this:

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;

Any idea how to use the bitwise operators inside the enumeration?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Eng_Mike
  • 13
  • 3
  • You can assign values to enumeration symbols, e.g. `enum {x=(1<<3), y=(1<<4), ...}` if that's what you're asking. – Tom Karzes Nov 08 '17 at 03:34
  • You do know that you can initialize an enumeration value to any integer? Like e.g. `Acc_2g = 4`? You can use any compile-time constant expression for the initialization, like e.g. `Acc_2g = 1 << 2`. [A good beginners book](http://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list) should have told you that. – Some programmer dude Nov 08 '17 at 03:34

1 Answers1

2

An enum is merely a set of integer constants, they cannot cause actions on data at run-time. So for example while you can define:

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

This does not "change" any bits as requested in the question. You still have to use the same idiom:

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

What you probably need is a struct with bit-fields. Note however that if the intent is to access specific bits in some hardware register, you will need to consult your compiler's documentation on how it it packs bit-fields with respect to bit order and padding - such things are implementation/target dependent, but this need not necessarily be avoided when the the register is also target specific.

For example, for some hypothetical 8 bit register:

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;

Then this type can be used to create a pointer to the register:

registerType *pReg = (registerType*)0x00008000;

The the register may be accessed as bit-fields:

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

Or as an entire register:

pReg->byte = 0x55;

One can go further by defining a structure for all registers of a single peripheral for example.

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • 1
    And in C11, you could use an anonymous inner struct (drop `bits` from the definition), and then you could use `pReg->bit5 = 0;`, for example. Also note that the standard does not specify whether `bit012` will be at the most significant or least significant end of the storage unit that holds it. – Jonathan Leffler Nov 08 '17 at 04:13
  • @chux : I think I did: *"consult your compiler's documentation on how it it packs bit-fields with respect to bit order and padding"*. – Clifford Nov 08 '17 at 04:18