LED ma trận 8×8: Lập trình đếm từ 0 đến 9

led ma tran dem tu 0 den 9

Bài viết này sẽ hướng dẫn các bạn lập trình cho LED ma trận để đếm từ 0 đến 9. Trước khi bắt đầu, chúng ta sẽ tìm hiểu về các font chữ của các số từ 0 đến 9.

Giới thiệu về phần mềm LCD Font Maker

Để dễ dàng lấy font, chúng ta cần sự trợ giúp của phần mềm. Hãy tải phần mềm này tại đây. Mình đã tạo sẵn mã cho các số từ 0 đến 9 và chúng ta sẽ lưu mã này vào một mảng hai chiều.

Điều khiển LED ma trận bằng phương pháp ngắt TIMER

Trong việc điều khiển hiển thị LED, chúng ta thường sử dụng phương pháp ngắt để quét LED. Đây giống như một module tự động quét LED và hiển thị lên màn hình cho chúng ta. Trong hàm main, ta có thể làm những công việc khác.

Tuy nhiên, giữa hàm main và hàm ngắt phải có một mối liên hệ nhất định để hàm main có thể điều khiển hiển thị. Vì vậy, chúng ta cần sử dụng một bộ đệm hiển thị – một mảng dữ liệu chứa dữ liệu cần hiển thị. Khi hàm main muốn hiển thị, ta chỉ cần ghi dữ liệu vào bộ đệm. Hàm ngắt sẽ tự động lấy dữ liệu từ bộ đệm để hiển thị đều đặn và tự động.

Khởi tạo bộ đệm

Tùy vào số lượng LED và cách điều khiển, chúng ta sẽ cần các bộ đệm có kích thước khác nhau. Trong ví dụ này, chúng ta có LED ma trận 8×8 (tức là 64 LED). Mỗi LED có 2 trạng thái ON và OFF tương ứng với 1 và 0. Vì vậy, chúng ta sẽ cần 64 bit dữ liệu cho bộ đệm (tương ứng với 8 byte). Tạo một bộ đệm có 8 byte dữ liệu như sau:

Mối quan hệ giữa bộ đệm và LED thật

Thuật toán điều khiển như sau: Một bộ đệm được tạo ra để lưu trữ trạng thái sáng hoặc tắt của LED. Mỗi bit dữ liệu tương ứng với một LED. Một chương trình ngắt timer tự động gọi sau một khoảng thời gian nhất định để lấy dữ liệu từ bộ đệm và xuất tín hiệu điều khiển ra LED. Đây là công việc tự động, vì vậy chúng ta chỉ cần xây dựng chương trình ngắt và “quẳng” nó đi luôn! Công việc của chúng ta là “vẽ” những gì cần hiển thị vào bộ đệm.

Xây dựng module ngắt

Module ngắt sẽ tự động lấy dữ liệu từ bộ đệm và hiển thị lên màn hình LED. Để làm được việc này, chúng ta cần sử dụng một bộ đếm thời gian. Khi bộ đếm đếm đến một khoảng thời gian nhất định, chương trình ngắt sẽ tự động gọi. Khoảng thời gian này quyết định tần số quét LED của chúng ta. Tần số càng cao càng tốt, nhưng quá cao sẽ khiến chương trình chỉ tập trung vào ngắt và bỏ bê hàm main. Vì vậy, chúng ta cần lựa chọn tần số ngắt phù hợp dựa trên tài nguyên và tốc độ của vi điều khiển.

Mỗi lần ngắt tương ứng với việc quét một hàng hoặc một cột. Trong module ma trận 8×8 của chúng ta, cần quét 8 lần để hoàn thành một bảng. Vì vậy, chúng ta cần 8 lần ngắt cho một khung hình. Giả sử ta muốn quét ở tần số khoảng 120 khung hình mỗi giây. Vậy tần số ngắt sẽ là xấp xỉ 1 giây / (120*8) = 0.001s = 1ms.

Với vi điều khiển 89s52 và thạch anh 12Mhz chia 12 (còn 1Mhz), mỗi xung đếm trong 1us, cần 1000 xung để đếm được 1ms. Vì vậy, ta sẽ cài đặt timer ở chế độ 16bit và nạp giá trị 0xFC17 vào thanh ghi TH1 và TL1.

OK, bây giờ chúng ta sẽ xây dựng hàm ngắt.

Trước khi đi vào mô tả hàm ngắt, hãy tìm hiểu một chút về hàm này! Biến z là một biến đếm từ 0 đến 7. Vì chúng ta quét 8 lần cho một khung hình, nên chỉ cần biến này đếm từ 0 đến 7. Cách khai báo static giống như biến toàn cục nhưng chỉ có thể được sử dụng trong hàm ngắt!
Sau đó, tắt tất cả LED (trước khi xuất dữ liệu, luôn luôn phải tắt LED – nếu không, sẽ xuất hiện hiện tượng bóng ma). Tiếp theo, lấy dữ liệu từ bộ đệm để hiển thị qua cổng P2. Tiếp theo, cho phép LED sáng bằng cách xuất dữ liệu qua cổng P3. Sau đó, tăng biến đếm z để tiếp tục quét.

  • z=0: quét hàng 1
  • z=1: quét hàng 2
  • z=2: quét hàng 3
  • z=3: quét hàng 4
  • z=4: quét hàng 5
  • z=5: quét hàng 6
  • z=6: quét hàng 7
  • z=7: quét hàng 8
  • z=8: kết thúc một khung hình, quay lại từ đầu

Do chúng ta quét theo hàng và mỗi lần ngắt quét một hàng, tổng số hàng cần quét là 8. Phương pháp quét này được gọi là quét 1/8.

Cuối hàm, ta nạp lại giá trị vào thanh TH1 TL1 để đảm bảo mỗi lần ngắt cách nhau 1ms.

OK! Vậy là chúng ta đã xây dựng xong chương trình ngắt (module hiển thị), chúng ta có thể bỏ nó đi mà không cần quan tâm gì nữa. Từ đây, việc lập trình sẽ gần như là lập trình C thuần túy (làm việc với dữ liệu). Bạn có thể tạo thành một thư viện riêng để sử dụng trong các dự án sau này mà không cần quan tâm đến vi điều khiển sẽ sử dụng.

Bây giờ, để hiển thị số bao nhiêu, chỉ cần gọi hàm kèm theo số trong hàm main. Ví dụ, muốn hiển thị số 2:

print_number(2);

Còn muốn đếm từ 0 đến 9 thì sao?

for(int i=0; i<=9; i++){
    print_number(i);
    delay(1000);
}

Đây là mã nguồn đầy đủ cho dự án đếm từ 0 đến 9 trên LED ma trận 8×8.

Tổng kết
Dự án đếm từ 0 đến 9 có vẻ đơn giản, nhưng đoạn mã lại dài hơn rất nhiều so với các đoạn mã mẫu khác trên mạng. Tuy nhiên, khi làm việc với các dự án phức tạp sử dụng LED ma trận như đồng hồ LED với các hiệu ứng đẹp, chúng ta bắt buộc phải sử dụng kỹ thuật quét LED này. Do đó, mình giới thiệu từ bây giờ và cho đến hết tutorial về LED ma trận, chúng ta sẽ sử dụng phương pháp này.

Đây cũng là kỹ thuật được sử dụng trong hầu hết các thiết bị hiển thị và card đồ họa.

Bạn có thể tải file mô phỏng và mã nguồn cho dự án này tại đây.

FEATURED TOPIC

hihi