I haven't touched bit fields (or unions) in over 20 years, but last night I was helping a friend with a project where he has 8 12-bit values that need to be SPI'd to a device as 96bits (or 12 bytes). Instead of bit manipulations, I suggested using a union of a bit field structure and a unsigned char array. I know that the order of bit fields is compiler dependent, but thought that would be easy to determine.
HOWEVER, I got some results, which I find undeciferable. Here is the test code I created.
#include <Arduino.h>
#include <SPI.h>
const int SPI_CLK = 13;
const int SPI_IN = 11;
const int SPI_OUT = 12;
const int SPI_CS = 10;
struct digit
{
unsigned int a:6;
unsigned int b:6;
unsigned int c:6;
unsigned int d:6;
};
union shared_digits
{
struct digit digits;
unsigned char byte_array[3];
};
void setup() {
Serial.begin(9600);
Serial.print("sizeof(shared_digits)=");
Serial.println(sizeof(shared_digits)); // Should be 3 bytes
union shared_digits ti_chip;
// Assign some values to the ti_chip structure
// 11111101 01010000 00101010 0xFD 0x50 0x2A
ti_chip.digits.a = B111111;
ti_chip.digits.b = B010101;
ti_chip.digits.c = B000000;
ti_chip.digits.d = B101010;
Serial.print("ti_chip.digits.a = ");
Serial.println(ti_chip.digits.a, BIN);
Serial.print("ti_chip.digits.b = ");
Serial.println(ti_chip.digits.b, BIN);
Serial.print("ti_chip.digits.c = ");
Serial.println(ti_chip.digits.c, BIN);
Serial.print("ti_chip.digits.d = ");
Serial.println(ti_chip.digits.d, BIN);
Serial.print(ti_chip.byte_array[0], BIN);
Serial.print(" ");
Serial.print(ti_chip.byte_array[1], BIN);
Serial.print(" ");
Serial.println(ti_chip.byte_array[2], BIN);
// Displays the following results
// 01111111 00000101 10101000 0x7F 0x05 0xAB
pinMode(SPI_CS, OUTPUT);
SPI.begin();
}
void loop() {
}
As you can see it appears to be swapping nibbles, but the first and last values are changing one of those nibbles. Any suggestions, or is this approach not functional with modern C? (Or is my memory disfunctional and was it never a valid approach)