Điều khiển LED 7 đoạn common anode với MAX7219

Mô tả dự án: 
MAX7219 hoặc MAX7221 là 1 con chip thú vị, nó tích hợp nối tiếp vào ra dùng điều khiển các ma trận LED tới 64 LED hoặc led 7 đoạn 1-8 số rất phổ biến. Nó có sẵn bộ giải mã BCD code-B, mạch ghép kênh multiplexing, RAM tĩnh 8x8 để lưu số. Tiếc thay MAX7219 được thiết kế để làm việc với các module LED chung cực âm (common-cathode). Các bài hướng dẫn arduino hiện nay bên nước ngoài đều yêu cầu loại common-cathode này và sử dụng thư viện có sẵn LedControl để điều khiển, trong đó có bài này trên arduino.vn.
 
 

Điều khiển LED 7 đoạn chung cực dương

Giới thiệu
MAX7219 hoặc MAX7221 là 1 con chip thú vị, nó tích hợp nối tiếp vào ra dùng điều khiển các ma trận LED tới 64 LED hoặc led 7 đoạn 1-8 số rất phổ biến. Nó có sẵn bộ giải mã BCD code-B, mạch ghép kênh multiplexing, RAM tĩnh 8x8 để lưu số. Tiếc thay MAX7219 được thiết kế để làm việc với các module LED chung cực âm (common-cathode). Các bài hướng dẫn arduino hiện nay bên nước ngoài đều yêu cầu loại common-cathode này và sử dụng thư viện có sẵn LedControl để điều khiển, trong đó có bài này trên arduino.vn.
 
Điều không may là ở Việt Nam chúng ta đa số bán loại chung cực dương (common-anode), sx tại Trung Hoa anh hùng nhằm giảm chi phí. Khi ta sử dụng MAX7219 để kết nối loại module LED này và dùng code arduino có sẵn sẽ không hoạt động (Và có thể gây chết LED). Điều này khiến người mới rất dễ nản vì không biết tại sao, đặc biệt là khi không thể tìm datasheet của các loại linh kiện này.
 
Sơ đồ của con LED common anode ở trên như sau(chú ý các số hiệu A-G):
 
Sơ đồ các chân:
 
Thư viện LedControl cho arduino có chú ý như sau:
For 7-Segment displays only the common cathode-type will work. There is no easy way to make a common anode-type 7-Segment display work with the MAX72XX 
Chỉ có loại chung cực âm mới hoạt động, không dễ để làm cho loại chung cực dương làm việc cùng MAX72xx.
 
Không dễ? Chúng ta hãy làm điều "không dễ" đó nào!

Các bước

Mình sẽ sử dụng MAX7219 điều khiển 1 module led 7 đoạn 2 số chung cực dương, và output bit "manual" không sử dụng thư viện và chế độ BCD code có sẵn của MAX7219. Kết nối ta dùng truyền thông nối tiếp SPI giữa Arduino Nano và MAX7219, tìm hiểu SPI ở đây:

 
Vật tư cần chuẩn bị:
1. Arduino Nano (hay Uno hoặc loại gì có SPI cũng OK)
2. LED 7 đoạn 2 số - 8 số tùy bạn.
3. Các điện trở thích hợp. Ở đây mình mắc 1 điện trở 40kΩ cho MAX7219, còn các điện trở cực A-G và Dp khoảng 220Ω - tùy các bạn tính toán trên cơ sở tiêu thụ của LED 7 đoạn: 3.4V -> 5V và dòng 20mA cho 1 segment.
 
Sơ đồ chân của MAX7219 như sau:
 
Trong các bài hướng dẫn với loại common-cathode LED, họ sẽ nối các chân SEG của MAX7219 vào các chân có mã A-B-C-D-E-F-G-DP của LED module. Còn các chân chung cực từ D1->D4 sẽ nối vào chân DIG0->DIG3 của IC. Như vậy MAX7219 đã map sẵn DIG là khối số, còn SEG là segment (các thanh đoạn LED trong số). Và BCD sẽ map luôn số / ký tự để output ra hình ảnh rất tiện, như sau:
 
 
Trong trường hợp của chúng ta, với loại common-anode, ta phải làm ngược lại bằng cách gắn SEG của LED với DIG của MAX7219, DIG của LED vào SEG MAX7219, cấp dấu: (+) vào D1->Dx của LED, (-) vào các chân A-DP.
Ta đảo ngược sơ đồ MAX7219 common-cathode bằng cách gắn các chân như sau:
chân LED stt chân MAX7219 tên chân
A 2 D0
B 11 D1
C 6 D2
D 7 D3
E 3 D4
F 10 D5
G 5 D6
DP 8 D7

