Tạo màn hình với led 7 đoạn và thanh ghi dịch 74HC595 | Dự án Arduino
Thêm một thanh ghi dịch song song / nối tiếp như 74HC595 phổ biến vào màn hình led 7 đoạn sẽ giúp giảm số lượng chân cần thiết để điều khiển nó (màn hình).
Về cơ bản, màn hình led 7 đoạn cần 9 chân: 8 chân phân đoạn (A, B, C, D, E, F, G và DP) + chân chung. Bằng cách nối tất cả các chân phân đoạn với một thanh ghi thay đổi, số lượng chân cần thiết sẽ giảm còn 3: chân clock và chân dữ liệu (đối với thanh ghi dịch) + chân chung.
Vì vậy, đối với màn hình led 7 đoạn gồm 4 led 7 đoạn, chúng ta chỉ cần 6 chân: clock, dữ liệu và 4 chân chung (mỗi led có chân chung riêng).
Dự án này cho thấy cách xây dựng bộ đếm digital đơn giản bằng Arduino, hiển thị 7 đoạn anode chung với 4 led 7 đoạn và thanh ghi 74HC595.
Yêu cầu phần cứng:
- Board UNO
- Led 7 đoạn loại có 4 led chung
- 74HC595
- 4 x Transistor PNP ( 2SA1015 , 2S9015 , 2N3906 ])
- 8 x Điện trở 100 ohm
- 4 x Điện trở 4,7k ohm
- Nút ấn
- Breadboard
- Dây dẫn
Sơ đồ mạch của dự án:
Hình ảnh dưới đây cho thấy sơ đồ mạch ví dụ của chúng tôi.
Như được hiển thị trong sơ đồ mạch ở trên, tất cả các chân phân đoạn được nối với các chân đầu ra 74HC595, mỗi chân qua điện trở 100 ohm, trong đó:
Đoạn A … G được nối với chân 74HC595 Q7 … Q1 và DP phân đoạn được nối với chân Q0.
Chân dữ liệu của thanh ghi 74HC595 được đặt tên là DS (# 14) và nó được nối với chân Arduino 6.
ST_CP (hoặc RCLK) và SH_CP (hoặc SRCLK) được nối với nhau, sau đó được nối với chân Arduino 7. Đây là chân clock.
Vì màn hình có 4 led 7 đoạn nên có 4 chân chung: 1 (hầu hết bên trái), 2, 3 và 4. Mỗi chân chung được nối với đầu cực collector của một transistor. Điểm mút cực phát của 4 transistor được nối với + 5V từ board Arduino. Điểm mút cơ sở của bốn transistor được nối với Arduino thông qua điện trở 4,7k.
4 transistor cùng loại (PNP).
Nút ấn được nối với chân analog Arduino 0 (A0) được sử dụng để tăng số lượng hiển thị.
Code dự án:
Code Arduino bên dưới không sử dụng bất kỳ thư viện nào cho màn hình 7 đoạn.
Khai báo nút ấn được xác định trong code là:
// counter button definition
#define button A0
Khai báo chân clock và chân dữ liệu được xác định là:
// shift register chân definitions
#define clockChân 7 // chân clock
#define dataChân 6 // chân data
Màn hình cần được làm mới định kỳ, vì tôi đã sử dụng mô-đun Timer1 ngắt với cấu hình sau:
// Timer1 module overflow interrupt configuration
TCCR1A = 0;
TCCR1B = 1; // enable Timer1 with prescaler = 1 ( 16 ticks each 1 µs)
TCNT1 = 0; // set Timer1 preload value to 0 (reset)
TIMSK1 = 1; // enable Timer1 overflow interrupt
Với bộ đếm trước Timer1 = 1, chúng tôi sẽ ngắt mỗi 4096 micro giây. Điều đó có nghĩa là mỗi led 7 đoạn được hiển thị 4096 us. {4096 us = 65536 / (16 * prescaler)}
Lưu ý rằng mô-đun Timer1 là bộ định thời 16 bit và tần số xung Arduino là 16 MHz.
Các hàm được sử dụng trong code:
ISR(TIMER1_OVF_vect): là chức năng ngắt Timer1, khi vi điều khiển bị gián đoạn bởi Timer1, nó sẽ trực tiếp thực hiện ‘chức năng’ này.
void disp(byte number, bool dec_point = 0): chức năng này là dành cho dữ liệu hiển thị trên màn hình 7-segment, nó in biến số có thể thay đổi giữa 0 và 9. Biến dec_point quyết định liệu các DP sẽ được in hay không , giá trị mặc định là 0 (không in), nếu dec_point = 1, phân đoạn DP sẽ BẬT.
void dist_off () : chức năng này sẽ tắt toàn bộ màn hình.
Tôi đã sử dụng chức năng Arduino shiftOut (built-in) để gửi dữ liệu một cách an toàn đến thanh ghi thay đổi 74HC595.
Code Arduino đầy đủ:
// counter button definition#define button A0// shift register pin definitions#define clockPin 7 // clock pin#define dataPin 6 // data pin// common pins of the four digits definitions#define Dig1 5#define Dig2 4#define Dig3 3#define Dig4 2// variable declarationsbyte current_digit;int count = 0;void disp(byte number, bool dec_point = 0);void setup(){pinMode(button, INPUT_PULLUP);pinMode(Dig1, OUTPUT);pinMode(Dig2, OUTPUT);pinMode(Dig3, OUTPUT);pinMode(Dig4, OUTPUT);pinMode(clockPin, OUTPUT);pinMode(dataPin, OUTPUT);disp_off(); // turn off the display// Timer1 module overflow interrupt configurationTCCR1A = 0;TCCR1B = 1; // enable Timer1 with prescaler = 1 ( 16 ticks each 1 µs)TCNT1 = 0; // set Timer1 preload value to 0 (reset)TIMSK1 = 1; // enable Timer1 overflow interrupt}ISR(TIMER1_OVF_vect) // Timer1 interrupt service routine (ISR){disp_off(); // turn off the displayswitch (current_digit){case 1:disp(count / 1000); // prepare to display digit 1 (most left)digitalWrite(Dig1, LOW); // turn on digit 1break;case 2:disp( (count / 100) % 10 ); // prepare to display digit 2digitalWrite(Dig2, LOW); // turn on digit 2break;case 3:disp( (count / 10) % 10 ); // prepare to display digit 3digitalWrite(Dig3, LOW); // turn on digit 3break;case 4:disp(count % 10); // prepare to display digit 4 (most right)digitalWrite(Dig4, LOW); // turn on digit 4}current_digit = (current_digit % 4) + 1;}// main loopvoid loop(){if(digitalRead(button) == 0){count++; // increment ‘count’ by 1if(count > 9999)count = 0;delay(200); // wait 200 milliseconds}}void disp(byte number, bool dec_point){switch (number){case 0: // print 0shiftOut(dataPin, clockPin, MSBFIRST, 0x02 | !dec_point);digitalWrite(clockPin, HIGH);digitalWrite(clockPin, LOW);break;case 1: // print 1shiftOut(dataPin, clockPin, MSBFIRST, 0x9E | !dec_point);digitalWrite(clockPin, HIGH);digitalWrite(clockPin, LOW);break;case 2: // print 2shiftOut(dataPin, clockPin, MSBFIRST, 0x24 | !dec_point);digitalWrite(clockPin, HIGH);digitalWrite(clockPin, LOW);break;case 3: // print 3shiftOut(dataPin, clockPin, MSBFIRST, 0x0C | !dec_point);digitalWrite(clockPin, HIGH);digitalWrite(clockPin, LOW);break;case 4: // print 4shiftOut(dataPin, clockPin, MSBFIRST, 0x98 | !dec_point);digitalWrite(clockPin, HIGH);digitalWrite(clockPin, LOW);break;case 5: // print 5shiftOut(dataPin, clockPin, MSBFIRST, 0x48 | !dec_point);digitalWrite(clockPin, HIGH);digitalWrite(clockPin, LOW);break;case 6: // print 6shiftOut(dataPin, clockPin, MSBFIRST, 0x40 | !dec_point);digitalWrite(clockPin, HIGH);digitalWrite(clockPin, LOW);break;case 7: // print 7shiftOut(dataPin, clockPin, MSBFIRST, 0x1E | !dec_point);digitalWrite(clockPin, HIGH);digitalWrite(clockPin, LOW);break;case 8: // print 8shiftOut(dataPin, clockPin, MSBFIRST, !dec_point);digitalWrite(clockPin, HIGH);digitalWrite(clockPin, LOW);break;case 9: // print 9shiftOut(dataPin, clockPin, MSBFIRST, 0x08 | !dec_point);digitalWrite(clockPin, HIGH);digitalWrite(clockPin, LOW);}}void disp_off(){digitalWrite(Dig1, HIGH);digitalWrite(Dig2, HIGH);digitalWrite(Dig3, HIGH);digitalWrite(Dig4, HIGH);}// end of code.
Video demo dự án: