如何将uint8_t放在uint16_t的中间而不影响其他位

时间:2017-12-10 12:40:26

标签: c embedded bit-manipulation bitwise-operators

我正在为使用16位SPI消息的DAC芯片编写SPI驱动程序......表示输出的值是从第11位到第4位(8位DAC)。我写过这个MASK,但我不知道如何在不影响其他位的情况下更新数据:

#define MCP4901_SPI_MASK_DATA               0x0FF0
//So data mask in binary is 0000 1111 1111 0000

extern uint16_t mcpA;

static inline void mcpSetData(uint16_t* mcp, uint8_t value) {
    //????
   *mcp =| value & MCP4901_SPI_MASK_DATA; //NOT WORKING
}

1 个答案:

答案 0 :(得分:3)

您对两个操作|&的使用是正确的,但您没有按正确的顺序使用它们,并且您没有正确定位其中一个操作数。

这是正确的做法:

*mcp &= ~MCP4901_SPI_MASK_DATA; // Clear out the middle bits
*mcp |= ((uint16_t)value) << 4; // Put in the value in the middle

由于您正在写入硬件寄存器,因此应使用单次写入以避免可能的副作用:

*mcp = (*mcp & ~MCP4901_SPI_MASK_DATA) | (((uint16_t)value) << 4);

MCP4901_SPI_MASK_DATA被反转以清除0x0FF0之外的位。或者,您可以将掩码定义为0xF00F,然后删除~运算符。

8位值向左移动4,将其置于16位中间,然后是#34; OR&#34; - 将其置于数字中。

Demo.