简体   繁体   中英

How can I allocate 10bit values to a byte array?

I need to send data from a microcontroller through a serial port and would like to minimize the data sent, because the data is a 10bit reading from an ADC. So I thought, I would use an union. This is what I got:

union fortybit
{
 struct
 {
  unsigned int a : 10;
  unsigned int b : 10;
  unsigned int c : 10;
  unsigned int d : 10;
 } tenbits;
 unsigned char bytes[5];
};

Now I'm sending the data like this:

fortybit fb;
for (int i = 0; i < 640; i++)
{
 fb.tenbits.a = 512;
 fb.tenbits.b = 512;
 fb.tenbits.c = 512;
 fb.tenbits.d = 512;
 Serial.write(fb.bytes, 5);
}

Which results in some strange readings, which are periodic and some of the values are right, but most of them are completely wrong.

What could I be doing wrong? What is the right way to do this?

You should never use bitfields in any external representation. This becomes external since you send the raw bytes where the bitfields are stored, over a serial line.

There's no way to know that the computer in the receiving end of hte serial line interprets your struct the same way. It might have a different byte ordering, a different native integer size into which the bits are packed which might mean different padding, or whatever.

It's simply not portable.

You should do it in a more controlled fashion, perhaps by manually computing each byte of the desired external representation. This is called serialization , and it's a good thing.

Its not like its that hard to do the packing transform yourself. Something like this should do the trick:

int A[4] = { 0x1,0x1,0x1,0x1 };
int B[5];

long long x=0;
for(int i=0; i<4; i++) {
    x |= A[i] << (10*i);
}
for(int i=0; i<5; i++) {
    B[i] = x & 0xFF;
    x >>= 8;
}

printf("%02x %02x %02x %02x %02x\n",B[0],B[1],B[2],B[3],B[4]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM