You can do it by putting the bits in a struct inside the union, but it may or may not work, depending on your implementation. The language definition does not specify in what order the separate bits will be matched with the bits of the unsigned char
; worse, it doesn't even guarantee that the bits will overlap with the unsigned char
(the compiler might decide to place the separate bits towards the most significant side of a word and the unsigned char
towards the least significant side or vice versa).
The usual technique in your situation is to use bitwise operations. Define constants named after the meaning of the bits, e.g.,
#define FLAG_BUSY 0x01
#define FLAG_DATA_AVAILABLE 0x02
#define FLAG_TRANSMISSION_IN_PROGRESS 0x04
...
#define FLAG_ERROR 0x80
Then to read and write individual bits:
if (status & FLAG_BUSY) ... /* test if the device is busy */
status &= ~FLAG_ERROR; /* turn off error flag */
status |= FLAG_TRANSMISSION_IN_PROGRESS /* turn on transmission-in-progress flag */