Sunday, February 1, 2015

Ma trận phím và thiết kế cải tiến

Ma trận phím thường được sử dụng khi chúng ta muốn sử dụng số lượng lớn phím bấm cũng như các loại công tắc,cảm biến 2 trạng thái.Quét ma trận phím về nguyên lý thực ra không khó,tuy nhiên trong các thiết kế ma trận phím thông thường có một nhược điểm là chỉ cho phép bấm 1 nút tại một thời điểm,nếu không sẽ đọc sai kết quả.Bài này mình sẽ giới thiệu về ma trận phím,cách quét và thiết kế của ma trận kiểu mới.

1.Ma trận phím và cách đọc ma trận phím

Ma trận phím có nhiều kích thước,ở đây mình giới thiệu ma trận kích thước 2x2,được bố trí theo dạng 2 hàng 2 cột.Cũng giống như ma trận LED, các nút nhấn ở cùng hàng và cột được nối với nhau,vì thế như ma trận phím bên dưới có 4 ngõ ra (2 hàng , 2 cột).



Các cổng 1,2,A,B sẽ được nối trực tiếp với các chân I/O của VĐK . Khi nhấn nút SW 65 chẳng hạn,thì cổng 1 sẽ thông với cổng A,giả sử công A được nối với GND thì cổng 1 cũng sẽ được nối GND.Tuy nhiên câu hỏi đặt ra là bằng cách kiểm tra trạng thái cổng 1 có thể xác định được nút SW65 có được nhấn hay không.Câu trả lời là không vì có thể nút SW66 được nhấn,VĐK sẽ không thể xác định được nút nào đang được nhấn.Giải pháp đưa ra là kỹ thuật "quét" ma trận phím.

Chúng ta sẽ cài đặt các chân nối với A,B là output,lần lượt nối GND (khi một chân là output nối GND thì các chân khác là input nối cao trở với nguồn để tránh ảnh hưởng tín hiệu),các chân 1,2 là input ,có điện trở kéo lên.Đọc trạng thái các chân 1,2 để biết trạng thái nút của hàng đang kiểm tra.Cụ thể như sau:

Bước 1. Cài đặt :

  • A là output (GND) 
  • B là input (nối cao trở lên VCC),vì nếu để B là output (VCC) thì giả sử nếu nhấn cả SW65 và SW66 thì sẽ gây thông VCC-GND gây chập.
  • 1,2, là input nối cao trở lên VCC.(trong MSP430 là cài đặt thanh ghi PxREN lên 1 và PxOUT lên 1)
Bước 2. Đọc giá trị cổng 1,2 .Ví dụ nếu mức logic của cổng 1 là 0 thì nút SW65 đã được nhấn.
Bước 3. Cài đặt :

  • A là input (VCC)
  • B là output (GND)
  • Đọc giá trị của cổng 1,2 .Kết quả chính là trạng thái của nút SW66 và SW68.
Sau đó quay lại bước 1 để tiếp tục quét lại từ đầu.
Tuy nhiên nhược điểm của mạch ma trận phím theo cách này là :

  • Chỉ quét phím được chính xác nếu chỉ có một phím được nhấn,hoặc các phím trong cùng 1 hàng được nhấn đồng thời.Giả sử trường hợp cả 3 phím SW65 , SW66 , SW67 được nhấn,khi đó , khi chúng ta quét cột B (cổng B là output GND) thì vẫn sẽ có tín hiệu GND nối từ B qua SW66 qua SW65 qua dây A và qua SW67 về cổng 2,Tức là khi đó cổng 2 sẽ nối GND (và sẽ báo nút SW68 được nhấn) và gây ra sai logic.
  • Cũng vì nguyên nhân trên mà mạch ma trận như trên không thể áp dụng được với các đối tượng nào khác ngoài phím thường (phím có nhớ,công tắc hành trình,cảm biến I/O ).
Giải pháp được đưa ra khá đơn giản nhưng sẽ giải quyết triện để vấn đề trên.

2.Thiết kế ma trận phím cải tiến

Thực ra kiểu thiết kế này không mới,nhưng ít người biết,hoặc để ý.Giải pháp đưa ra nhằm loại bỏ dòng điện sinh ra thông giữa các nút nhấn ở các cột khác nhau.Đó là mắc thêm một diode schottky vào trước mỗi nút nhấn như bên dưới.
Nguyên lý hoạt động khá đơn giản.Giả sử chúng ta đang quét cột A (nối GND),các cột B , C đặt là input nối cao trở với VCC.Giả sử nhấn cả nút SW1 , SW2 , SW10 , mức logic gây ra từ SW2 và SW10 đều bị chặn bởi các diode nên không thể ảnh hưởng đến các cột khác được.Kết quả là chúng ta vẫn đọc được mức logic tại cổng P4.1 là 1.

3.Một đoạn code đơn giản quét ma trận phím 8x8

Mình minh họa một đoạn code đơn giản viết cho MSP430 , quét ma trận phím 8x8 với các hàng được nối với Port1 và cột nối với Port2.Trạng thái các nút được cập nhật vào mảng Ma_tran_phim[].

Khởi tạo:
unsigned char Ma_tran_phim[8];
//////////////////////////////////////////////
/*
* Phan nay cai dat ma tran phim
*/
// Set hang , set input , noi cao tro len VCC
P1DIR &= 0x00;
P1REN |= 0xFF;
P1OUT |= 0xFF;
//Set cot , khi moi bat dau set input,noi cao tro len VCC
P2DIR &= 0x00;
P2REN |= 0xFF;
P2OUT |= 0xFF;
Hàm quét ma trận phím:
for(i=0;i<8;i++)
{
    //Cot nao duoc quet thi set output noi GND
    P2DIR = (1<<i);
    P2OUT = ~(1<<i);
    _delay_cycles(10000);
    Ma_tran_phim[i]= ~P1IN;
}
P2DIR &= 0x00;
P2OUT |= 0xFF;
Hy vọng bài viết giúp ích được cho các bạn!!!

No comments:

Post a Comment

END COMMENT FACEBOOK-->