【发布时间】:2020-10-07 23:40:06
【问题描述】:
【问题讨论】:
【问题讨论】:
将会有一些关于你如何读取和写入这个寄存器的细节。可能它会以某种方式映射到内存中,您可以通过读取和写入该内存地址来访问它。由于您没有提供有关其实施方式的任何详细信息,因此我无法为您提供帮助。我能做的就是告诉你如何在你读取寄存器的值后修改它的特定位。
由于这个寄存器包含 8 位,我将使用unsigned char 类型。并且您可以使用按位运算来修改寄存器中的位,特别是按位与 (&) 和按位或 (|)。
通常你会定义一个掩码来隔离特定的感兴趣的部分。在这种情况下,它将是一个 8 位值,将感兴趣的位设置为 1,其他位置设置为 0。因此,对于 D0,它将是 0000 0001 的二进制值,而对于 D4,它将是 0001 0000。这些可以分别用十六进制等效地写为 0x01 和 0x10,这就是这种类型的掩码通常是如何完成的。
#define REGISTER_0x2B_D0_MASK 0x01
#define REGISTER_0x2B_D4_MASK 0x10
现在要读取这些位之一,您可以简单地按位并使用适当的掩码。要写入(设置)位,您可以按位或。
d0 = register_value & REGISTER_0x2B_D0_MASK; // read bit d0 value from register
register_value = register_value | REGISTER_0x2B_D0_MASK; // set bit d0 to 1
register_value = register_value & ~REGISTER_0x2B_D0_MASK; // set bit d0 to 0
第一行通过将每个位与掩码的位进行与运算来工作。由于掩码的所有位除最后一位外均为 0,因此它使除最后一位以外的所有位中的结果均为 0(因为 0&anything 为 0,而 1&anything 就是那个东西)。
第二行通过将每个位与掩码进行或运算来工作。因为 0|anything 是那个东西,而 1|anything 是 1,所以它只将最后一位设置为 1,而其他一切都保持原样。
第三行是最棘手的,因为它使用带有 ~ 的掩码的补码。这会反转掩码,因此它变为除最后一位之外的所有 1,最后一位变为 0。然后按位应用并意味着它将除最后一位之外的每一位与 1 (不做任何更改)进行与运算,强制它为0.
所以示例代码看起来像这样:
#define REGISTER_0x2B_D0_MASK 0x01
#define REGISTER_0x2B_D4_MASK 0x10
void main()
{
unsigned char register_value, d0, d4;
// get the current value of the register somehow
register_value = read_register_0x2b();
// read the bits of interest
d0 = register_value & REGISTER_0x2B_D0_MASK;
d4 = register_value & REGISTER_0x2B_D4_MASK;
// set D0 to 1
register_value = register_value | REGISTER_0x2B_D0_MASK;
// set D4 to 0
register_value = register_value & ~REGISTER_0x2B_D4_MASK;
// apply changes to register
write_register_0x2b(register_value);
}
请注意,在读取位的示例中,您会在寄存器中占据的位置获得位。因此,如果 d0 设置为 1,则 d0 值将为 0x01。同样,如果 d4 设置为 1,则 d4 值将为 0x10。如果您只是想用它来测试该位是否已设置,这很好,因此不设置 0 并设置其他任何内容。如果您希望 d4 设置为 1,则需要将该位向下移动到最不重要的位置,如下所示:
d4 = (register_value & REGISTER_0x2B_D4_MASK) >> 4;
【讨论】: