SRAMにDIPで直接データを書き込む装置をarduinoを使って作ってみた

今回も今回でスパゲッティ。
ちなみに横のZ80にはワイヤーが足りず繋げませんでした(´・ω・`)
先日、EEPROMにデータを書き込む装置をArduinoで作りましたが、まだROMをつないであれこれできるほどZ80について理解しているわけではありませんし、どんどんプログラムを書き込んでは実験して…というのを繰り返すにはあの装置は(主にワイヤーが邪魔で)非常に不便です。そんな時、SRAMに毎回DIPで書き込んでそのたびに実験するという装置をyoutubeで見かけたのでこれだと思い作ってみたのですが、思ったように書き込むまで手間取ったのでメモがてら装置について説明しようと思います。

■SRAMに書き込む動作と読み出す動作


 SRAMに書き込む動作はROMに比べれば非常にシンプルです。まず、今回使ったSRAMのTC55257DPL-85Lのピン配列を見てみます。
DIPtypeのピン配列。

この中で動作切り替えに使うのはCE、OE、R/Wのたった3ピン。各ピンの機能は、
  • CE : SRAMを使用可能か否かを切り替える。
  • OE : SRAMからデータを読み出す
  • R/W : 読み出し・書き出しをコントロールする。クロックに近い?
といった感じになっています。ちなみにI/Oはデータバスで、Aがアドレスバスを指しています。+5V駆動なので、Arduinoの5Vピンにつなげば動かせるという手軽さ。ステキ!
 では、データを書き込むときにはこれらのピンをどういう風に動かせばいいかといいますと、
  1. アドレスピンにアドレスデータを入力
  2. OEピンはHIGH(動かさない)に
  3. CEピンをLOWにし、SRAMを起動する
  4. R/WをLOWにし、データを受け付ける状態に
  5. I/Oピンにデータを出力(ここでデータが書き込まれる)
  6. CEピンをHIGHにし、SRAMを止める
  7. R/WをHIGHに
  8. I/Oへのデータ出力をOFF
  9. アドレスピンへの出力をOFF
といった手順で書き込めるようです。EEPROMと大きく違うところは、データを書き込んでいる間もアドレスバスからの出力をやめないというところでしょうか。
 では、読み出しはどうするかというと
  1. アドレスピンにアドレスデータを出力
  2. R/WピンをHIGHに
  3. CEピンをLOW
  4. OEピンをLOW(ここでデータが出力される)
  5. OEをHIGHに
  6. CEをHIGHにし、SRAMを止める
  7. アドレスピンへの出力をOFF
といった手順でできるようです。

■回路には必ずプルダウン回路が必要?


 最初ただシンプルにDIPスイッチとSRAMをつないだだけの回路でSRAMに書き込んでいたのですが、どうにもこうにもうまく書き込めません。書き込んでいない部分のデータも反応してしまったり、しなかったり…(´・ω・`)これはどうしたことだと考えていたとき、こちらのサイト様「プルアップ抵抗/プルダウン抵抗について」を読みまして「もしかしてデータやアドレスの入力があいまいになっているのかも?」と考え、入力していないときには0Vになってほしいので今回はプルダウン抵抗をはさんだら、問題なく書き込めるようになりました。この原因には電位差とかいうものが関係しているようで、精密さを求められるマイコンの世界では必須の回路のようです。知らなかったわぁ。
 なので、アドレスバス線とデータバス線にこのプルダウン回路を取り付けるのは必須であるということが今回の大きな収穫でした。でも一個一個抵抗をつなぐのは大変なので、集合抵抗を使うといいかもしれませんね。

最後に、今回のArduinoのプログラムを貼っておきます。

/*---------------------------------------*/
#define CE 13
#define OE 12
#define RW 11
#define DD 10//データピン
#define AD 9 //アドレスピン
void setup() {
  // put your setup code here, to run once:
pinMode(CE,OUTPUT);
pinMode(OE,OUTPUT);
pinMode(RW,OUTPUT);
pinMode(DD,OUTPUT);
pinMode(AD,OUTPUT);
Serial.begin(9600);
digitalWrite(CE,HIGH);
digitalWrite(OE,HIGH);
digitalWrite(RW,HIGH);
digitalWrite(DD,LOW);
digitalWrite(AD,LOW);
}

void loop() {
  // put your main code here, to run repeatedly:
int inputchar;

inputchar = Serial.read();
  if(inputchar != -1){
    switch(inputchar){
      case 'r'://読み込み
      digitalWrite(AD,HIGH);
      digitalWrite(DD,LOW);
      digitalWrite(RW,HIGH);
      digitalWrite(CE,LOW);
      digitalWrite(OE,LOW);
      Serial.println("READ");
      break;
      case 'w'://書き込み
      digitalWrite(AD,HIGH);
      digitalWrite(OE,HIGH);
      digitalWrite(CE,LOW);
      digitalWrite(RW,LOW);
      digitalWrite(DD,HIGH);
      /*digitalWrite(CE,HIGH);
      digitalWrite(RW,HIGH);*/
      Serial.println("WRITE");
      break;
      case 's': //SET
      digitalWrite(OE,HIGH);
      digitalWrite(CE,HIGH);
      digitalWrite(RW,HIGH);
      
      digitalWrite(DD,LOW);
      digitalWrite(AD,LOW);
      Serial.println("SET");
      break;
    }
  }
}

コメント

このブログの人気の投稿

ファミコンの完全自作ROM&カセットを作ろう!!その1~立ちはだかるコンパイラの壁~

ファミリーベーシックでゲームプログラミング

ファミコンの完全自作ROM&カセット作ろう!〜cc65で起動ROMをつくる〜