編集2:
元の回答(以下)を修正するまでに、@ouahがすでに正しい回答を投稿していることがわかったので、私の代わりにそれを使用してください. より詳細な説明については、以下の「編集 1」をお読みください。
私の元の答え:
PORTBはおそらく として定義されていません。intこれは、 のアドレスをPORTB取得しても が得られないことを意味しますint *。あなたが正しく、int *forPORTBを使用できると確信している場合は、キャストを使用して、心配する必要がないことをコンパイラーに伝えることができます。次のようにキャストできます。
ptr = (int*)&PORTB
の定義に移動し、PORTBそれがどのタイプであるかをお知らせください。
編集1:
PORTB私は、それが であることを知っていてint、 からキャストしていると仮定しましたvoid*。@H2CO3 さん、実際には a であることを指摘していただき、ありがとうござい(*(volatile uint8_t *)(0x25))ます。PORTBvolatile 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はすでに正解を投稿しています. これをどのように行うべきかについては、それを参照してください。