なぜここでビット演算を行うのか?(SPI FRAM リード方法)

参照: https://github.com/adafruit/Adafruit_FRAM_SPI/blob/master/Adafruit_FRAM_SPI.cpp 以下のメソッドは、入力を読み込んで8ビットに変換するものです。その機能に関していくつか質問があります。

addr = 0xFFFF を例にとると、このメソッドは変数を 0xFF に変換しています。末尾からビットが削除されることは理解できますが、確かに65535 != 255です。おそらく、相対的に、その最大サイズに、しかし、これはどのように有用な変換ですか?私はここでビット単位について何かを見逃しているかもしれません...

uint8_t Adafruit_FRAM_SPI::read8 (uint16_t addr)
{
 digitalWrite(_cs, LOW);
 SPItransfer(OPCODE_READ); //read memory from fram array (2-byte)
 SPItransfer((uint8_t)(addr >> 8));
 SPItransfer((uint8_t)(addr & 0xFF));
 uint8_t x = SPItransfer(0);
 digitalWrite(_cs, HIGH);
 return x;
}

間違っていたら訂正してください、キャストは符号拡張が起こらないようにするためです。

マスキングは理論的には理解できますが、ここでの適用が全く理解できません。

最後に、いつも同じ値 x = 0 を返しますが、なぜですか?

また、書き込みメソッドはありますが、読み込みメソッドはありませんね。read8だけです。理由は?

ソリューション

仮に addr0xbeef であるとします。そして、各操作を分解すると

expression             │ value
───────────────────────┼───────
addr                   │ 0xbeef
addr >> 8              │ 0x00be
(uint8_t)(addr >> 8)   │   0xbe
addr & 0xFF            │ 0x00ef
(uint8_t)(addr & 0xFF) │   0xef

つまり、これは本質的にアドレスを2つの8ビットのチャンクに分解しているのです。 そして、そのチャンクを個別に送信しているのです。このような仕組みになっているのは SPIはバイト単位でしか送信できません。

キャストは、符号拡張を行わないようにするためのものです。

Addrは符号なし数なので、符号拡張は起こりえません。 キャスティングは、コードを文書化すること以外には、何の役にも立ちません。 コードを文書化する以外には何の役にも立ちません。これは、単にSPItransfer()uint8_tを受け取るので、暗黙的に行われることになります。 はuint8_tという引数を取るので、暗黙のうちに行われます。もしSPItransfer()` が 16 ビットでオーバーロードされていれば、このキャストは役に立つかもしれません。 が 16 ビットバージョンでオーバーロードされた場合、このキャストは役に立つかもしれません。

最後に、いつも同じ値 x = 0 を返しますが、なぜですか?

いいえ、SPItransfer(0);のコールが返すもの、つまりFRAMモジュールによって送られたデータを返します。 つまり、FRAMモジュールから送られたデータです。

解説 (0)