Keyboard.h
/********** AVR 矩阵键盘扫描程序 *********
* 版本.........: 2.0
* 作者.........: 陈利栋
* 目标.........: AVR
* 文件名.......: Keyboard.h
* 编译器.......: AVR GCC 20100110
* 开发环境.....: AVR Studio V4.18
* 创建时间.....: 2010.09.12
* 最后修改.....: 2010.09.29
****************************************
*/
#ifndef __KEYBOARD_H__
#define __KEYBOARD_H__

#include 
<avr/io.h>
#include 
<util/delay.h>

#define KEYBOARD_PORT                 PORTA
#define KEYBOARD_DDR                  DDRA
#define KEYBOARD_PIN                  PINA

#define KEY_NULL                      0xff
#define KEY_READY_COUNT               100       // 此值在不同环境下应适当调整(1 - 65535),值越小,灵敏度越高

#define KEY_CONTINUE_START_COUNT      20000     // 检测连续按键开始需要的次数,需要适当调整
#define KEY_CONTINUE_RUNNING_COUNT    1000      // 连续按键间隔需要的次数,需要适当调整

extern unsigned char key_continue_flag;         // 连续按键标记
extern unsigned char GetKeyValue(void);

#endif /* __KEYBOARD_H__ */

 

 

 

 

 

Keyboard.c
/********** AVR 矩阵键盘扫描程序 *********
* 版本.........: 2.0
* 作者.........: 陈利栋
* 目标.........: AVR
* 文件名.......: Keyboard.c
* 编译器.......: AVR GCC 20100110
* 开发环境.....: AVR Studio V4.18
* 创建时间.....: 2010.09.12
* 最后修改.....: 2010.09.29
****************************************
*/
#include 
"Keyboard.h"

unsigned 
char _key_last = KEY_NULL;
unsigned 
int  _key_count = 0;

unsigned 
int  _key_continue_count = 0;
unsigned 
char key_continue_flag = 0;

unsigned 
char KeyScan(void)
{
    unsigned 
char temp = 0;

    KEYBOARD_DDR 
= 0x0f;
    KEYBOARD_PORT 
= 0xf0;
    _delay_us(
10);
    temp 
= KEYBOARD_PIN;

    KEYBOARD_DDR 
= 0xf0;
    KEYBOARD_PORT 
= 0x0f;
    _delay_us(
10);
    temp 
|= KEYBOARD_PIN;

    
if (temp != _key_last)
    {
        _key_count
++;
        
if (_key_count >= KEY_READY_COUNT)
        {
            _key_last 
= temp;
            _key_count 
= 0;
            
return _key_last;
        }
        key_continue_flag 
= 0;
    }
    
else
    {
        
if (temp != 0xff)
        {
            _key_continue_count
++;
            
if (key_continue_flag == 0)
            {
                
if (_key_continue_count >= KEY_CONTINUE_START_COUNT)
                {
                    key_continue_flag 
= 1;
                    _key_continue_count 
= 0;
                    
return temp;
                }
            }
            
else
            {
                
if (_key_continue_count >= KEY_CONTINUE_RUNNING_COUNT)
                {
                    _key_continue_count 
= 0;
                    
return temp;
                }
            }
        }
        _key_count 
= 0;
    }

    
return KEY_NULL;
}

unsigned 
char GetKeyValue(void)
{
    
switch (KeyScan())
    {    
        
case KEY_NULL: return KEY_NULL;
        
case 0x77return '1';
        
case 0x7Breturn '2';
        
case 0x7Dreturn '3';
        
case 0x7Ereturn 'A';
        
case 0xB7return '4';
        
case 0xBBreturn '5';
        
case 0xBDreturn '6';
        
case 0xBEreturn 'B';
        
case 0xD7return '7';
        
case 0xDBreturn '8';
        
case 0xDDreturn '9';
        
case 0xDEreturn 'C';
        
case 0xE7return '*';
        
case 0xEBreturn '0';
        
case 0xEDreturn '#';
        
case 0xEEreturn 'D';
        
default  : return KEY_NULL;
    }
}