将各个位分配给字节

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

下表显示了16位。 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 

或者从寄存器0x7读取:

  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通信没问题,但我准备消息的代码是问题)。

所以问题是:

  • 我做正确的事还是做法?
  • 如何在不出现编译错误的情况下将reg_data从8增加到11?
  • 您对更好的方法有什么建议?

这似乎有效:


 #include  #include  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; }