将单个位分配给字节

Assigning individual bits to bytes

我需要在微控制器和另一个芯片之间进行 SPI 通信。该芯片接受 16 位字。但是抽象库要求数据以两个 8 位字节的形式发送。现在我想做一个包装器,这样我就可以轻松地创建读写请求……但我还没有取得任何成功。它应该是这样的:

下面的table表示16bits。写入时 MSB 可以是 0,读取时可以是 1。地址可以从0x00x7,数据是11位。

R/W  |      ADDRESS   |    DATA
 B15 |      B14-B11   |   B10-B0
 0   |        0000    | 00000000000
 W0  | A3, A2, A1, A0 | D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0

例如,如果我想从寄存器 0x1 读取,我想我必须像这样设置位:

 W0  | A3, A2, A1, A0 | D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0
  1  | 0    0   0   1 |  0    0   0   0   0   0   0   0   0   0   0

或从寄存器 0x​​7 读取:

 W0  | A3, A2, A1, A0 | D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0
  1  | 0    1   1   1 |  0    0   0   0   0   0   0   0   0   0   0

我已经尝试创建这个 struct/union 看看它是否可以工作:

typedef struct{
    uint8_t acc_mode:1;
    uint8_t reg_addr:4;
    uint8_t reg_data:8; //TODO fix me should be 11
} DRVStruct;

typedef union {
    DRVStruct content;
    uint16_t all;
} DRVUnion;

void DRV_PrepareReadMsg(uint8_t reg, uint8_t* msgBuffer) {
    DRVUnion temp;
    temp.content.acc_mode = 1;
    temp.content.reg_addr = reg;
    temp.content.reg_data = 0; //read mode does not need data!

    msgBuffer[1] = temp.all & 0xFF;
    msgBuffer[0] = temp.all >> 8;
}

我得到了奇怪的结果...我不时从 SPI 得到答复(我确信 SPI 通信没问题,但我准备消息的代码有问题)。

所以问题是:

这似乎有效:


#include <stdio.h>
#include <stdint.h>

typedef union {
    struct{     // no struct tag, since it is not needed...
        uint16_t acc_mode:1;
        uint16_t reg_addr:4;
        uint16_t reg_data:11; //TODO fix me should be 11
        } bits;
    uint16_t all;
    uint8_t bytes[2]; //extra bonus when lit;-)
        } DRVUnion;

int main(void)
{
DRVUnion uni,uni13[13];

printf("Size=%zu, %zu\n", sizeof uni, sizeof uni13);
return 0;
}