编辑2:
当我开始纠正我的原始答案(如下)时,我看到@ouah 已经发布了一个正确的答案,所以我请你使用它而不是我的。有关更详细的说明,请阅读下面的“编辑 1”。
我原来的答案:
PORTB
可能未定义为 anint
这意味着当您获取地址时PORTB
不会得到int *
. 如果您确定自己是对的并且可以使用int *
for PORTB
,则可以使用强制转换来告诉编译器它不需要担心。你可以像这样投射它:
ptr = (int*)&PORTB
转到定义PORTB
并让我们知道它是什么类型。
编辑1:
我的假设是你知道那PORTB
是一个int
并且你是从void*
. 感谢@H2CO3 指出它实际上是 a(*(volatile uint8_t *)(0x25))
基本上意味着它PORTB
是 a volatile uint8_t
。
在这种情况下,您永远不应该将其转换为int
! 如果这可行,则意味着您的机器可能是小端,您不应该依赖它。
为了正确解释它,让我们建立一个简单的例子:
我们在内存中有这个:
Address Value
0x02 7
0x03 11
注意:7 是十六进制的 0x07,二进制是 00000111,11 是十六进制的 0x0B,二进制是 00001011
现在我们有 2 个指针:
uint8_t* BytePointer;
int* IntPointer; // int is either 2 or 4 bytes, we will assume it is 2 bytes.
int Value16;
uint8_t Value8;
// Let's set both to point to our fake memory address
BytePointer = (uint8_t*) 0x02;
IntPointer = (int*) 0x02;
// Now let's see what value each holds?
Value8 = *BytePointer;
Value16 = *IntPointer;
// Value8 will contain 0x07
// Value16 will contain 0x0B07 on a Little Endian machine
// Value16 will contain 0x070B on a Big Endian Machine
这个例子说明了当我们从指针中读取值时会发生什么,那么写入呢?让我们保持和以前一样的变量并写一些值
*BytePointer = 5;
内存现在看起来像这样:
0x02 5
0x03 11
int
指针呢?
*IntPointer = 5;
由于 anint
是两个字节,它将改变两个字节:
// Little endian
0x02 5
0x03 0
// Big endian
0x02 0
0x03 5
因此,如果您使用PORTB
as int
,则每次分配给它时,您都在写入 2 个字节,一个写入地址,PORTB
一个紧接在其后。我希望之后的一切都不重要......你不应该这样做,所以uint8_t*
如果你真的想使用指针,你应该使用 an 。
但是当我开始正确解释这一切时,@ouah 已经发布了一个正确的答案。请参阅它以了解如何执行此操作。