Come usare gli operatori per manipolare i bit
Lavorare con i microcontrollori, incluso Arduino, è divenuto abbastanza semplice grazie all’impiego di linguaggi ad alto livello che permettono di imparare in modo semplice e veloce la programmazione di questi device. Nonostante l’uso di funzioni che gestiscono variabili complesse, molte volte si ha la necessità di gestire i singoli bit. Arduino implementa dei metodi per accedere direttamente ai bit di una variabile e di poterne leggerne e cambiare il valore.
I bit è l’unità più piccola capace di esprimere un informazione (valori 1 e 0). L’unione di più bit forma altre unità come il byte (composto da 8 bit). Il byte è stato il primo sistema per codificare un carattere ed è capace di esprimere 256 valori (2^8 = 256).
Per accedere ai singoli bit che compongono il byte possiamo usare le funzioni seguenti:
Leggere un singolo bit
Per leggere il valore di un singoli bit usiamo la funzione bitRead(Val, Posizione); dove Val è il valore della variabile e Posizione è il numero del bit da leggere, con indice zero. Eccovi alcuni esempi di utilizzo
[c]
byte Data = 0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
Data = 0; //in binario 00000000
Serial.print(“Valore in bit della variabile Data(“);
Serial.print(Data);
Serial.println(“):”);
Serial.print(bitRead(Data, 0)); //bit meno significativo
Serial.print(bitRead(Data, 1));
Serial.print(bitRead(Data, 2));
Serial.print(bitRead(Data, 3));
Serial.print(bitRead(Data, 4));
Serial.print(bitRead(Data, 5));
Serial.print(bitRead(Data, 6));
Serial.print(bitRead(Data, 7)); //bit più significativo
Serial.println();
delay(1000);
Data = 255; //in binario 11111111
Serial.print(“Valore in bit della variabile Data(“);
Serial.print(Data);
Serial.println(“):”);
Serial.print(bitRead(Data, 0)); //bit meno significativo
Serial.print(bitRead(Data, 1));
Serial.print(bitRead(Data, 2));
Serial.print(bitRead(Data, 3));
Serial.print(bitRead(Data, 4));
Serial.print(bitRead(Data, 5));
Serial.print(bitRead(Data, 6));
Serial.print(bitRead(Data, 7)); //bit più significativo
Serial.println();
delay(1000);
Data = 127; //in binario 11111110
Serial.print(“Valore in bit della variabile Data(“);
Serial.print(Data);
Serial.println(“):”);
Serial.print(bitRead(Data, 0)); //bit meno significativo
Serial.print(bitRead(Data, 1));
Serial.print(bitRead(Data, 2));
Serial.print(bitRead(Data, 3));
Serial.print(bitRead(Data, 4));
Serial.print(bitRead(Data, 5));
Serial.print(bitRead(Data, 6));
Serial.print(bitRead(Data, 7)); //bit più significativo
Serial.println();
delay(1000);
}
[/c]
Settare un bit
La funzione che permette di mettere a 1 un singolo bit è la seguente bitSet(Val, Posizione); dove Val esprime il valore del byte e Posizione è l’indice del bit da settare.
[c]
byte Data = 0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
Data = 0; //in binario 00000000
Serial.print(“Valore in bit della variabile Data(“);
Serial.print(Data);
Serial.println(“):”);
Serial.print(bitRead(Data, 0)); //bit meno significativo
Serial.print(bitRead(Data, 1));
Serial.print(bitRead(Data, 2));
Serial.print(bitRead(Data, 3));
Serial.print(bitRead(Data, 4));
Serial.print(bitRead(Data, 5));
Serial.print(bitRead(Data, 6));
Serial.print(bitRead(Data, 7)); //bit più significativo
Serial.println();
delay(2000);
//setta il bit 0
bitSet(Data, 0);
//visualizza il valore di Data
Serial.print(“Valore in bit della variabile Data(“);
Serial.print(Data);
Serial.println(“):”);
Serial.print(bitRead(Data, 0)); //bit meno significativo
Serial.print(bitRead(Data, 1));
Serial.print(bitRead(Data, 2));
Serial.print(bitRead(Data, 3));
Serial.print(bitRead(Data, 4));
Serial.print(bitRead(Data, 5));
Serial.print(bitRead(Data, 6));
Serial.print(bitRead(Data, 7)); //bit più significativo
Serial.println();
delay(2000);
//setta il bit 7
bitSet(Data, 7);
//visualizza il valore di Data
Serial.print(“Valore in bit della variabile Data(“);
Serial.print(Data);
Serial.println(“):”);
Serial.print(bitRead(Data, 0)); //bit meno significativo
Serial.print(bitRead(Data, 1));
Serial.print(bitRead(Data, 2));
Serial.print(bitRead(Data, 3));
Serial.print(bitRead(Data, 4));
Serial.print(bitRead(Data, 5));
Serial.print(bitRead(Data, 6));
Serial.print(bitRead(Data, 7)); //bit più significativo
Serial.println();
delay(2000);
}
[/c]
Resettare un bit
la funzione che invece permette di mettere a zero un singolo bit è la seguente bitClear(Val, Posizione); dove Val è il solito valore in byte e Posizione rappresenta l’indice del bit da settare a 0.
[c]
byte Data = 0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
Data = 255; //in binario 11111111
Serial.print(“Valore in bit della variabile Data(“);
Serial.print(Data);
Serial.println(“):”);
Serial.print(bitRead(Data, 0)); //bit meno significativo
Serial.print(bitRead(Data, 1));
Serial.print(bitRead(Data, 2));
Serial.print(bitRead(Data, 3));
Serial.print(bitRead(Data, 4));
Serial.print(bitRead(Data, 5));
Serial.print(bitRead(Data, 6));
Serial.print(bitRead(Data, 7)); //bit più significativo
Serial.println();
delay(2000);
//resetta il bit 0
bitClear(Data, 0);
//visualizza il valore di Data
Serial.print(“Valore in bit della variabile Data(“);
Serial.print(Data);
Serial.println(“):”);
Serial.print(bitRead(Data, 0)); //bit meno significativo
Serial.print(bitRead(Data, 1));
Serial.print(bitRead(Data, 2));
Serial.print(bitRead(Data, 3));
Serial.print(bitRead(Data, 4));
Serial.print(bitRead(Data, 5));
Serial.print(bitRead(Data, 6));
Serial.print(bitRead(Data, 7)); //bit più significativo
Serial.println();
delay(2000);
//resetta il bit 5
bitClear(Data, 5);
//visualizza il valore di Data
Serial.print(“Valore in bit della variabile Data(“);
Serial.print(Data);
Serial.println(“):”);
Serial.print(bitRead(Data, 0)); //bit meno significativo
Serial.print(bitRead(Data, 1));
Serial.print(bitRead(Data, 2));
Serial.print(bitRead(Data, 3));
Serial.print(bitRead(Data, 4));
Serial.print(bitRead(Data, 5));
Serial.print(bitRead(Data, 6));
Serial.print(bitRead(Data, 7)); //bit più significativo
Serial.println();
delay(2000);
}
[/c]
Settare o resettare con la stessa funzione
Esiste una funzione capace di eseguire sia le operazione di settaggio dei bit sia le operazioni di reset, il suo prototipo è bitWrite(Val, Posizione, ValBit); dove Val è il byte che vogliamo modificare, Posizioe rappresenta l’indice del bit da modificare e ValBit è il valore del bit (1 0 0)
[c]
byte Data = 0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
Data = 255; //in binario 11111111
Serial.print(“Valore in bit della variabile Data(“);
Serial.print(Data);
Serial.println(“):”);
Serial.print(bitRead(Data, 0)); //bit meno significativo
Serial.print(bitRead(Data, 1));
Serial.print(bitRead(Data, 2));
Serial.print(bitRead(Data, 3));
Serial.print(bitRead(Data, 4));
Serial.print(bitRead(Data, 5));
Serial.print(bitRead(Data, 6));
Serial.print(bitRead(Data, 7)); //bit più significativo
Serial.println();
delay(2000);
//resetta il bit 0
bitWrite(Data, 0, 0);
//resetta il bit 3
bitWrite(Data, 2, 0);
//visualizza il valore di Data
Serial.print(“Valore in bit della variabile Data(“);
Serial.print(Data);
Serial.println(“):”);
Serial.print(bitRead(Data, 0)); //bit meno significativo
Serial.print(bitRead(Data, 1));
Serial.print(bitRead(Data, 2));
Serial.print(bitRead(Data, 3));
Serial.print(bitRead(Data, 4));
Serial.print(bitRead(Data, 5));
Serial.print(bitRead(Data, 6));
Serial.print(bitRead(Data, 7)); //bit più significativo
Serial.println();
delay(2000);
//setta il bit 1
bitWrite(Data, 0, 0);
//setta il bit 3
bitWrite(Data, 2, 1);
//resetta il bit 5
bitWrite(Data, 4, 0);
//visualizza il valore di Data
Serial.print(“Valore in bit della variabile Data(“);
Serial.print(Data);
Serial.println(“):”);
Serial.print(bitRead(Data, 0)); //bit meno significativo
Serial.print(bitRead(Data, 1));
Serial.print(bitRead(Data, 2));
Serial.print(bitRead(Data, 3));
Serial.print(bitRead(Data, 4));
Serial.print(bitRead(Data, 5));
Serial.print(bitRead(Data, 6));
Serial.print(bitRead(Data, 7)); //bit più significativo
Serial.println();
delay(2000);
}
[/c]
La funzione bit();
La funzione bit(x); ci permette di calcolare il valore decimale del bit specificato, l’esempio chiarisce meglio il concetto
[c]
void setup()
{
Serial.begin(9600);
}
void loop()
{
//valori decimali dei singoli bit
Serial.println(bit(0)); 2^0 = 1
Serial.println(bit(1)); 2^1 = 2
Serial.println(bit(2)); 2^2 = 4
Serial.println(bit(3)); 2^3 = 8
Serial.println(bit(4)); 2^4 = 16
Serial.println(bit(5)); 2^5 = 32
Serial.println(bit(6)); 2^6 = 64
Serial.println(bit(7)); 2^7 = 128
Serial.println();
delay(2000);
}
[/c]
Negli esempi è stato analizzato il singolo byte ma è possibile lavorare anche con gli altri tipi. Ad esempio possiamo effettuare delle operazioni su una variabile unsigned int (composta da 16 bit (2^16)-1 da 0 a 65535)
[c]
unsigned int Data = 65535;
void setup()
{
Serial.begin(9600);
}
void loop()
{
//valore decimale del bit 12
Serial.print(“valore decimale del bit 12 “);
Serial.print(bit(12)); // 2^12 = 4096
Serial.println();
Data = 65535;
//visualizza il valore di Data
Serial.print(“Valore in bit della variabile Data(“);
Serial.print(Data);
Serial.println(“):”);
Serial.print(bitRead(Data, 0)); //bit meno significativo
Serial.print(bitRead(Data, 1));
Serial.print(bitRead(Data, 2));
Serial.print(bitRead(Data, 3));
Serial.print(bitRead(Data, 4));
Serial.print(bitRead(Data, 5));
Serial.print(bitRead(Data, 6));
Serial.print(bitRead(Data, 7));
Serial.print(bitRead(Data, 8));
Serial.print(bitRead(Data, 9));
Serial.print(bitRead(Data, 10));
Serial.print(bitRead(Data, 11));
Serial.print(bitRead(Data, 12));
Serial.print(bitRead(Data, 13));
Serial.print(bitRead(Data, 14));
Serial.print(bitRead(Data, 15)); //bit più significativo
Serial.println();
delay(2000);
//setta il bit 1
bitWrite(Data, 0, 0);
//resetta il bit 3
bitWrite(Data, 10, 0);
//resetta il bit 5
bitWrite(Data, 15, 0);
//visualizza il valore di Data
Serial.print(“Valore in bit della variabile Data(“);
Serial.print(Data);
Serial.println(“):”);
Serial.print(bitRead(Data, 0)); //bit meno significativo
Serial.print(bitRead(Data, 1));
Serial.print(bitRead(Data, 2));
Serial.print(bitRead(Data, 3));
Serial.print(bitRead(Data, 4));
Serial.print(bitRead(Data, 5));
Serial.print(bitRead(Data, 6));
Serial.print(bitRead(Data, 7));
Serial.print(bitRead(Data, 8));
Serial.print(bitRead(Data, 9));
Serial.print(bitRead(Data, 10));
Serial.print(bitRead(Data, 11));
Serial.print(bitRead(Data, 12));
Serial.print(bitRead(Data, 13));
Serial.print(bitRead(Data, 14));
Serial.print(bitRead(Data, 15)); //bit più significativo
Serial.println();
delay(2000);
}
[/c]
Manipolare i bit sembra macchinoso ma il vantaggio è che Arduino esegue molto velocemente questo tipo di operazioni, vedremmo successivamente come sia possibile eseguire semplici operazioni lavorando con i singoli bit.
[facebook_ilike]