Hướng dẫn sử dụng IC thanh ghi dịch 74HC595 giao tiếp với Arduino
IC thanh ghi dịch 74HC595 là một linh kiện quan trọng trong các ứng dụng điện tử và dự án sử dụng Arduino. Nó được sử dụng để mở rộng số lượng chân điều khiển đầu ra của Arduino một cách hiệu quả và tiết kiệm chân. Thông qua bài viết các bạn sẽ dần nắm rõ hơn cách hoạt động và cấu tạo của 74HC595 Arduino.
Để tạo động lực cho Team Arduino KIT ra nhiều bài viết chất lượng hơn, các bạn có thể ủng hộ mình bằng cách Donate qua MoMo, Ngân hàng, Paypal…Nhấn vào link bên dưới nhé.
Xem ngay: Hướng dẫn sử dụng module LED ma trận 8×8 MAX7219 với Arduino
Khi nào nên sử dụng IC thanh ghi dịch 74HC595
IC 74HC595 được sử dụng khi các bạn cần mở rộng số lượng đầu ra của Arduino. Dưới đây là một số trường hợp bạn nên sử dụng IC thanh ghi dịch 74HC595.
- Mở rộng số lượng đầu ra: Khi bạn cần điều khiển nhiều thiết bị như đèn LED, động cơ, relay hoặc bất kỳ thiết bị nào khác có đầu vào logic.
- Tiết kiệm chân kết nối: Khi số lượng chân I/O trên Arduino bị hạn chế, các bạn có thể sử dụng IC 74HC595 để mở rộng số lượng đầu ra mà không cần sử dụng nhiều chân đấu nối trên Arduino.
Với IC 74HC595, bạn có thể giao tiếp thông qua giao thức Serial (SPI) để dịch các tín hiệu vào và điều khiển các đầu ra song song. Bằng cách sử dụng các chân dữ liệu và xung clock, bạn có thể dịch các bit dữ liệu vào thanh ghi và điều khiển các đầu ra tương ứng.
Đây là một bộ điều khiển Original Nintendo Controller được phát hành vào năm 1985 là một ứng dụng thực tế sử dụng thanh ghi dịch 74HC595.
IC thanh ghi dịch 74HC595 hoạt động như thế nào?
IC thanh ghi dịch 74HC595 hoạt động dựa trên nguyên tắc dịch tần số (Serial-In, Parallel-Out – SIPO). Nó cho phép bạn dịch các dữ liệu đầu vào theo một chuỗi bit và điều khiển các đầu ra tương ứng theo một chuỗi bit song song.
Quá trình hoạt động của IC 74HC595 như sau:
- Dữ liệu đầu vào (bit) được gửi từ vi điều khiển hoặc nguồn dữ liệu khác vào chân dữ liệu (DS) của IC.
- Một tín hiệu xung clock (số xung điều khiển) được gửi vào chân xung clock (SH_CP) của IC. Mỗi lần tín hiệu xung clock được cung cấp, dữ liệu đầu vào sẽ dịch sang phải một vị trí.
- Dữ liệu đầu vào mới nhất sẽ được lưu trữ trong thanh ghi dịch nội bộ của IC.
- Tiếp theo, một tín hiệu xung đồng bộ (ST_CP) được cung cấp vào chân (ST_CP) của IC. Khi tín hiệu xung đồng bộ được cung cấp, dữ liệu trong thanh ghi dịch sẽ được chuyển sang thanh ghi lưu trữ ngoại vi (output register).
- Các đầu ra song song (Q0-Q7) của IC 74HC595 Arduino kết nối đến các thiết bị ngoại vi như LED, LED matrix, động cơ, relay, v.v. Dữ liệu trong thanh ghi lưu trữ sẽ được chuyển đến các đầu ra tương ứng.
- Khi cung cấp tín hiệu xung đồng bộ tiếp theo, dữ liệu từ thanh ghi dịch sẽ được chuyển sang thanh ghi lưu trữ ngoại vi và các đầu ra tương ứng sẽ thay đổi.
Quá trình trên sẽ tiếp tục cho đến khi tất cả các bit dữ liệu đầu vào được dịch vào IC 74HC595 và các đầu ra tương ứng.
Sơ đồ chân thanh ghi dịch 74HC595
- VCC: Nguồn cấp (+5V).
- GND: Được nối đất (-).
- DS (SER): Chân dữ liệu (Data In) để lấy dữ liệu đầu vào.
- OE: Chân Enable đầu ra (Output Enable), được sử dụng để kích hoạt hoặc vô hiệu hóa đầu ra của IC.
- ST_CP (RCLK): Chân Xung Đồng bộ (Storage Register Clock) để lưu trữ dữ liệu vào thanh ghi lưu trữ ngoại vi.
- SH_CP (SRCLK): Chân Xung Clock (Shift Register Clock) để dịch chuyển dữ liệu từ DS vào thanh ghi dịch.
- MR (SRCLR): Chân Reset Master (Master Reset), được sử dụng để đặt lại trạng thái ban đầu của IC.
- Q1(B)-Q7(H): là các đầu ra song song (parallel output) của IC, được kết nối đến các thiết bị ngoại vi như LED, đèn LED matrix, động cơ, relay,…
- Q0 (QA): Đầu ra thấp nhất (Least Significant Bit) của thanh ghi dịch.
- Q7′ (QH’): Chân này được sử dụng để kết nối nhiều hơn một IC 74HC595 dưới dạng xếp tầng.
Linh kiện cần thiết cho dự án
TÊN LINH KIỆN | SỐ LƯỢNG | NƠI BÁN |
Arduino Uno R3 | 1 | Shopee | Cytron |
IC 74HC595 | 1 | Shopee | Cytron |
LED | 8 | Shopee | Cytron |
Điện trở 220R | 8 | Shopee | Cytron |
Dây cắm | 10-20 | Shopee | Cytron |
Sơ đồ đấu nối IC thanh ghi dịch 74HC595 với Arduino Uno
Kết nối chân 16 (VCC) và 10 (SRCLR) với 5V của Arduino và chân 8 (GND) và 13 (OE) với GND.
Tiếp theo, kết nối ba chân được sử dụng để điều khiển thanh ghi dịch. Kết nối chân 11 (SRCLK), chân 12 (RCLK) và chân 14 (SER) của thanh ghi dịch với các chân 6, 5 và 4 của Arduino.
Tất cả cực âm (chân ngắn) của mỗi đèn LED được nối đất chung và cực dương (chân dài) của mỗi đèn LED nối với chân đầu ra của thanh ghi dịch tương ứng.
Sử dụng một điện trở 220Ω hoặc 330Ω để bảo vệ đèn LED không bị quá tải.
Khi kết nối các đèn LED, hãy đảm bảo rằng QA được kết nối với đèn LED đầu tiên và QH được kết nối với đèn LED cuối cùng; nếu không, đèn LED sẽ không sáng theo đúng thứ tự!
Code ví dụ IC thanh ghi dịch 74HC595 Arduino
Đoạn code bên dưới là một ví dụ về cách sử dụng IC thanh ghi dịch 74HC595 để điều khiển một dãy các đèn LED.
int latchPin = 5; // Latch pin of 74HC595 is connected to Digital pin 5 int clockPin = 6; // Clock pin of 74HC595 is connected to Digital pin 6 int dataPin = 4; // Data pin of 74HC595 is connected to Digital pin 4 byte leds = 0; // Variable to hold the pattern of which LEDs are currently turned on or off /* * setup() - this function runs once when you turn your Arduino on * We initialize the serial connection with the computer */ void setup() { // Set all the pins of 74HC595 as OUTPUT pinMode(latchPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); } /* * loop() - this function runs over and over again */ void loop() { leds = 0; // Initially turns all the LEDs off, by giving the variable 'leds' the value 0 updateShiftRegister(); delay(500); for (int i = 0; i < 8; i++) // Turn all the LEDs ON one by one. { bitSet(leds, i); // Set the bit that controls that LED in the variable 'leds' updateShiftRegister(); delay(500); } } /* * updateShiftRegister() - This function sets the latchPin to low, then calls the Arduino function 'shiftOut' to shift out contents of variable 'leds' in the shift register before putting the 'latchPin' high again. */ void updateShiftRegister() { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, leds); digitalWrite(latchPin, HIGH); }
Khi nạp code thì chương trình sẽ hoạt động như thế này:
Giải thích Code
int latchPin = 5; // Latch pin of 74HC595 is connected to Digital pin 5 int clockPin = 6; // Clock pin of 74HC595 is connected to Digital pin 6 int dataPin = 4; // Data pin of 74HC595 is connected to Digital pin 4
Các biến latchPin, clockPin, và dataPin là các biến đại diện cho chân kết nối giữa Arduino và IC 74HC595. Chúng xác định các chân kết nối được sử dụng cho việc truyền dữ liệu và điều khiển IC.
byte leds = 0; // Variable to hold the pattern of which LEDs are currently turned on or off
Biến leds là một biến byte để lưu trữ mẫu (pattern) của các đèn LED đang được bật hoặc tắt.
void setup() { // Set all the pins of 74HC595 as OUTPUT pinMode(latchPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); }
Trong hàm setup(), chúng ta đặt các chân của 74HC595 Arduino là OUTPUT để sử dụng cho việc truyền dữ liệu và điều khiển.
void loop() { leds = 0; // Initially turns all the LEDs off, by giving the variable 'leds' the value 0 updateShiftRegister(); delay(500); for (int i = 0; i < 8; i++) // Turn all the LEDs ON one by one. { bitSet(leds, i); // Set the bit that controls that LED in the variable 'leds' updateShiftRegister(); delay(500); } }
Trong hàm loop(), đầu tiên, khởi tạo biến leds là 0 để tắt tất cả các đèn LED. Sau đó, chúng ta gọi hàm updateShiftRegister()
để cập nhật dữ liệu trên IC.
Sau đó, trong vòng lặp for, bật từng đèn LED một. Bằng cách sử dụng hàm bitSet(), đặt bit tương ứng của biến leds để bật đèn LED đó. Sau đó, lại gọi hàm updateShiftRegister() để cập nhật dữ liệu trên IC.
void updateShiftRegister() { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, leds); digitalWrite(latchPin, HIGH); }
Hàm updateShiftRegister() thực hiện việc đưa latchPin xuống mức thấp, sau đó gọi hàm shiftOut() để truyền dữ liệu từ biến leds sang IC 74HC595 thông qua các chân dataPin và clockPin. Sau đó, latchPin được đưa lên mức cao để cập nhật dữ liệu trên IC.
Code 2: Thay đổi độ sáng đèn LED bằng PWM
Trong ví dụ này, mình sẽ dùng chân OE trên IC để kiểm soát độ sáng của đèn LED.
Chân OE (Kích hoạt đầu ra) hoạt động như một công tắc. Khi chân này được đặt mức CAO, các chân đầu ra sẽ không hoạt động. Khi OE được đặt ở mức THẤP, các chân đầu ra hoạt động bình thường.
Trong ví dụ trước, mình đã kết nối OE với GND, cho phép đầu ra luôn hoạt động. Dưới đây là trạng thái khi các bạn sử dụng chân Digital của Arduino để lập trình Arduino.
Tuy nhiên, bằng cách kết nối OE với chân có hỗ trợ PWM của Arduino, các bạn có thể kiểm soát độ sáng của đèn LED, giống như hình bên dưới.
Sơ đồ đấu nối
Sơ đồ đấu nối sẽ giống như ví dụ đầu tiên, chỉ cần thay đổi chân 13 (OE) của 74HC595 Arduino. Thay vì kết nối OE với GND, hãy nối nó với chân số 3 Arduino.
Code ví dụ
int latchPin = 5; // Latch pin of 74HC595 is connected to Digital pin 5 int clockPin = 6; // Clock pin of 74HC595 is connected to Digital pin 6 int dataPin = 4; // Data pin of 74HC595 is connected to Digital pin 4 int outputEnablePin = 3; // OE pin of 74HC595 is connected to PWM pin 3 byte leds = 0; // Variable to hold the pattern of which LEDs are currently turned on or off /* * setup() - this function runs once when you turn your Arduino on * We initialize the serial connection with the computer */ void setup() { // Set all the pins of 74HC595 as OUTPUT pinMode(latchPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(outputEnablePin, OUTPUT); } /* * loop() - this function runs over and over again */ void loop() { setBrightness(255); leds = 0; // Initially turns all the LEDs off, by giving the variable 'leds' the value 0 updateShiftRegister(); delay(500); for (int i = 0; i < 8; i++) // Turn all the LEDs ON one by one. { bitSet(leds, i); // Set the bit that controls that LED in the variable 'leds' updateShiftRegister(); delay(500); } for (byte b = 255; b > 0; b--) // Gradually fade all the LEDs back to off { setBrightness(b); delay(50); } } /* * updateShiftRegister() - This function sets the latchPin to low, then calls the Arduino function 'shiftOut' to shift out contents of variable 'leds' in the shift register before putting the 'latchPin' high again. */ void updateShiftRegister() { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, leds); digitalWrite(latchPin, HIGH); } /* * setBrightness() - Generates PWM signal and writes it to OE pin. */ void setBrightness(byte brightness) // 0 to 255 { analogWrite(outputEnablePin, 255-brightness); }
Dưới đây là kết quả khi điều khiển bằng PWM.