[RISOLTO]passare un bitfield alla funzione shiftout

Ciao, dovrei passare un bitfield (struct dove le singole variabili hanno dimensioni in bit) alla funzione shiftout. Il compilatore mi genera errori vari. Ho provato a creare una struct con 8 elementi da 1 bit ciascuno usando:

struct tipostruct {

 uint8_t uno:1;
 uint8_t due:1;
 "       "      "
 "       "      "
 uint8_t otto:1;

} pippo;

void shiftout(uint8_t value) {

 uint8_t i;

 for(i=0;i<8;i++) {

  digitalWrite(npin, !!(value & (1 << (7-i))));

 }
}

Poi a creare una variabile puntatore ed inserirci l’indirizzo della struct per poi passare alla shiftout il puntatore anzi che la variabile però il compilatore si accorge che all’interno della shiftout lavora come unsigned char e il puntatore che gli passo invece lavora come struct di unsigned char.

Qualcuno conosce un trucco o una altra via per imbrogliare il compilatore? :cold_sweat:

Stranamente il C o C++ non permette di ricavare un puntatore a stuct bitfield, quindi il seguente codice non dovrebbe funzionare:

struct tipostruct {

 uint8_t uno:1;
 uint8_t due:1;
 "       "      "
 "       "      "
 uint8_t otto:1;

} pippo;

void shiftout(struct tipostruct *ptr_bitfield) {
    ptr_bitfield->uno = 0;
}

// call 
shiftout(&pippo);

Se pippo è globale la puoi usare, se devi usarla in un modulo in cui non è dichiarata la devi dichiarare extern struct tipostruct pippo;
e poi la puoi usare, ma stiamo parlando di C modulare e non di arduino e non so come funzionano i moduli.

Sono comode la bitfield ma non poterne passare il puntatore ad una funzione è troppo limitante, per questo evito di usarle e al loro
posto uso una variabile sotto typedef es;
typedef uint32_t bit_state_flags;
bit_state_flags global_state;

poi crei delle macro per manipolare i singoli bit e ritornarne lo stato.
Di global_state puoi ricaverne il puntatore con & e puoi dichiarare puntatori con bit_state_flags *st;

Notte;

mmm però all’interno di shiftout avrei bisogno di lavorare con la bitfield come se fosse una normale unsigned char per usare questo codice:

uint8_t i;

 for(i=0;i<8;i++) {

  digitalWrite(npin, !!(value & (1 << (7-i))));

Diciamo che non mi importa se passo come variabile o puntatore, ma all’interno di questa funzione devo lavorare come se fosse una uint8_t.

Devi usare una union al cui interno inserisci la struttura e la variabile unsigned char che utilizzerai per per la digitalwrite.

andrea86:
Il compilatore mi genera errori vari. Ho provato a creare una struct con 8 elementi da 1 bit ciascuno usando:

Strano, a me compila senza errori (neppure warning con il verbose):

struct tipostruct {
 uint8_t f1:1;
 uint8_t f2:1;
 uint8_t f3:1;
 uint8_t f4:1;
 uint8_t f5:1;
 uint8_t f6:1;
 uint8_t f7:1;
 uint8_t f8:1;
} pippo;

void myshiftout(struct tipostruct *ptr_bitfield) {
    ptr_bitfield->f1 = 0;
}

void setup()
{ myshiftout(&pippo);
}

void loop()
{}

@nid69ita: gli errori li dava con il mio codice.

Ho risolto come diceva astro. Ammetto di aver letto delle union però non ne avevo capito dell’utilità.

union {
  
  struct {
    
      uint8_t uno:1;
      uint8_t due:1;
      uint8_t tre:1;
      uint8_t qua:1;
      uint8_t cin:1;
      uint8_t sei:1;
      uint8_t set:1;
      uint8_t ott:1;
      
  } pippo;
  
  uint8_t pluto;

} topolino;

void myshift() {
  
  for(uint8_t i=0; i< 8; i++) {
    
    digitalWrite(13, !!(topolino.pluto & (1 << (7 - i))));
  }
  
  digitalWrite(13, LOW);
}

void setup() {
  
  pinMode(13, OUTPUT);
  
  topolino.pippo.uno = 1;
  topolino.pippo.tre = 1;
  topolino.pippo.cin = 1;
  topolino.pippo.sei = 1;
  topolino.pippo.set = 1;
  topolino.pippo.ott = 1;
}

// the loop routine runs over and over again forever:
void loop() {
  
  myshift();
  
  delay(1000);
  
}