Ваши значения слишком велики для выделенного пространства:
0x8 = 1000b - four bits, not three
0x1 = 1b - but if char is signed you can only have 0 and -1!
0x10 = 16 = 10000b - five bits, you'be allocated four
Итак, эффективный результат:
(0x8 | (0x1 << 3) | (0x10 << 4)) & 0xff
=> (0x8 | 0x8 | 0x100) & 0xff
=> 0x8
что ты и получаешь. 0xfa это:
11111010b
но вы предполагаете, что первый элемент в структуре находится в позиции бита 7 (наиболее значимый), но стандарт (насколько я знаю) не указывает, где должны начинаться биты (это может быть бит 0, наименее значительно) и, глядя на ваш вывод, я думаю, что первое поле является наименее значимым битом, поэтому у вас есть:
ccccbaaa
где a - tft_op, b - e_bit, а c - no_of_pkt. Чтобы получить 0xfa это либо:
tft_op = 2
e_bit = 1
no_of_pkt = 15
или, если заказ обратный:
tft_op = 7
e_bit = 1
no_of_pkt = 10
Кроме того, вместо char *ptr = (char*)&st_octet;
изучите использование объединения:
typedef union
{
struct _octet
{
char tft_op:3;
char e_bit:1;
char no_of_pkt:4;
};
char data;
} octet_t;