アフィリエイト広告
アフィリエイト広告

Arduinoで 74HC597 (PISOシフトレジスタ) を制御する

今回は、シフトレジスタ 74HC597 を使って、8ビットのデータを shiftIn() 関数で Arduino へ読み込む動作の実験をしてみました。

PISO シフトレジスタについては、論理回路のひとつとして過去に勉強していますので、そちらも参照ください。

74HC597 の概要

74HC597 はパラレル入力シリアル出力 (Parallel-In, Serial-Out, PISO) タイプのシフトレジスタです。74HC595 のようにストレージレジスタを内蔵していますが、こちらは入力側がストレージレジスタになっています。詳細はデータシートを参照してください。

基本的な制御方法は、

  1. ストレージクロック STCP を送り、パラレルデータをストレージレジスタに読み込む
  2. パラレルロード PL でストレージレジスタのデータをシフトレジスタへ移す
  3. シフトクロック SHCP によりデータを順次シフトし、シリアル信号 Q7 としてに出力する

です。Arduinoでは、STCPPL を送信した後、shiftIn() 関数で SHCP を送ってシリアルデータを受け取ります。

74HC597 の初期化はマスタリセット MR を LOW にすることで行なえます。今回は、抵抗でプルダウンしておき、Arduinoが起動した後にデジタル出力により HIGH にするという方法にしました。こうすることで、Arduino の起動前の不定な動作を抑止できます。

74HC597 の動作の確認

シフトレジスタ 74HC597 からシリアルデータを出力し、Arduino で読み取る動作を確認します。

回路図

図1 が、シフトレジスタ 74HC597 の動作を確認するための実験回路です。

74HC597の動作の実験回路図
図1. 74HC597 動作の実験回路

左の Dipスイッチで 8ビットのデータを作り、それを 74HC597 のパラレル入力に渡します。
シリアル入力 DS は使用しませんので、GND に落としておきます。ストレージクロック STCP、シフトクロック SHCP、マスタリセット MR は、それぞれ Arduino より制御します。MR は抵抗でプルダウンし、Arduino の起動前に LOW にしておくことでシフトレジスタを初期化します。
シリアル出力 Q7 は Arduino へ送ります。Arduino では shiftIn() 関数を使用してデータを読み込みます。

JKフリップフロップ CD4027 を利用した RSラッチは、パラレルロード PL の制御を行なっています。Arduino からのパラレルロード制御信号 PARL で RSラッチをセットし、シフトクロック SHCP でリセットします。 この働きについては後述します。

電源は Arduino を接続したパソコンから USB で供給しています。IC の駆動電源は Arduino の 5V 出力を使用します。受けとったデータは、Arduino IDE のシリアルモニタで確認しています。Arduino は Nano Every を使用しました。NANO でも UNO でも、同様に動くと思います。

スケッチ

シフトレジスタ 74HC597 が出力する 8ビットシリアルデータを Arduino で読み取り、シリアルモニタへ出力する動作確認用のスケッチです。

  1. // Shift Register 74HC597 Test Sketch 2023.9.6 meyon230
  2. const byte STcp_Pin = 9; // Storage Clock
  3. const byte SHcp_Pin = 13; // Shift Clock
  4. const byte PARL_Pin = 10; // Parallel Load
  5. const byte MR_Pin = 8; // Master Reset
  6. const byte Q7_Pin = 12; // Serial Data
  7. void setup() {
  8.   pinMode(STcp_Pin, OUTPUT);
  9.   pinMode(SHcp_Pin, OUTPUT);
  10.   pinMode(PARL_Pin, OUTPUT);
  11.   pinMode(MR_Pin, OUTPUT);
  12.   Serial.begin(9600);
  13.   digitalWrite(MR_Pin, HIGH);
  14. }
  15. void loop() {
  16.   static byte serialData = 0;
  17.   digitalWrite(STcp_Pin, HIGH);
  18.   digitalWrite(STcp_Pin, LOW);
  19.   digitalWrite(PARL_Pin, HIGH);
  20.   digitalWrite(PARL_Pin, LOW);
  21.   serialData = shiftIn(Q7_Pin, SHcp_Pin, MSBFIRST);
  22.   Serial.println(serialData, BIN);
  23.   delay(100);
  24. }

特に説明するまでもないと思います。
17行目で MR を HIGH にして、シフトレジスタの動作を開始させています。23~24行目がストレージクロック STCP の出力、25~26行目がパラレルロード制御信号 PARL の出力です。digitalWrite() の処理には数μsかかりますので、コマンドを連続して記述しても出力されるパルス幅は十分にあります。

