DEKKER
DEKKER

Reputation: 911

Forcing two unsigned chars into a union

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

Answers (1)

Tom Karzes
Tom Karzes

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

Related Questions