8bit variable and struct to represent a Register & its bits

Basically what i want is something along these lines
pseudo code

uint8_T = 8_bits_in_register ← this would be the variable that would hold the 8 bits for the register

struct ADMUX ← i know i cannot call it ADMUX but for the sake of making this easier to explain lets say its called admux
{
some_variable_type left_Adjust ;

some_variable_type ref_Voltage_Avcc ;

some_variable_type ref_Voltage_1v ;

};

then i would use it :
ADMUX.left_Adjust = true ;
ADMUX.ref_Voltage_1v = false ;
ADMUX.ref_Voltage_AVCC = true ;

and as i set these up they get appended to the 8 bit variable (which would be a binary number)
in the proper order so that when that variable is passed to the register all my setting match

so it would look like

8_bit_variable = 0b00101101 and i would pass that on to the real admux ,

is this feasible? or is there a more efficient way to write a generic way of setting up something such as ADC or PWM for that matter
basically use a structure to set all the bits in a port

I'm not sure if it is supported in the avr_gcc compiler but:

i just tried it and seems to work
the names bitZero - bitSeven would be changed to match the register bits such as MUX1 , MUX2, obviously i would have to change it since it cant literally match
and the structure name would be changed to something like ADCsetup …

now it would be ideal if i could initialize the fields to zero so i do not have to set each field to zero , but since this will be a generic reusable file for my self
ill have a function to initialize them all to zero
that way i only set the fields i am interested in

struct testReg
{
  int bitZero ;
  int bitOne ;
  int bitTwo ; 
  int bitThree;
  int bitFour;
  int bitFive;
  int bitSix;
  int bitSeven; 
  
  
  
};

struct  testReg  regEdit ; //structure that will represent a register and its settings

uint8_t myVar = 0;
void setup()
{
   Serial.begin(9600);
  DDRB |= 1<<PINB5 ; 
   
  
}

int doTheMath() 
// check each field of the structure and weather its true or false add that bit value to the uint8_t
{
    regEdit.bitZero < 1 ? myVar = 0 : myVar = 1 ; 
   regEdit.bitOne < 1 ? myVar = myVar : myVar +=2 ;
   regEdit.bitTwo < 1 ? myVar = myVar : myVar +=4 ;
   regEdit.bitThree < 1 ? myVar = myVar : myVar +=8 ;
   regEdit.bitFour < 1 ? myVar = myVar : myVar +=16 ;
   regEdit.bitFive < 1 ? myVar = myVar : myVar +=32 ;
   regEdit.bitSix < 1 ? myVar = myVar : myVar +=64 ;
   regEdit.bitSeven < 1 ? myVar = myVar : myVar +=128 ;
  return myVar;
}

void loop ()
{
 
   regEdit.bitZero = false ;
   regEdit.bitOne = false ; 
   regEdit.bitTwo =false  ; 
   regEdit.bitThree = false;
   regEdit.bitFour = false;
   //ive set only the 5th bit to true  , which i will pass to port B where bit 5 is the led on digital pin 13
   regEdit.bitFive = true ; 
   regEdit.bitSix = false ; 
   regEdit.bitSeven = false;
   
   PORTB ^= doTheMath();
   Serial.println(doTheMath());
   delay(50);
   
}

interesting i totally forgot about this
a quick sizeof showed me i went from 16 bytes to one bite on the size of the structure , how nice

Take a look at "union"s .

Mark

struct testReg

{
 int bitZero ;
 int bitOne ;
 int bitTwo ;
 int bitThree;
 int bitFour;
 int bitFive;
 int bitSix;
 int bitSeven;
};

Eeerm, no. That’s not how a bit field is made. You do it like this:

typedef struct {
  byte bitZero:1 ;
  byte bitOne:1 ;
  byte bitTwo:1 ; 
  byte bitThree:1;
  byte bitFour:1;
  byte bitFive:1;
  byte bitSix:1;
  byte bitSeven:1; 
} BitField;

Notice how there is a ‘:1’ at the end which specifies that each takes up only a single bit.

You can then do:

  volatile BitField* admux = (volatile BitField*)&ADMUX; //declare a BitField variable which is located at the address of ADMUX.
  admux->bitZero = 1; //equivalent to ADMUX |= _BV(0);

You could also define this type:

typedef union
  byte allBits;
  struct {
    byte bitZero:1 ;
    byte bitOne:1 ;
    byte bitTwo:1 ; 
    byte bitThree:1;
    byte bitFour:1;
    byte bitFive:1;
    byte bitSix:1;
    byte bitSeven:1; 
  };
} BitField;
...
//Allowing you to do this:
...
  volatile BitField* admux = (volatile BitField*)&ADMUX; //declare a BitField variable which is located at the address of ADMUX.
  admux->allBits = 0; //set all bits to 0.
  admux->bitZero = 1; //equivalent to ADMUX |= _BV(0);