RSラッチの働き – 8ビットすべてを読み込む

shiftIn() 関数によるシリアルデータの読み込みのタイミングダイヤグラムを、図2 に示します。

shiftyIn()関数の動作のタイミングダイヤグラム
図2. shiftIn() 動作のタイミングダイヤグラム

まず、ストレージクロック STCP を送り、パラレルデータをストレージレジスタに取り込みます。次にパラレルロード PL を送り、ストレージレジスタからシフトレジスタにデータを移します。その後 shiftIn() 関数によりシフトクロック SHCP が送られて、シリアル出力 Q7 が Arduino に読み込まれます。

ところが、PL が送られたときに Q7 にはビットデータ D7 が出力されますから、shiftIn() 関数が SHCP を HIGH にするとデータがシフトしてしまいます。shiftIn() 関数は SHCP を HIGH にしてからデータを読み込むので、結果的に D7 を読み落としてしまいます。

この不具合を改善するために、SHCP が入るまで RSラッチで PL を保持するようにしました。PL が LOW の間はデータはシフトしませんので、最初の SHCP でデータがシフトしてしまうことを抑止できます。

動作を改善したタイミングダイヤグラム
図3. shiftIn() 動作を改善したタイミングダイヤグラム

図3 が、RSラッチにより動作を改善したタイミングダイヤグラムです。

Arduino から PARL 信号を出力して RSラッチをセットすると、反転出力 Q が LOW になりますから、これを PL としてシフトレジスタに送ります。SHCP が入ったとき PL は LOW ですから、データはシフトせず、D7 を読み込むことができます。

RSラッチは最初の SHCP でリセットされ、PL は RSラッチの遅延時間の後に HIGH になりますから、データのシフトは 2つ目の SHCP が入ったときから始まります。こうして、8ビットすべてのビットを読み込めるようになります。

動作状況

シリアルモニタの出力状況
図4. シリアルモニタ出力状況

図4 は、シリアルモニタの出力状況です。

Dipスイッチは、

  1. OFF (LSB)
  2. ON
  3. ON
  4. OFF
  5. ON
  6. OFF
  7. ON
  8. ON (MSB)

となっています。

Arduino が読み込んだデータは 0b11010110 ですから、合致していますね。Dipスイッチをいろいろに設定して、それに応じたデータが表示されることを確認しました。

ブレッドボード

ブレッドボードのようす
図5. ブレッドボードのようす

図5 は、実験中のブレッドボードと出力波形です。

ブレッドボードは、左から Dipスイッチ、シフトレジスタ 74HC597、JKフリップフロップ CD4027、Arduino Nano Every と並んでいます。

オシロスコープの表示波形は、Arduino から送られた SHCP (黄) とシリアル出力 Q7 (青) です。
Q7 の最初の立ち上がりは、PL が LOW になったタイミングです。shiftIn() 関数は SHCP が HIGH の位置でデータを読み取りますので、波形からも「11010110」と読み取っているであろうことがわかります。

後記

今回は、PISO シフトレジスタ 74HC597 を使用して 8ビットのパラレルデータをシリアルデータに変換し、Arduino に shiftIn() 関数で読み込む回路の実験をしました。

シフトレジスタといえば、74HC595 (SIPO) を使って Arduino のデジタル出力ピンを増やすことができるといわれます。逆に考えれば、74HC597 (PISO) を利用すればデジタル入力ピンを増やすことが可能になります。
ググってみつけた PISO シフトレジスタ 74HC165 (ストレージレジスタなし) を利用した記事を読むと、やはり shiftIn() 関数では先頭のビットを読めないことが書かれています。そのために shiftIn() 関数を利用せずに、独自にプログラムされているようです。

今回の実験では、8ビットすべてを読み込む処理をハードウェアで対応しました。そのため、shiftIn() 関数がそのまま利用できます。

当初、単純に読み込みシーケンスを実行したので 7ビットしか読み込めませんでした。少しばかり頭を悩ませたのですが、最近フリップフロップやラッチについていろいろ考えていたせいか、わりと簡単に解決できてしまったように思います。知識の積み重ねがちょっとは役に立ったかな、と。

さて、これシリアル伝送の第一歩目になりますか? Arduino との組み合わせを考えるなら、次は SPI ですか? ゆっくり勉強してみます、考えて … みましょう (;´Д`)

タイトルとURLをコピーしました