Lắp như vậy xong ta sẽ có các địa chỉ (sẽ dùng với hàm sendCommand trong code):

  1=A
  2=B
  3=C
  4=D
  5=E
  6=F
  7=G
  8=DP
 
Để bớt rườm rà mình không sử dụng segment DP mà chỉ dùng từ A->G
 
Các chân D1->Dx ta gắn vào DIG0->DIG7
trong trường hợp LED 2 số này ta gắn D1 vào chân 14=SEG A, D2 vào chân 16=SEGB
 
Gắn các chân của MAX7219 như sau: 
chân số 0 DIN->Arduino D11
chân số 13 CLK->Arduino D13
chân số 12 LOAD->Arduino D10 (hoặc chân D nào cũng được)
 
Sơ đồ fritzing
 
 
Ta sẽ code như sau:
Khởi tạo chế độ SPI của arduino. 
  Serial.begin(9600);
  pinMode(slaveSelect, OUTPUT);  
 SPI.begin(); //initialize SPI     
Serial.println("TienTN: SPI inited");
 
Tắt chế độ BCD code của MAX7219 đi, kích hoạt module LED
  // Disabled BCD mode  
sendCommand(DECODE_MODE, 0x00); //decode command, if 0x0F use standard 7-segment digits     
//prepare the 7219 to display 7-segment data  
sendCommand (SCAN_LIMIT, 0x07); //in default MAX7219 behaviour, this is for digits block  
sendCommand (INTENSITY,0xF); //set max intensity (range is 0-15)  
sendCommand (SHUTDOWN,0x01); //normal mode (default is shutdown mode)     
sendCommand (DISPLAY_TEST,0x00); //Display test off
 
 
Chú ý: vì không còn BCD mode nữa và không biết có thư viện nào hỗ trợ việc này chưa nên mình đưa từng bit "bằng tay" ra ngoài. Vì mình không kết nối các chân SEG của LED với chân SEG của MAX7219, nên phải điều khiển các segment trên LED qua từng chân DIG.
 
Dùng 1 byte để điều khiển từ 1-8 khối số, tương ứng với 8 cái chân D1-D8 của LED module, nối với SEG A->SEG DP trên chip, ví dụ:
 
sendCommand(1,0b01000000); //ta đang mắc segment A nối với chân DIG0, là chân thứ 2 của MAX7219
                           //các bit từ 0->7 tương ứng các chân SEG A -> SEG DP
                           //segment A của mặt số thứ 2 (bit thứ 2 từ trái qua) gắn với chân SEG B sẽ bật sáng lên
delay(1000);               //chờ 1s
sendCommand(1,0b10000000); //bật segment A của mặt số thứ nhất(bit thứ nhất), tắt segment A của số vừa rồi
 
Như vậy, bạn đã thấy tham số address của sendCommand không phải là mặt số mà lại là số thứ tự LED segment, còn các bit bên trong điều khiển on-off từng led. Ta đã xoay ngược mapping lại.
 
Trong code mình định nghĩa sẵn 1 array các segment theo thứ tự A->DP, sau đó tổ hợp thành bitmask cho tối đa 8 con số trong module LED.
Code đã test trên Uno, Nano và Mega.
 
Kết quả
Bạn có thể thấy là có thêm vào 1 tụ hóa 10uF, 1 tụ sứ 100nF để chống nhiễu (tuy nhiên không bắt buộc)
Bạn có thể sử dụng cách này để điều khiển các loại module khác có common-anode giống như trên.
Chúc các bạn thành công!
lên
5 thành viên đã đánh giá bài viết này hữu ích.
Chuyên mục: 
Các dự án được truyền cảm hứng

Select any filter and click on Apply to see results