シフトレジスタについて
シフトレジスタとは・・・
ビット情報を複数のレジスタに記憶させ、同時出力させることのできる装置。
クロック信号に同期してビット情報を順に移動(shift)させることができる シフトレジスタの種類はいくつかあるが、今回使用するものは型番74HC595。
8ビット分の情報を8個のレジスタから同時出力することができる。


シフトレジスタはなぜ必要なの?
結論から言うと、Arduino Unoのデジタルピンの本数が限られているから。

上記画像の数字が印字されている部分がデジタルピン。
0~13番までしかなく、複数の装置を動かす場合に足りなくなることがある。
例えば8個のLED。

全てのLEDを制御するためには8本のデジタル信号が必要になる。

こうなると残りのデジタルピンが6本になってしまい、制御できる装置の数が限られてしまう。
これを解決するためにシフトレジスタを使う。
シフトレジスタの仕組み
今回使用するシフトレジスタ(74HC595)は、1度に8ビットのデータを出力することができる。
※以下画像はデータシートから抜粋したもの。

15、1~7 | QA ~ QH | パラレル出力 |
9 | QH’ | シフトレジスタの最上位ビットの状態を常に出力 |
16 | VCC | 電源( + ) |
14 | SER | ビット入力(デジタルピンの状態を取得) |
13 | OE | HIGH:QA ~ QHの出力を無効にする LOW:QA ~ QHの出力を有効にする ※研修ではLOWにしておく |
12 | RCLK | ストレージレジスタへの書き込みタイミングを知らせるクロック信号 |
11 | SRCLR | QA ~ QHのビットをシフトさせるクロック信号 |
10 | SRCLR | HIGH:シフトレジスタ内の情報を保持する LOW:シフトレジスタ内の情報をクリアする ※1 他のCLKとは非同期 ※2 研修ではHIGHにしておく |
8 | GND | グランド( – ) |
シフトレジスタの流れ
SRCLRはビット情報をクリアしてしまうので、基本はHIGHにしておく。
OEをLOWにし、 QA ~ QHの出力状態を有効にする。
① SERの情報をSRCLRのクロック信号でシフトさせる
② QA → QB → QC → ・・・・QHという流れで1ビットずつシフトさせていく(①を8回繰り返す)
③ RCLRのクロック信号でQA ~ QHの情報をストレージレジスタに反映し、出力する
このようにシフトレジスタを使用することで
デジタルピン1本で8ピンの制御を行うことができる。
※RCLRとSRCLRの制御は別途行う必要があるので、SERと合わせて計3本のデジタルピンを使用する
シフトレジスタを使って8個のLEDを光らせてみよう
電子回路を組み、Arduino UNOにプログラムを書き込んで実際に8個のLEDを制御してみよう。
【 使用するもの 】
・Arduino UNO
・ブレッドボード
・LED × 8
・抵抗 × 8 (この例では330Ωを使用)
・シフトレジスタ
・ジャンパーピン × 必要数
・シリアルケーブル
【電子回路図】

VCC:HIGH
GND:LOW
SER:5番ピン
RCLK:6番ピン
SRCLR:7番ピン
OE:LOW
SRCLR:HIGH
QA ~ QH:左のLEDから順番に

