Tài khoản E-mail miễn phí @ngohaibac.net

Các bạn hãy dành chút thời gian đọc kĩ hướng dẫn sử dụng trước khi dùng.

Phương pháp quét keypad – ma trận phím bấm dùng ngắt Timer

By admin
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...

Chào các bạn.

Mình không biết phương pháp này các bạn biết chưa, hoặc đã ai post chưa. Nhưng đó là mình suy nghĩ và code ra chứ không hề copy ý tưởng hay code của ai khác :D.

Phương pháp dựa trên dùng ngắt Timer0 dùng cho PIC16F887 do đó sẽ rất là tối ưu, tất nhiên có thể dùng cho tất cả các loại PIC và vi điều khiển khác.

Cấu tạo của Keypad:

Nội dung của phương pháp này như sau, rất đơn giản giống tư tưởng của các phương pháp scan truyền thống:

B1. Cho các cột = 1

B2. Đọc các hàng, nếu hàng nào = 1, thì sau khoảng 10 đến 15ms thì lại đọc tiếp. Nếu vẫn = 1 thì à, đúng là phím bấm rồi, ke ke. Như vậy xác định được hàng nào rồi nha. Cho vào biến row_num.

B3. Cho row_num = 1, đọc các cột xem, cột nào = 1 thì đó là cột bấm đó, gán vào biến col_num. Chờ khi phím nhả thì gọi hàm thực hiện theo từng phím key_function();

Rất đơn giản như thế nhưng mình thực hiện rất tối ưu, các bạn có thể tham khảo:

void scanKeypad(void){
unsigned char i;        // Define i as register later
// if state 0 then set column to 1, and see the change of row
switch(progress){
case 0:
// set all column (4 low bit) as output, and row as input, and write ‘1′ to column
tris_keypad    =  0xF0;
port_keypad |= 0×0F;
// if value of row diffirent than 0,then set progress to 1
// and set Tcycle = 10
if ((port_keypad & 0xF0) != 0) {
// Determine next state
progress = 1;
cycle_1  = 10;
}else{
progress = 0;
};
break;

// Progress 1, check after 10 ms
case 1:
cycle_1–;
// when cycle_1 = 0,then check again
if(cycle_1 == 0){
if ((port_keypad & 0xF0) != 0) {
// Determine which row equal 1
for(i = 7; i>3; i–){
if ( (port_keypad & (1<<i)) != 0){
row_num = i-3;
break;
};
};
//Determine next state
progress = 2;
}else{
progress = 0;        // Start state
};
};
break;
// Progress 2, to determind the column
case 2:
//Set row tris to 0,
// row_num corespond to (row_num + 3) bit in port_keypad
tris_keypad ^= 1<<(row_num + 3);        // clear tris bit of row to 0, as output
tris_keypad    |= 0×0F;                    // Set all pin of column as input(0 to 3)
port_keypad != 1<<(row_num + 3);
for(i = 0;i<4;i++){
if ( (port_keypad & (1<<i)) != 0){
col_num = i+1;
break;
};
};
// Wait for user release key
while ((port_keypad & (1<<i)) != 0);
// Do all function of keypad after scan sucessfully
key_function();
//Determind the next state
progress = 0;
//cycle_2  = 0xFF;
break;
default:
break;
};
};

Bài toán của mình chỉ thực hiện sau khi nhấn phím nên mình mới chờ khi nhả phím. Còn để xác định phím hold hay là nhấn thì dùng thêm process thứ 3, sau thời gian khoảng 250ms nữa hoặc hơn tùy bạn, kiểm tra lại trạng thái của phím bấm đó, nếu thấy vẫn = 1 thì tức là trạng thái hold, còn lại là trạng thái nhấn phím.

Các biến được dùng trong hàm quét phím có thể được khai báo bằng Macro và khai báo biến global.Mình dùng các thanh ghi làm biến, các bạn chú ý dùng để không trùng vào các module đang dùng.

//Define for keypad on PORTD
#define port_keypad PORTD
#define tris_keypad TRISD

#define progress    TXREG        //process variable
#define row_num        TMR1L        // Index of row
#define col_num        CCPR2L        // Index of column

#define cycle_1        CCPR2H        // 10ms

Vậy chỉ cần thay PORTD bằng bất kì port nào khác mà keypad nối vào là được.

Còn hàm key_function() dùng để thực hiện các lệnh của phím, tùy các bạn.

void key_function(void){
switch(row_num){
case 1:
switch(col_num){
case 1:        //Key 1
case 2:        // Key 2
case 3:        // Key 3

………………….
}

Chú ý: các bạn gọi hàm này trong hàm ngắt của Timer, bao nhiêu ms hay ns là tùy bạn.

Chúc các bạn thành công.

Các bài viết liên quan:

  1. Phạm Thành Nam posted the following on 3 August, 2008 at 12:57 am.

    có ai không giúp mình với mình sắp thi rui ma không biết thế nào về C cả……………………cảm ơn trước

    Reply to Phạm Thành Nam

Leave a reply

:mrgreen: :| :twisted: :arrow: 8O :) :? 8) :evil: :D :idea: :oops: :P :roll: ;) :cry: :o :lol: :x :( :!: :?: