編集2:
元の回答(以下)を修正するまでに、@ouahがすでに正しい回答を投稿していることがわかったので、私の代わりにそれを使用してください. より詳細な説明については、以下の「編集 1」をお読みください。
私の元の答え:
PORTB
はおそらく として定義されていません。int
これは、 のアドレスをPORTB
取得しても が得られないことを意味しますint *
。あなたが正しく、int *
forPORTB
を使用できると確信している場合は、キャストを使用して、心配する必要がないことをコンパイラーに伝えることができます。次のようにキャストできます。
ptr = (int*)&PORTB
の定義に移動し、PORTB
それがどのタイプであるかをお知らせください。
編集1:
PORTB
私は、それが であることを知っていてint
、 からキャストしていると仮定しましたvoid*
。@H2CO3 さん、実際には a であることを指摘していただき、ありがとうござい(*(volatile uint8_t *)(0x25))
ます。PORTB
volatile uint8_t
これは、絶対にキャストしないでくださいint
。これが機能する場合は、マシンがおそらくリトルエンディアンであり、これに頼るべきではないことを意味します。
適切に説明するために、簡単な例を設定しましょう。
これは記憶に残っています:
Address Value
0x02 7
0x03 11
注: 7 は 16 進数で 0x07、2 進数で 00000111、11 は 16 進数で 0x0B、2 進数で 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
は 2 バイトであるため、2 バイトが変更されます。
// Little endian
0x02 5
0x03 0
// Big endian
0x02 0
0x03 5
したがって、PORTB
として使用するとint
、それに割り当てるたびに のアドレスに 1 バイト、PORTB
直後に 1 バイトの 2 バイトが書き込まれます。後が重要ではないことを願っています...これを行うべきではないので、uint8_t*
本当にポインターを使用したい場合はを使用する必要があります。
しかし、私がそれをすべて適切に説明するまでに、@ouahはすでに正解を投稿しています. これをどのように行うべきかについては、それを参照してください。