1

我正在尝试读取 SD 卡的“大小”。我拥有的示例示例具有以下代码行:

unsigned char xdata *pchar; // Pointer to external mem space for FLASH Read function;
pchar += 9; // Size indicator is in the 9th byte of CSD (Card specific data) register;

 // Extract size indicator bits;
size = (unsigned int)((((*pchar) & 0x03) << 1) | (((*(pchar+1)) & 0x80) >> 7));

我无法理解在上面提取指示位的行中实际做了什么。有人可以帮助我理解这一点吗?

4

4 回答 4

4

size由两个字节的位组成。一个字节在pchar,另一个在pchar + 1

(*pchar) & 0x03)取 2 个最低有效位(砍掉 6 个最高有效位)。使用 将该结果左移一位<< 1。例如:

11011010 (& 0x03/00000011)==> 00000010 (<< 1)==> 00000100 (-----10-)

类似的事情是用pchar + 1. 例如:

11110110 (& 0x80/10000000)==> 10000000 (>> 7)==> 00000001 (-------1)

然后将这两个值与 进行或运算|。所以在这个例子中你会得到:

00000100 | 00000001 = 00000101 (-----101)

但请注意,5 个最高有效位将始终为0(上面用 表示-),因为它们被&-ed 去掉了:

总而言之,第一个字节包含两位size,而第二个字节只有一位。

于 2013-06-29T08:10:57.707 回答
3

看起来大小指示符,比如 SI,由 3 位组成,其中*pchar在其最低两位 () 中包含 SI 的两个最高有效位,0x03*(pchar+1)其最高位 () 中包含 SI 的最低有效位0x80

于 2013-06-29T08:05:18.303 回答
1
size = (unsigned int)((((*pchar) & 0x03) << 1) | (((*(pchar+1)) & 0x80) >> 7));
  • 有人可以帮助我理解这一点吗?

我们有 byte*pchar和 byte *(pchar+1)。每个字节由 8 位组成。让我们*pchar用粗体索引76543210的每一位,*(pchar+1)用斜体索引76543210的每一位。

1..((*pchar) & 0x03) << 1表示“将*pchar除位 0 和 1 之外的所有位归零,然后将结果左移 1 位”:

76543210 --> xxxxxx10 --> xxxxx10x

2..(((*(pchar+1)) & 0x80) >> 7)表示“将除第 7 位之外的所有位归零*(pchar+1),然后将结果右移 7 位”:

76543210 --> 7xxxxxxx --> xxxxxxx7

3..((((*pchar) & 0x03) << 1) | (((*(pchar+1)) & 0x80) >> 7))表示“将左右操作数的所有非零位组合成一个字节”:

xxxxx10x | xxxxxxx7 --> xxxxx10 7

因此,在结果中,我们有两个低位来自*pchar和一个高位来自*(pchar+1)

于 2013-06-29T08:58:47.877 回答
1

第一行和第二行说明如何指向您想要的数据。

现在让我们从左到右完成所涉及的步骤。

操作的第一部分获取 指向的字节,对该字节pchar执行逻辑与,0x03并将该结果移位一位。

然后将该结果与下一个字节进行逻辑或运算,然后(*pchar+1)将其与 进行逻辑与运算0x80,然后将其右移七位。本质上,这部分只是去掉字节中的第一位并将其移动七位。

结果基本上是这样的:

想象一下pchar指向用字母表示位的字节:ABCDEFGH.

第一部分与0x03,所以我们留下了000000GH。然后将其左移一位,因此剩下00000GH0.

正确的部分也是如此。pchar+1由 表示IJKLMNOP。有了第一个逻辑 AND,我们剩下I0000000. 然后将其右移七次。所以我们有0000000I. 这与使用 OR 的左侧部分相结合,所以我们有00000GHI,然后将其转换为一个 int,它保存您的大小。

基本上,有三个位保持大小,但它们不是字节对齐的。因此,需要进行一些操作。

于 2013-06-29T08:08:25.997 回答