Mặc dù trong phần các vấn đề cơ bản của I/O đã có ví dụ về vấn đề này, nhưng ở đây mình đưa ra riêng một thread để các bác mới ngâm cứu về AVR dễ tham khảo.
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
File Key4x4.c
Trong file gởi kèm có phần mô phỏng trên Protues kèm theo.
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 -~~~~~----------------|
*/
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
}
Comment