[Arduino範例] 使用74HC595移位暫存器,控制多個LED燈

只要是學過Arduino的人都知道如何控制LED燈,1顆沒問題,3顆5顆沒題,但如果是8顆呢?等等,程式是沒問題,但接完LED,腳位也差不多用完了!這時74HC595就派上用場了,它可以用3個腳位控制8個以上的LED!

74HC595是一顆移位暫存器 (Shift Register),使用這顆晶片,你只需要Arduino的三個接腳,就可以同時控制八個輸出。74HC595是可以串聯多顆來得到更多輸出的腳位,如果串聯2顆就能控制16顆LED燈,以此類推。這次我們先用單顆74HC595進行練習。

另外,移位暫存器不只有74HC595,也有其它選擇的,像是STP16C596,單顆就能提供16個通道,每個通道還能提供高達120mA的電流,遠大於74HC595的25-35mA,不過我們本範例還是先介紹最常見的74HC595哦。

想了解移位暫存器原理的朋友可以參考WiKi上的解說:

https://zh.wikipedia.org/wiki/移位寄存器

74HC595有16個腳位,每個腳位的名稱如下:

74HC595的16個腳位,其中Q0~Q7可以用來接8顆LED,以本次的範例來說,其它腳位的接法如下:

VCC => 5V

DS => PIN 11 (Data pin)

OE => GND

STCP => PIN 8 (Latch pin)

SHCP => PIN 12 (Clock pin)

MR => 5V

GND => GND

接法其實不難,就是線超多的,而且每顆LED我們還要加上220歐姆的電阻,相信不少人看了接線圖就眼花了吧,不過一定要把線都接正確哦!

送出資料會用到shiftOut()這個函式,而函式所需要的資料類型為byte,也就是0-255的數字,用來表示8bit的資料,每一個通道一個bit,用0和1來代表LOW和HIGH,也就是LED的亮與不亮。

舉例來說,如果要讓第1、3、5、7,4個燈亮,2、4、6、8,4顆燈不亮,那就是10101010,換算成10進位就是170。

換算的方法應該有上過電概的人就會了,只是很多人都忘了吧^^,沒關係,有不少網站提供換算的功能,Google一下就有了,以下網站是傑森找到的,大家可以參考看看。

https://www.binaryhexconverter.com/binary-to-decimal-converter

我們要做的範例很簡單,就是讓8顆燈,4顆4顆交錯輪流亮,先亮1、3、5、7,再亮2、4、6、8,也就是10101010、01010101,換算十進位就是170和85。

int latchPin = 8; // Latch pin (STCP腳位)

int clockPin = 12; // Clock pin (SHCP腳位)

int dataPin = 11; // Data pin (DS腳位)

void setup()

{

// Set all the pins of 74HC595 as OUTPUT

pinMode(latchPin, OUTPUT);

pinMode(dataPin, OUTPUT);

pinMode(clockPin, OUTPUT);

}

void loop()

{

digitalWrite(latchPin, LOW); // 送資料前要先把 latchPin 設成低電位

shiftOut(dataPin, clockPin, LSBFIRST, 170); //送出資料,170就是2進位的10101010

digitalWrite(latchPin, HIGH); // 送完資料後要把 latchPin 設成高電位

delay(300);

digitalWrite(latchPin, LOW);

shiftOut(dataPin, clockPin, LSBFIRST, 85); //85就是2進位的01010101

digitalWrite(latchPin, HIGH);

delay(300);

}

程式裡最主要的是shiftOut()這個函式,它需要4個參數:dataPin、clockPin、資料順序(LSBFIRST由右至左、MSBFIRST由左至右)、資料。其中資料順序我們用的是LSBFIRST,而資料則是填入170或85。

還有一點很重要的,就是在shiftOut()送出資料前,必須先將latchPin設為低電位,送完資料再把latchPin設回高電位。

我們用了兩段程式,分別送出170和85,間隔0.3秒,寫入程式後,就可以看到LED開始閃爍變化囉!

另外再送上另一個範例,就是常見的流水燈,這個例子是由第8顆燈開始亮起,依序亮到第1顆燈,然後全滅,再重覆。

int latchPin = 8; // Latch pin (STCP腳位)

int clockPin = 12; // Clock pin (SHCP腳位)

int dataPin = 11; // Data pin (DS腳位)

byte leds = 0; // 亮燈的LED數量

void setup()

{

// Set all the pins of 74HC595 as OUTPUT

pinMode(latchPin, OUTPUT);

pinMode(dataPin, OUTPUT);

pinMode(clockPin, OUTPUT);

}

void loop()

{

leds = 0; // 一開始燈全滅,所以設為0

updateShiftRegister(); //進行送資料的副程式

delay(500);

for (int i = 0; i < 8; i++) //依序亮燈

{

bitSet(leds, i); // 經由多少燈要亮的i,換算成10進位,並把結果交給leds

updateShiftRegister(); //進行送資料的副程式

delay(100);

}

}

void updateShiftRegister()

{

digitalWrite(latchPin, LOW);

shiftOut(dataPin, clockPin, LSBFIRST, leds);

digitalWrite(latchPin, HIGH);

}