【ソースコード①】
#define SRCLK (7)
#define RCLK (6)
#define SER (5)
void setup() {
pinMode(SRCLK, OUTPUT);
pinMode(RCLK, OUTPUT);
pinMode(SER, OUTPUT);
}
void loop() {
// SERをHIGHにしてビットを1にしておく
digitalWrite(SER, HIGH);
// SRCLK信号を8回送り、SERの1をシフトさせる
for (int i=0; i<8; i++) {
digitalWrite(SRCLK, LOW);
digitalWrite(SRCLK, HIGH);
}
// LEDの変化を見るために10秒後に点灯させる
delay(10000);
// RCLK信号を送り、QA~QHのストレージレジスタに反映させ、出力する
digitalWrite(RCLK, LOW);
digitalWrite(RCLK, HIGH);
}
このソースコードはSERのビット1を8回シフトレジスタにシフトさせ、
10秒後に8個のLEDを点灯させるもの。
SERをLOWにしてシフトさせるとLEDを消灯させることができる。
いろいろ試してみよう。
シフトレジスタを使って8個のLEDを4個ずつ交互に光らせる
今度はLEDを左から順に交互に光らせてみる。
【ソースコード②】
#define SRCLK (7)
#define RCLK (6)
#define SER (5)
// シフトレジスタに送るビット情報を用意しておく
const uint8_t bit = 0b10101010;
// loop回数をカウントし、偶数回と奇数回で変化させる
uint8_t loopCount = 0;
void setup() {
pinMode(SRCLK, OUTPUT);
pinMode(RCLK, OUTPUT);
pinMode(SER, OUTPUT);
}
void loop() {
uint8_t sendBit = bit;
if((loopCount % 2) == 1) sendBit = bit >> 1;
uint8_t maskMSB = 0b10000000;
// SRCLK信号を8回送る
for (int i=0; i<8; i++) {
digitalWrite(SER, (sendBit & maskMSB));
digitalWrite(SRCLK, LOW);
digitalWrite(SRCLK, HIGH);
maskMSB = maskMSB >> 1;
}
// LEDの変化を見るために1秒待つ
delay(1000);
// RCLK信号を送り、QA~QHのストレージレジスタに反映させ、出力する
digitalWrite(RCLK, LOW);
digitalWrite(RCLK, HIGH);
loopCount++;
}


1秒間隔で4個のLEDが交互に点灯するようになった。
他にもLEDを1個ずつ点灯させたり、流れるように点灯させたりと、
ビットの送り方次第で点灯パターンを変えれるので試してみよう。
シフトレジスタをshiftOut()関数で制御する
今までは1ビットずつシフトレジスタにシフトさせていたが、
shiftOut()関数を使うと1バイトのデータをシフトレジスタに送ってくれる。
shiftOut(dataPin, clockPin, bitOrder, value)
第一引数 | dataPin | SERのピン番号 |
第二引数 | clockPin | SRCLKのピン番号 |
第三引数 | bitOrder | ・MSBFIRST 最上位ビットから送信 ・LSBFIRST 最下位ビットから送信 |
第四引数 | value | シフトレジスタに送信するデータ ※型uint8_tの1バイトのみ |
【使用例】
shiftOut(SER, SRCLK, MSBFIRST, 0b11110000);
digitalWrite(RCLK, LOW);
digitalWrite(RCLK, HIGH);
この例ではMSBFIRSTなのでデータの「1」から順にシフトレジスタに送信する。
送信後のシフトレジスタのQA ~ QHはAから順に「0,0,0,0,1,1,1,1」となる。
※SRCLKはsetup()関数でLOWに設定すること
シフトレジスタの連結
シフトレジスタ(74HC595)は連結して使用することができる。
例えばシフトレジスタを2個連結する場合、QH’を2個目のシフトレジスタのSERに回路を繋ぐ。
QH’は1個目のシフトレジスタから溢れたビット(9ビット目以降)を常に出力している。
なので、2バイト分のデータを送信すると1個目のシフトレジスタからシフトされて
2個目のシフトレジスタにシフトされ、データが記憶される。
shiftOut(SER, SRCLK, MSBFIRST, 0b11110000);
shiftOut(SER, SRCLK, MSBFIRST, 0b00001111);
digitalWrite(RCLK, LOW);
digitalWrite(RCLK, HIGH);
上記コードを実行するとシフトレジスタの中身は以下となる。
1個目のシフトレジスタ | QA ~ QH | 1,1,1,1,0,0,0,0 |
2個目のシフトレジスタ | QA ~ QH | 0,0,0,0,1,1,1,1 |
RCLKとSRCLKについて
この2つのクロック信号は接続したデジタルピンのLOWからHIGHへの切り替わりをトリガーにしている。
2個のシフトレジスタが同じクロック信号で良ければ、1個目のクロックピンを2個目のクロックピンに接続すれば良い。
その他のピンについては1個目のシフトレジスタと同じように回路を組む。

Arduino初心者の方にオススメの本です。
電子パーツの使い方などが詳しく書かれています。



シフトレジスタ(74HC595)です。
74HC595の前後のアルファベットは、各メーカー独自のものだったりするので、気にしなくても大丈夫です。
コメント