Arduinoの基礎 - 74HC595

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
ナビゲーションに移動 検索に移動

概要

シフトレジスタを使用すると、少ない出力ピンで多くの出力を制御することが可能になる。
ここでは、シフトレジスタ(74HC595))とArduino UNOを使用して、8個のLEDを制御する方法を記載する。

以下のように、8個のLEDを順番に点灯させる。
LEDをシフトレジスタに接続して、シフトレジスタの制御用に3本のGPIOを使用する。


シフトレジスタ(74HC595)のピン配置

シフトレジスタ(74HC595)のピン配置は次の通りである。

Arduino 74HC595 1.png


VCCは16番ピン、GNDは8番ピンである。

デジタル出力は、QAからQHの8本、ピン番号はQAから順に、15、1、2、...、7である。ここに、8個のLEDと電流制限用の抵抗を接続する。

9番ピンのQH'は、カスケード用のシリアル出力である。(ここでは使用しない)
カスケード接続については、後述のセクション"シフトレジスタ(74HC595)のカスケード接続"を参照すること。
74HC595を2個カスケード接続(数珠つなぎ)にして、16個のLEDを制御する方法を記載している。

14番ピンのSERは、シリアルデータ入力である。このピンを使用して、Arduinoから8ビットのデータを入力する。
後述のセクションに記載しているが、Arduinoのプログラムにおいて、shiftOut()関数に1バイトのデータを渡すだけである。

12番ピンのRCLK(ストレージ・レジスタ・クロック)は、ラッチ制御用である。データのセット前にLowにして、変更を有効化する時にHighにする。

11番ピンのSRCLK(シフト・レジスタ・クロック)は、74HC595内部のDタイプストレージレジスタにデータをセットするためのクロックである。
なお、SRCLKとRCLKは、両方ともポジティブエッジトリガである。(クロックの立ち上がりでレジスタに値がセットされる)

13番ピンは、OE(Output Enable)ピンである。Lowの時に出力が有効になる。
ここでは、常に有効するのでGNDに接続する。

10番ピンはSRCLR(シリアルクリア)である。このピンをLowにセットすると直ちに出力をクリアできる。
ここでは、5[V]に接続して常にHighにする。

※備考
ピン名の上にバーが記述されている時は、アクティブ・ローを意味する。
これは、Lowの時にそのピンの機能が有効になるということである。


シフトレジスタ(74HC595)の使用

このセクションでは、Arduinoからシフトレジスタ(74HC595)を使用して、8個のLEDを点灯・消灯させる。

回路図

Arduinoからシフトレジスタ(74HC595)を介して8個のLEDを制御するためには、74HC595の出力ピンQAからQHにLEDを接続する。

Arduino 74HC595 2.png


電流を制限するために、ここでは、470[Ω]の抵抗を接続している。

Arduinoとの接続では、3つのGPIOを使用する。(ここでは、 8番ピン〜10番ピンを使用する)
Arduinoの8番ピン(D8)は、74HC595のSER(14番)と接続する。(SERはシリアルデータ入力ピン)
Arduinoの9番ピン(D9)は、74HC595のRCLK(12番)を接続する。(RCLKはラッチ)
Arduinoの10番ピン(D10)は、74HC595のSRCLK(11番)を接続する。(SRCLKはクロック)

その他は、電源、OE、SRCLR、GND等を5[V]およびGNDに接続する。

シフトレジスタ(74HC595)に8ビットデータの入力

74HC595の8個の出力を制御するためには、1バイト(8ビット)のデータをSERピンに入力する。
この8ビットがそれぞれQAからQHまでの8個の出力のオン / オフを決める。

シフトレジスタにデータをセットするためには、shiftOut()関数を使用する。
この時、shiftOut()関数を呼ぶ前に、ラッチ(RCLK)をLowにセットする。
shiftOut()関数の呼び出し後にラッチ(RCLK)をHighにセットすることで出力が有効になる。

 const int PIN_SER    =  8;
 const int PIN_LATCH  =  9;
 const int PIN_CLK    = 10;
 
 void setup()
 {
    pinMode( PIN_SER, OUTPUT );
    pinMode( PIN_LATCH, OUTPUT );
    pinMode( PIN_CLK, OUTPUT );
 
    byte b = B11000000;
 
    digitalWrite(PIN_LATCH, LOW);
    shiftOut(PIN_SER, PIN_CLK, LSBFIRST, b);
    digitalWrite(PIN_LATCH, HIGH);
 }
 
 void loop()
 {
 
 }


上記の例では、セットするデータとしてB11000000としている。(以下のように、10進数で初期化しても同様)

 byte b = (byte)192; // B11000000 or 0xC0 と同じ



シフトレジスタにおけるデータの並び(MSBFIRSTとLSBFIRST)

B11000000をセットする場合、出力QAからQHのどこがHighになり、どこがLowになるのだろうか。
これは、shiftOut()関数を呼ぶ時に渡すフラグで変わる。

B11000000と記述する時、左端のビットをMSB、右端のビットをLSBという。
shiftOut()関数の引数は、第1引数から順に、シリアルデータ入力ピン番号、シフトレジスタクロックピン番号、ビット順、値である。
ビット順は、MSBFIRSTまたはLSBFIRSTのいずれかを指定する。

