Dove si trova la funzione byte()

Ciao, avrei bisogno di estrapolare dei bit da un unsigned int e farci delle unsigned char.

Attualmente uso:

unsigned int cID = 0x56F;
unsigned char SIDH = cID >> 3;
unsigned char SIDL = cID << 5;

Però non so se è corretto e non so se poi può generare dei problemi o blocchi del programma in certe situazioni... :~ e per questo volevo vedere come avevano fatto la funzione byte(). Ho provato a cercarla nelle librerie tipo stdio.h ed altre ma senza successo. Qualcuno sa dove si possono trovare queste funzioni particolari di arduino?

Byte è un alias per uint_8, apri il file Arduino.h e trovi:

typedef uint8_t byte;

leo72:
Byte è un alias per uint_8,

Che a sua volta è un alias per "unsigned char" :slight_smile:

Esatto.

scusatemi, mi sono espresso male. Non intendevo il tipo di variabile, ma la funzione byte() che restituisce una variabile tipo byte quando le si passa una variabile di altro tipo.

ps. leo e astro, voi come fareste ad ottenere queste u char dal u int?

Ma devi dividere un unsigned int nel byte basso e byte alto?
Potresti usare questo

byte alto = (valore>>8) & 0xFF;
byte basso = valore & 0xFF;

La prima fa lo shift a DX di 8 bit, poi fa l'and con $FF per cui prende solo gli 8 bit meno significativi; la seconda come prima ma senza lo shift, quindi prende subito gli 8 bit più a destra.

PS:
puoi anche usare le funzioni integrate di Arduino lowByte e highByte:
http://arduino.cc/en/Reference/LowByte
http://arduino.cc/en/Reference/HighByte

Sono delle macro che se non ricordo male fanno quasi la stessa cosa di quella che ti ho scritto poc'anzi

Forse intende il casting di una variabile. :roll_eyes:

PaoloP:
Forse intende il casting di una variabile. :roll_eyes:

Ha posto due domande, la prima riguarda il casting ma la seconda mi pare si riferisca proprio al dubbio iniziale, ossia scomporre un uint16 in 2 uint8.

Il casting lo fa il compilatore, non mi ricordo di macro o funzioni sparse nel core dell'Arduino per gestire i byte()

Intende questa, dal reference:

Sinceramente non capisco a cosa serva, se devi fare un cast puoi usare la sintassi del c vCar=(char)vInt; ma attenzione a overflow!!!
oppure usando lowByte() che mi sembra la migliore (scarti la parte alta dell'int)

EDIT: provato a cercare la byte() ma non la trovo. Trovato invece la bit() nel Arduino.h
#define bit(b) (1UL << (b))

Sì, intende quella. Voleva sapere dove si trovava nel core. Non lo so.

Non l'ho trovata da nessuna parte nell'IDE 1.0.4. Secondo me è deprecata. :roll_eyes:

La questione è che in una variabile unsigned int c'è l'ID dei messaggi che devo trasmettere. LID è composto da 11 bit però non essendoci una variabile da 11 bit uso la unsigned int.

Il controller ha 2 registri a 8 bit che devono contenere l'ID. Nel SIDH prendono posto i 8 bit + "alti" del ID, quindi dal bit 3 al 10. E sta roba io la faccio con

SIDH = ID >> 3;

Il SIDL è il registro per la parte bassa del ID (i bit del ID dallo 0 al 2). In questo registro il bit 2 del ID è il bit 7 del registro, il bit 1 del ID è il 6 del registro e il bit 0 del ID è il bit 5 del registro. Per questo registro io sono partito da

SIDL = ( ID & 0x07 ) << 5;

Poi mi sono accorto che l'operazione di mascheratura era superflua perchè funziona anche con il solo

SIDL = ID << 5;

Quindi nell'esempio di leo

leo72:

 & 0xFF;

lo stesso risultato si ottiene anche con il solo

byte basso = valore/quote]

Io volevo vedere come avviene il casting di un Int in un Byte per sapere se togliendo la mascheratura succedono problemi.

nid69ita:
Intende questa, dal reference:
byte() - Arduino Reference

Assolutamente inutile visto che basta fare "(unsigned char) MyVar", ovviamente tutti i bit eccedenti i primi otto vengono troncati con la possibilità di trovarsi un valore falsato, il casting deve sempre essere utilizzato previa accensione del cervello :slight_smile:

E con una union?

union
{
    unsigned int Integer;
    byte Byte[2];
} ID;

void pippo()
{
    ID.Integer = 6789;
    serial.print(ID.Byte[0]);
    serial.print(ID.Byte[1]);
}

Ho trovato anche questa soluzione che usa i puntatori

int a = 1;
char * c = (char*)(&a); //In C++ should be intermediate cst to void*

Ma non saprei come accedere alla seconda cifra. Forse aggiungendo 8 all'indirizzo?

andrea86:
Io volevo vedere come avviene il casting di un Int in un Byte per sapere se togliendo la mascheratura succedono problemi.

Il casting di un int un un byte avviene semplicemente troncando gli otto bit superiori, molta attenzione al fatto che se int contiene un valore negativo il casting verso un unsigned char (byte) porta inevitabilmente a valori errati per via del modo in cui i numeri negativi sono rappresentati in binario.

nid69ita:
Sinceramente non capisco a cosa serva, se devi fare un cast puoi usare la sintassi del c vInt=(char)vCar; ma attenzione a overflow!!!

Intendevi cChar = (char)vInt? Se sì, cos'è l' overflow?

astrobeed:

andrea86:
Io volevo vedere come avviene il casting di un Int in un Byte per sapere se togliendo la mascheratura succedono problemi.

Il casting di un int un un byte avviene semplicemente troncando gli otto bit superiori, molta attenzione al fatto che se int contiene un valore negativo il casting verso un unsigned char (byte) porta inevitabilmente a valori errati per via del modo in cui i numeri negativi sono rappresentati in binario.

Però astro io uso il unsigned int, in teoria da quello che ho capito ( il c l'avevo "studiato" a scuola quasi 10 anni fa... ) non dovrebbe avere il 15 bit per la storia se il numero è negativo o no.

andrea86:
Però astro io uso il unsigned int, in teoria da quello che ho capito ( il c l'avevo "studiato" a scuola quasi 10 anni fa... ) non dovrebbe avere il 15 bit per la storia se il numero è negativo o no.

Se usi gli unsigned int in valore contenuto può essere solo positivo, da 0 a 65535, quindi il problema legato ai valori negativi non c'è.

andrea86:

nid69ita:
Sinceramente non capisco a cosa serva, se devi fare un cast puoi usare la sintassi del c vInt=(char)vCar; ma attenzione a overflow!!!

Intendevi cChar = (char)vInt? Se sì, cos'è l' overflow?

Si, la fretta a volte .... :grin:

Nel tuo caso mi sembra la soluzione migliore la lowByte() che oltretutto rende anche il codice più leggibile rispetto a un mascheramento.
#define lowByte(w) ((uint8_t) ((w) & 0xff))