[Arduino cơ bản] Giao tiếp LED ma trận

Thảo luận trong 'Arduino' bắt đầu bởi VuPhat.MCA, 14/8/19.

  1. VuPhat.MCA

    VuPhat.MCA New Member

    Bài này chúng ta sẽ cùng tìm hiểu về cách điều khiển LED Matrix bằng phương pháp quét LED + IC mở rộng ngõ ra 74HC595.

    Chuẩn bị:

    a) Arduino UNO R3
    b) IC ghi dịch 74HC595
    c) LED ma trận 8x8
    d) Trở vạch 220Ω

    Sơ đồ kết nối:
    Trong sơ đồ kết nối, chúng ta sử dụng phương pháp quét led ma trận với các chân cột của LED ma trận được nối với chân 2, 3, 4, 5, 6, 7, 8, 9. Các chân hàng được nối với đầu ra của ic dịch bit 74HC595. Chân dữ liệu DS đươc nối với chân 11, chân SHCP được nối với chân 12 và STCP được nối với chân 10. Chân OE được nối với GND và MR được nối với VCC.
    [​IMG]
    IC ghi dịch 74HC595:
    74HC595 là IC ghi dịch 8-bit kết hợp chốt dữ liệu, đầu vào nối tiếp, đầu ra song song. Thường dùng trong các mạch điều khiển LED 7 đoạn, quét LED ma trận,… để tiết kiệm số chân của vi điều khiển. Có thể mở rộng số ngõ ra của vi điều khiển bằng cách mắc nối tiếp đầu vào dữ liệu với các IC74HC595 khác.
    [​IMG]

    Dưới đây là tên và chức năng của các chân IC74HC595:
    [​IMG]

    Các chân SH_CP, ST_CP, DS là 3 chân chúng ta sẽ nối với vi điều khiển, các chân OE và MR thì chúng ta sẽ nối trực tiếp xuống GND và 5V. để cho phép ngõ ra và không cho phép Reset dữ liệu.
    Ví dụ mình cần gửi byte 0b11000011 ra các chân Q0 - Q7, hãy xem biểu đồ thời gian để xem cách chúng hoạt động nhé:
    [​IMG]

    Cách sử dụng IC dịch bit 74HC595:
    B1) Khởi tạo ban đầu SH_CP, ST_CP, DS là đầu ra có giá trị khởi tạo ban đầu là mức thấp.
    B2) Lấy từng bit của byte (lấy MSB trước) sau đó kiểm tra, nếu bit = 1 thì kéo chân DS lên mức cao, ngược lại nếu bit = 0 thì kéo DS xuống mức thấp. Với từng bit chúng ta sẽ tạo xung L-to-H (sườn lên) tại SH_CP để dịch từng bit đó.
    B3) Sau khi dịch xong toàn bộ bit, ta sẽ tạo ra một xung L-to-H để chốt dữ liệu ra ngõ ra.

    Phương pháp quét LED ma trận:
    LED ma trận có cấu tạo gồm các LED được mắc như hình dưới đây, trong đó các chân Anot của các hàng được nối chung với nhau, các chân Katot của các cột được nối chung với nhau.
    Để bật hiển thị một điểm ảnh, ví dụ là đèn LED được khoanh đỏ như trong hình, chúng ta chỉ cần kéo C1 xuống mức thấp và R3 lên mức cao.
    [​IMG]
    Tiếp theo chúng ta cùng đi tìm hiểu phương pháp quét LED nhé!
    Có hai phương pháp quét led ma trận đó là quét hàng và quét cột. Ở đây mình sẽ giới thiệu phương pháp là quét cột, phương pháp quét hàng cũng tương tự như vậy. Nếu coi các chân từ C1 đến C8 giống như các chân điều khiển D1 đến D8 LED 7 thanh và các chân hàng từ R1 đến R8 là các chân dữ liệu (a, b, c, d, e, …) của LED 7 thanh thì chúng ta sẽ thực hiện các bước như sau:
    Các bước quét LED ma trận:
    B1) Bật hiển thị cột 1 (C1 = LOW), xuất mã của cột 1, trễ khoảng 5ms, tắt hiển thị cột 1 (C1 = HIGH).
    B2) Bật hiển thị cột 2 (C2 = LOW), xuất mã của cột 2, trễ khoảng 5ms, tắt hiển thị cột 2 (C1 = HIGH).

    B8) Bật hiển thị cột 8 (C8 = LOW), xuất mã của cột 8, trễ khoảng 5ms, tắt hiển thị cột 8 (C8 = HIGH).
    Trong sơ đồ nguyên lý, Q0 – Q7 của HC595 được nối với R8 đến R1 của LED matrix, tiếp theo chúng ta sẽ đi tìm mã hiển thị của các cột bằng ví dụ về mã của số 0 và số 1.
    [​IMG]

    Chương trình:
    Mã:
    const int shcpPin = 12; // Chân Arduino nối với SHCP HC595
    const int stcpPin = 10; // Chân Arduino nối với STCP HC595
    const int dataPin = 11; // Chân Arduino nối với DS HC595
    
    const int col1Pin = 2; // Chân Arduino nối với cột 1 LED Ma trận
    const int col2Pin = 3; // Chân Arduino nối với cột 2 LED Ma trận
    const int col3Pin = 4; // Chân Arduino nối với cột 3 LED Ma trận
    const int col4Pin = 5; // Chân Arduino nối với cột 4 LED Ma trận
    const int col5Pin = 6; // Chân Arduino nối với cột 5 LED Ma trận
    const int col6Pin = 7; // Chân Arduino nối với cột 6 LED Ma trận
    const int col7Pin = 8; // Chân Arduino nối với cột 7 LED Ma trận
    const int col8Pin = 9; // Chân Arduino nối với cột 8 LED Ma trận
    
    // Mã LED Ma trận
    unsigned char matrixHex[10][8] = {
      {0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c},
      {0x08, 0x18, 0x28, 0x08, 0x08, 0x08, 0x08, 0x3e},
      {0x3c, 0x42, 0x02, 0x04, 0x08, 0x10, 0x20, 0x7e},
      {0x3c, 0x42, 0x02, 0x1c, 0x02, 0x02, 0x42, 0x3c},
      {0x04, 0x08, 0x10, 0x20, 0x44, 0x7e, 0x04, 0x04},
      {0x7e, 0x40, 0x40, 0x3c, 0x02, 0x02, 0x42, 0x3c},
      {0x3c, 0x42, 0x40, 0x7c, 0x42, 0x42, 0x42, 0x3c},
      {0x7e, 0x02, 0x04, 0x08, 0x10, 0x10, 0x10, 0x10},
      {0x3c, 0x42, 0x42, 0x3c, 0x42, 0x42, 0x42, 0x3c},
      {0x3c, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x42, 0x3c}
    };
    
    void setup() {
      // Cấu hình các chân nối với Arduino là đầu ra
      pinMode(shcpPin, OUTPUT);
      pinMode(stcpPin, OUTPUT);
      pinMode(dataPin, OUTPUT);
      pinMode(col1Pin, OUTPUT);
      pinMode(col2Pin, OUTPUT);
      pinMode(col3Pin, OUTPUT);
      pinMode(col4Pin, OUTPUT);
      pinMode(col5Pin, OUTPUT);
      pinMode(col6Pin, OUTPUT);
      pinMode(col7Pin, OUTPUT);
      pinMode(col8Pin, OUTPUT);
    }
    
    void loop() {
      // Đếm từ 0 đến 9
      for (int num = 0; num < 10; num++) {
        // Lặp 25 lần tạo trễ khoảng  8 * 5 * 25 = 1000ms
        for (int i = 0; i < 25; i++) {
          // Bật hiển thị cột 1
          MATRIX_setCol(0, 1, 1, 1, 1, 1, 1, 1);
          // Xuất mã của cột 1
          HC595_shiftOut(matrixHex[num][0]);
          // Trễ 5mss
          delay(5);
          // Tắt hiển thị cột 1
          MATRIX_setCol(1, 1, 1, 1, 1, 1, 1, 1);
    
          // Bật hiển thị cột 2
          MATRIX_setCol(1, 0, 1, 1, 1, 1, 1, 1);
          // Xuất mã của cột 2
          HC595_shiftOut(matrixHex[num][1]);
          // Trễ 5ms
          delay(5);
          // Tắt hiển thị cột 2
          MATRIX_setCol(1, 1, 1, 1, 1, 1, 1, 1);
    
          // Tương tự với các cột khác
          MATRIX_setCol(1, 1, 0, 1, 1, 1, 1, 1);
          HC595_shiftOut(matrixHex[num][2]);
          delay(5);
          MATRIX_setCol(1, 1, 1, 1, 1, 1, 1, 1);
    
          MATRIX_setCol(1, 1, 1, 0, 1, 1, 1, 1);
          HC595_shiftOut(matrixHex[num][3]);
          delay(5);
          MATRIX_setCol(1, 1, 1, 1, 1, 1, 1, 1);
    
          MATRIX_setCol(1, 1, 1, 1, 0, 1, 1, 1);
          HC595_shiftOut(matrixHex[num][4]);
          delay(5);
          MATRIX_setCol(1, 1, 1, 1, 1, 1, 1, 1);
    
          MATRIX_setCol(1, 1, 1, 1, 1, 0, 1, 1);
          HC595_shiftOut(matrixHex[num][5]);
          delay(5);
          MATRIX_setCol(1, 1, 1, 1, 1, 1, 1, 1);
    
          MATRIX_setCol(1, 1, 1, 1, 1, 1, 0, 1);
          HC595_shiftOut(matrixHex[num][6]);
          delay(5);
          MATRIX_setCol(1, 1, 1, 1, 1, 1, 1, 1);
    
          MATRIX_setCol(1, 1, 1, 1, 1, 1, 1, 0);
          HC595_shiftOut(matrixHex[num][7]);
          delay(5);
          MATRIX_setCol(1, 1, 1, 1, 1, 1, 1, 1);
        }
      }
    }
    
    // Hàm gửi dữ liệu ra HC595
    void HC595_shiftOut(unsigned char b) {
      // Đặt lại chân SHCP và STCP
      digitalWrite(shcpPin, LOW);
      digitalWrite(stcpPin, LOW);
    
      for (int i = 0; i < 8; i++) {
        // Lấy từng bit (MSB trước) của byte cần xuất để kiểm tra
        // Nếu bit đó khác 0
        if (b & (0x80 >> i)) {
          // Kéo chân DS lên mức cao
          digitalWrite(dataPin, HIGH);
        // Ngược lại
        } else {
          // Kéo chân DS xuống mức thấp
          digitalWrite(dataPin, LOW);
        }
    
        // Tạo xung L-to-H dịch dữ liệu
        digitalWrite(shcpPin, LOW);
        delayMicroseconds(1);
        digitalWrite(shcpPin, HIGH);
      }
    
      // Tạo xung L-to-H chốt dữ liệu
      digitalWrite(stcpPin, LOW);
      delayMicroseconds(1);
      digitalWrite(stcpPin, HIGH);
    }
    
    // Hàm đặt mức logic cho các cột
    void MATRIX_setCol(int c1, int c2, int c3, int c4, int c5, int c6, int c7, int c8) {
      // Xuất giá trị ra chân nối với cột 1
      digitalWrite(col1Pin, c1);
    
      // Tương tự cho các cột khác
      digitalWrite(col2Pin, c2);
      digitalWrite(col3Pin, c3);
      digitalWrite(col4Pin, c4);
      digitalWrite(col5Pin, c5);
      digitalWrite(col6Pin, c6);
      digitalWrite(col7Pin, c7);
      digitalWrite(col8Pin, c8);
    }
    
    Kết quả:
    Quan sát LED ma trận, chúng ta thấy LED ma trận hiển thị đếm giá trị từ 0 đến 9.
     
    Last edited: 15/8/19

trang này