例えば、値がB11000000、ビット順がLSBFIRSTである場合、LSBの0から入力されて、最初にQAにセットされる。
次のクロック(の立ち上がり)において、QAにセットされていた出力がQBにシフトし、新しく入力された最下位ビットから数えて2番目の0がQAにセットされる。
次のクロックで、QBの値はQCへ、QAの値はQBへ、と1つずつシフトしていく。
こうして最終的に、QA、QB、...、QHそれぞれに、1、1、0、0、0、0、0、0が順番にセットされることになる。

Arduino 74HC595 3.png


ビット順にMSBFIRSTを指定する場合は、MSBからデータが入力されるので、LSBFIRSTの場合と逆の順番になる。

Arduino 74HC595 4.png


このように、シリアルで入力してパラレルで出力を取り出せるタイプを、SIPO(Serial-In Parallel-Out)シフトレジスタという。

Arduino 74HC595 5.png



8個のLEDを順番に点灯させるサンプルコード

このセクションでは、左から右へLEDが流れるように光るサンプルコードを記述する。
以下の例では、点灯するLEDのパターンをbyte型配列で設定して、その配列の要素の値を順番にshiftOut()関数でシフトレジスタにセットしている。

 const int PIN_SER   =  8;
 const int PIN_LATCH =  9;
 const int PIN_CLK   = 10;
 
 byte patterns[] =
 {
    B00000000,
    B10000000,
    B11000000,
    B11100000,
    B11110000,
    B11111000,
    B01111100,
    B00111110,
    B00011111,
    B00001111,
    B00000111,
    B00000011,
    B00000001,
    B00000000
 };
 
 void setup()
 {
    pinMode( PIN_SER, OUTPUT );
    pinMode( PIN_LATCH, OUTPUT );
    pinMode( PIN_CLK, OUTPUT );
 }
 
 void loop()
 {
    for ( int i=0; i<sizeof(patterns)/sizeof(byte); i++ )
    {
       digitalWrite( PIN_LATCH, LOW );
       shiftOut( PIN_SER, PIN_CLK, LSBFIRST, patterns[i] );
       digitalWrite( PIN_LATCH, HIGH );
       delay(200);  
    }
 }



シフトレジスタ(74HC595)のカスケード接続

このセクションでは、2個の74HC595をカスケード接続することにより、16個のLEDをオン / オフする方法を記載する。

74HC595のカスケード接続には、9番ピン(カスケード用シリアル出力)を使用する。
前段の74HC595の9番ピン(カスケード用シリアル出力)を、後段の74HC595の14番ピン(シリアルデータ入力)に接続する。
これにより、前段の74HC595のSER(シリアル入力)から入力されたデータが、カスケード接続された後段の74HC595に次々と伝達される。


2個のシフトレジスタ(74HC595)をカスケード接続して、16個のLEDを制御する

2個の74HC595を使用して、16個のLEDをオン / オフする場合、下図のように接続する。

Arduino 74HC595 6.png


その他の接続は、上記セクションの場合と同様である。
この場合も、Arduinoからの出力で必要になるのは、データ、ラッチ、クロックの3つの出力だけである。

Arduinoのプログラムを以下のように記述する。

 const int PIN_SER   =  8;
 const int PIN_LATCH =  9;
 const int PIN_CLK   = 10;
 
 void setup()
 {
    pinMode( PIN_SER, OUTPUT );
    pinMode( PIN_LATCH, OUTPUT );
    pinMode( PIN_CLK, OUTPUT );
 
    byte b1 = B11010001;
    byte b2 = B00110011;
 
    digitalWrite(PIN_LATCH, LOW);
    shiftOut(PIN_SER, PIN_CLK, LSBFIRST, b2);
    shiftOut(PIN_SER, PIN_CLK, LSBFIRST, b1);
    digitalWrite(PIN_LATCH, HIGH);
 }
 
 void loop()
 {
 
 }


下図左が前段のシフトレジスタ(74HC595)で、下図右が後段のシフトレジスタ(74HC595)である。
前段のシフトレジスタ(74HC595)はArduinoからシリアルデータ入力されて、後段のシフトレジスタ(74HC595)の入力は前段のシフトレジスタのカスケード用シリアル出力に接続している。
また、LEDの配置はQAからQHが左から右に並ぶように配線している。

Arduino 74HC595 7.png


プログラムのデータ書き込み部分を見ると、最初に1バイトのデータ変数b2LSBFIRSTのビット順で入力している。
続いて、1バイトのデータ変数b1を入力している。
このため、先に入力された変数b2のデータB00110011が、後段のシフトレジスタにセットされる。
また、後に入力した変数b1のデータB11010001が前段のシフトレジスタにセットされる。

LSBFIRSTのビット順なので、プログラムに記載したB11010001とB00110011がそのままLEDのオン(1がON)、オフ(0がOFF)となる。

 byte b1 = B11010001;
 byte b2 = B00110011;
 
 digitalWrite(PIN_LATCH, LOW);
 shiftOut(PIN_SER, PIN_CLK, LSBFIRST, b2);
 shiftOut(PIN_SER, PIN_CLK, LSBFIRST, b1);
 digitalWrite(PIN_LATCH, HIGH);