
Cách dùng bàn phím ma trận 4x4(for AVR)
Những điểm khác cơ bản của phần code này so với code ví dụ đã đưa:
- Ngắn gọn hơn
- Không tốn Timer
- Chống rung phím đơn giản, hiệu quả (không dùng delay)
- Dễ định nghĩa cho các loại bàn phím khác nhau
File Key4x4.h
Code:
#ifndef _KEY4X4_H_
#define _KEY4X4_H_
//-----------------------------------------------------------------//
// ----- Define Hardware ------//
#define KEY4X4_PORT PORTC
#define KEY4X4_PIN PINC
#define KEY4X4_DDR DDRC
unsigned char KeyPad[4][4] = {
'7', '8', '9', '/',
'4', '5', '6', 'x',
'1', '2', '3', '-',
'C', '0', '=', '+'};
/*
unsigned char KeyPad[4][4] = {
'1', '2', '3', 'A',
'4', '5', '6', 'B',
'7', '8', '9', 'C',
'#', '0', '*', 'D'};
// ----- Define Firmware ------//
*/
#endif
/* HARDWARE CONNECTION
1 PD0 -------0----1----2----3
| | | |
2 PD1 -------4----5----6----7
| | | |
3 PD2 -------8----9----10---11
| | | |
4 PD3 -------12---13---14---15
R1 | | | |
5 PD4 -~~~~~-| | | |
R2 | | |
6 PD5 -~~~~~------| | |
R3 | |
7 PD6 -~~~~~-----------| | R1..R4=10k..47k
R4 |
8 PD7 -~~~~~----------------|

*/
File Key4x4.c
Code:
/*****************************************************
Project : Keypad Matrix 4x4
Version : 1.0
Date : 07-11-2007
Author : Nam
Company : PYT
Chip type : ATmega16
Program type : Application
Clock frequency : 12 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 256
*****************************************************/
#include <avr/io.h>
#include <avr/interrupt.h>
#include "key4x4.h"
//-----------------------------------------------------------------//
// Global variables
uint8_t key_old_state[4][4];
//------------------------------------------------------------------------------/
/
void check_key()
{
for (uint8_t row=0; row<4; row++) {
KEY4X4_PORT = (1<<row); //select row
for (uint8_t col=0; col<4; col++) {
uint8_t key_cur_state = (KEY4X4_PIN>>col+4) & 1;
if (key_cur_state && (!key_old_state[row][col])) {
uint8_t key_code = KeyPad[row][col];
lcd_putchar(key_code);
}
key_old_state[row][col] = key_cur_state;
}
}
}
//------------------------------------------------------------------------------/
/
int main(void)
{
// ----------------- Input/Output Ports initialization ---------------
KEY4X4_PORT = 0xFF; // Pull-up R

KEY4X4_DDR = 0x0F; // 4 row -> output, 4 col -> input
lcd_init(16);
// Global enable interrupts
sei();
while (1) {
check_key();
}; //while
}
1. Ở phần Hadware connection: các pins PD4...PD7 nhw hình vẽ là nối qua R1...R4 rồi mới vào nút nhấn. Còn nếu là pull-up thi nối vào nút nhấn và
nối lên V+. Vậy chính xác là kiểu nào?
Tôi tìm hiểu hóa ra thế này: Đối với AVR do có R pullups bên trong nên dùng phần mềm cài đặt, không cần R ngoài kéo lên...Nếu có như sơ đồ của
tintintin thì họ giải thích là tránh ngắn mạch giữa các cực của IC. Các IC không có R pullups bên trong thì phải có R ngoài kéo lên V+...
2. về cái này thì trong codevision có example rồi đấy. vào đó mở file này mà coi.
cách viết khá hay, dùng timer, mỗi lần chỉ quét một cột, có chống rung, chống nhiễu, ngoài ra còn có thời gian release phím nữa. dùng cho
trường hợp bạn cần nhận phím nhấn liên tục thay vì nhấn nhiều lần.
tuy nhiên để dễ sử dụng và điều chỉnh linh hoạt thì chắc là cần sửa cái exp đó một tí.
Code C quét phím - chống dội phím cho AVR dùng codevision lập trình
Khi bạn nhấn một phím và giữ bất kì bao lâu cũng được, khi nhả phím ra nó mới
thực hiện.
- Kết nối phần cứng bàn phím ma trận 4x4, 4 chân nối vào 4 bit thấp của portB,
4 chân nối vào 4 bit cao của portB.
- Phuơng pháp quét phím cấp điện lần lượt 4 chân bít thấp, kiểm tra sự thay đổi
ở 4 chân bit cao. khi nào có sự thay đổi nhảy đến phần chống dội phím, sau đó
xử lí sự kiện có phím nhấn.
Code quét phím:
while(1)
{

DDRB=0x0F;
PORTB=0;
PORTB.0=1;
delay_ms(5);
if (PINB>15) break;
PORTB=0;
PORTB.1=1;
delay_ms(5);
if (PINB>15) break;
PORTB=0;
PORTB.2=1;
delay_ms(5);
if (PINB>15) break;
PORTB=0;
PORTB.3=1;
delay_ms(5);
if (PINB>15) break;
}
Code ch ng d i phímố ộ
void chongdoi(void)
{ int i;
loinhan:;
for (i=0;i<=50;i++) // khi có phím nh n s nh y đ n đâyấ ẽ ả ế
{
if (PINB<=15) goto loinhan; //đ m b o kg còn d i n aả ả ộ ữ
}
ma_key=PINB; // luu gia tri portB
delay_ms(50);
while(1)
{
if (PINB<=15) //đ i phím nh raợ ả
{
loinha:;
for (i=0;i<=50;i++)
{
if (PINB>15) goto loinha;

}
break;
}
}
PORTB=0; //reset PORTB
}

