Reputation: 911
In my microcontroller I receive two uint8_t
from UART. I need to parse it so that I can easily refer to its content later. The incoming data is like this:
10 | 9 8 | 7 6 | 5 4 | 3 2 1 0
TRETRY | DEAD_TMIE | OCP_MODE | OCP_DEG | VDS_LVL
As I am a noob and can't get bit masking to work, I went for the union trick...but it does not work as expected. Here is my union:
typedef union {
struct {
uint8_t dont_care :5; //b15-b11 these bits should be discarded
uint8_t retry_time :1; //b10
uint8_t dead_time :2; //b9-b8
uint8_t ocp_mode :2; //b7-b6
uint8_t degl_time :2; //b5-b4
uint8_t vds_lvl :4; //b3-b0
} bits;
uint16_t data;
uint8_t bytes[2];
} DRV_OverCurrentProtection;
What I receive is exactly 0000000101011001
I tried to fill the union like this:
DRV_OverCurrentProtection ocp;
ocp.data = buff[0] << 8 | buff[1];
But I get this in the debugger (obviously its wrong!):
//actual data
buff[0] volatile uint8_t 1 (Binary)
buff[1] volatile uint8_t 1011001 (Binary)
//after assignment to the union
data uint16_t 101011001 (Binary)
//bits
dont_care uint8_t 25 '\031'
retry_time uint8_t 0 '\0'
dead_time uint8_t 1 '\001'
ocp_mode uint8_t 1 '\001'
degl_time uint8_t 0 '\0'
vds_lvl uint8_t 0 '\0'
I am feeling hopeless and I think with unions I go no where...would you please tell me what is going wrong in my code and implementation and yet better what is the best way to do something like this? that would be a great help to a newb.
Upvotes: 2
Views: 116
Reputation: 24052
Your struct is packing the bit fields from low-to-high. Just reverse the order:
struct {
uint8_t vds_lvl :4; //b3-b0
uint8_t degl_time :2; //b5-b4
uint8_t ocp_mode :2; //b7-b6
uint8_t dead_time :2; //b9-b8
uint8_t retry_time :1; //b10
uint8_t dont_care :5; //b15-b11 these bits should be discarded
} bits;
That should produce the association you're looking for.
Upvotes: 1