(2017.10.21 作成)
このページではSRAMの使い方について紹介したいと思います。
SRAMは揮発性のメモリの一種で電源を消すと内容は消えてしまうのですが高速で無限回の書き換えが可能なので、不揮発性メモリ(EEPROMなど)とは違う使い道があります。
このSRAMですが多くの場合高速というメリットを生かすためにパラレル接続となっていますが、この場合ピン数が10ピン以上となり大型化します。
そのような中、不揮発性メモリより高速で少ピン接続が可能なSRAMがMicrochipさんから発売されており、このページではその使用方法について紹介したいと思います。
MicrochipさんのシリアルSRAMの一つである23LC1024です。
LCが2.5~5.5V対応を表しており、電子工作に使用するにはこちらが良いと思います。ほかにも低電圧向けの23A1024という型番が存在します。
容量は型番の通り1024kbit = 128kByteです。ほかにも23LC512などの型番がありますが価格差があまりないので量産でもしない限り1024が最もよいでしょう。Aliexpressで1個200円ぐらいで購入できます。
パッケージはDIPタイプ(いわゆるゲジゲジ)が電子工作を行うには使いやすいと思いますが、右写真のようにSOICタイプも選べます。この場合は写真のように変換基板を介して使用するのが個人の電子工作ではよいと思います。
23LC1024とはSPIで接続します。チップとしてはさらに高速なSDIやSQI接続も可能ですが、汎用性を考えるとSPIが良いと思います。
接続は左の通りとなります。
HOLDピンはHighにしないとサスペンドモードになります。
SIO2ピン(NUピン)は未接続でも問題ないのですが万が一SQIモードになったときにコマンドで戻せるようにHighにした方がよいようです。
23LC1024にはアクセスモードが3種類あり
です。ただしSequential modeですべて賄えるので実際にはこれだけ使えればよいかと思います。
コマンドは単純で、電源投入後最初一度だけにシーケンシャルモードに設定します。といってもモードレジスタ書き込みコマンド(0x01)に続いてSequential modeを表す値(0x40)を送るだけです。
あとは
書き込み:0x02 → 先頭アドレス(3byte) → 値
読み出し:0x03 → 先頭アドレス(3byte) → 値
を任意のタイミングで、任意のバイト数送るだけで使用できます。
こちらのページに23LC1024を使用するライブラリを公開しています。
またSTM32F103C8T6基板を用いたサンプルコードを以下に示します。それぞれの引いているincludeファイルや環境構築についてはこちらを参照してください。
以下にSTM32用のサンプルコードを示しますが、Arduinoでも同様のコードで動きます。詳しくはダウンロードしたライブラリ中のサンプルコードを見てください。
#include "DKS_Common_F103xB.h" #include "DKS_F103C8T6.h" #include "DKS_SPI_F103xB.h" #include "DKS_GPIO_F103xB.h" #include "DKS_SRAM.h" DKS::SPI::SPI *spi; DKS::DigitalOut *cs; DKS::Memory::Microchip23LCx *sram; int main(void) { DKS::InitSystem(); DKS::STM32F103C8T6 board(DKS::BlackPill); spi = new DKS::SPI::SPI(SPI1, 0, 0, 0); //SCK: PA5, MISO: PA6, MOSI:PA7 cs = new DKS::DigitalOut(GPIOA, GPIO_PIN_4); spi->setClock(DKS::SPI::SPI_Speed_10MHz); sram = new DKS::Memory::Microchip23LCx(spi, cs, 1024); const uint16_t length(100); const uint32_t address2(0x0a01); uint16_t i; uint8_t wBytes[length]; uint8_t rBytes[length]; for (i = 0; i < length; i++) { wBytes[i] = i+6; rBytes[i] = 0; } sram->write(address2, wBytes, length); sram->read(address2, rBytes, length); for (i = 0; i < length; i++) { if (wBytes[i] != rBytes[i]) { board.led->write(1); while (true); } } while (true) { board.led->toggle(); DKS::Delay(500); } }
まだコメントはありません。