我正在尝试读取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));
我无法理解在上面提到指标位的行中实际做了什么。有人可以帮我理解这个吗?
答案 0 :(得分: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)
然后将这两个值与|
进行OR运算。所以在这个例子中你会得到:
00000100 | 00000001 = 00000101 (-----101)
但请注意,5个最高有效位始终为0
(上面标有-
),因为它们是&
- ed away:
总而言之,第一个字节保存两位size
,而第二个字节只保存一位。
答案 1 :(得分:3)
似乎SI的大小指示符由3位组成,其中*pchar
包含最低两位(0x03
)和*(pchar+1)
中包含两个最高有效位的SI最高位(0x80
)中SI的最低有效位。
答案 2 :(得分:1)
第一行和第二行弄清楚如何指向您想要的数据。
现在让我们从左到右完成所涉及的步骤。
操作的第一部分采用pchar
指向的字节,对字节和0x03
执行逻辑AND,并将结果移位一位。
然后将该结果与下一个字节(*pchar+1)
进行逻辑或运算,后者又与0x80
进行“与”运算,然后右移7位。本质上,这部分只是剥离字节中的第一位并将其移位7位。
结果基本上是这样的:
想象一下pchar
指向字节,其中的位用字母表示:ABCDEFGH
。
第一部分与0x03
成对,因此我们留下了000000GH
。然后将其左移一位,因此我们留下00000GH0
。
右边部分也是如此。 pchar+1
代表IJKLMNOP
。使用第一个逻辑AND,我们留下I0000000
。然后右移7次。所以我们有0000000I
。这与使用OR的左手部分组合在一起,因此我们有00000GHI
,然后将其转换为int,它保持你的大小。
基本上,有三个位保持大小,但它们不是字节对齐的。因此,有必要进行一些操纵。
答案 3 :(得分:1)
size = (unsigned int)((((*pchar) & 0x03) << 1) | (((*(pchar+1)) & 0x80) >> 7));
我们有字节*pchar
和字节*(pchar+1)
。每个字节由8位组成。
让我们将*pchar
的每一位用粗体编号: 76543210 ,并将*(pchar+1)
的每一位用斜体标记: 76543210 。
1 .. ((*pchar) & 0x03) << 1
表示“除了位0和1之外的所有位*pchar
为零,然后将结果向左移位1位”:
76543210 - &gt; xxxxxx10 - &gt;的 xxxxx10x 强>
2 .. (((*(pchar+1)) & 0x80) >> 7)
表示“除了第7位以外的所有*(pchar+1)
位,然后将结果向右移7位”:
76543210 - &gt; 7xxxxxxx - &gt; xxxxxxx7
3 .. ((((*pchar) & 0x03) << 1) | (((*(pchar+1)) & 0x80) >> 7))
表示“将左右操作数的所有非零位组合成一个字节”:
xxxxx10x | xxxxxxx7 - &gt;的 xxxxx10 强> 7
因此,在结果中,我们有*pchar
的两个低位和*(pchar+1)
的一个高位。