我需要在微 Controller 和另一个芯片之间进行 SPI 通信。该芯片接受 16 位字。但抽象库要求数据以两个 8 位字节的形式发送。现在我想制作一个包装器,这样我就可以轻松创建读写请求......但我还没有取得任何成功。它应该是这样的:
下表显示 16 位。 MSB 可以是 0
(用于写入)或 1
(用于读取)。地址可以从0x0
到0x7
,数据为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
我尝试创建这个结构/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 <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;
}
关于c - 将各个位分配给字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47110886/