编辑 2:
当我开始纠正我的原始答案(如下)时,我看到 @ouah 已经发布了一个正确的答案,所以我请你使用它而不是我的。如需更详细的说明,请阅读下面的“编辑 1”。
我原来的回答:
PORTB 可能没有定义为int,这意味着当您获取PORTB 的地址时,您不会得到int *。如果你确定你是对的并且你可以使用int * 代替PORTB,你可以使用强制转换来告诉编译器它不需要担心。你可以像这样投射它:
ptr = (int*)&PORTB
转到PORTB的定义,让我们知道它是什么类型。
编辑 1:
我的假设是你知道PORTB 是一个int,并且你是从void* 转换它的。感谢@H2CO3 指出它实际上是(*(volatile uint8_t *)(0x25)),这基本上意味着PORTB 是volatile uint8_t。
在这种情况下,您绝不应该将其转换为int!如果这有效,则意味着您的机器可能是little endian,您不应该依赖它。
为了正确解释,让我们建立一个简单的例子:
我们有这个记忆:
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;
由于int 是两个字节,它会改变两个字节:
// Little endian
0x02 5
0x03 0
// Big endian
0x02 0
0x03 5
因此,如果您将PORTB 用作int,则每次分配给它时,您都会写入2 个字节,一个写入PORTB 的地址,一个紧接着一个。我希望后面的内容都不重要......你不应该这样做,所以如果你真的想使用指针,你应该使用uint8_t*。
但是当我开始正确解释这一切时,@ouah 已经发布了正确答案。请参阅它以了解如何执行此操作。