比较常用的3 个IO 口实现6 个按键方便,给初学者参考,实现比较简单测序如下:
/*--------------------------------------------------*/
/* AVR 系统的处理器为: ATMega32 */
/* AVR 系统的晶振频率: 7.3728 Mhz */
/* 作者: xininye */
/* 日期: 2007-08-27 */
/*--------------------------------------------------*/
/* 文件名: KEYPAD.C */
/* 功能: 按键扫描 */
/*--------------------------------------------------*/
#include
#include
#include "delay.h"
#include "uart.h"
#include "keypad.h"
// ScanKey 按键扫描函数,被定时器0 中断调用
//-----------------------------------------------------------------------------//
unsigned char ScanKey(void)
{
unsigned char key;
KEY_DDR = (1<00000;
KEY_OUT = ((1<delay_us();
if(!(KEY_IN & (1<{
key = S_DOWN;
return key;
}
if(!(KEY_IN & (1<{
key = S_ENTER;
return key;
}
KEY_DDR = (1<00000;
KEY_OUT = ((1<delay_us();
if(!(KEY_IN & (1<{
key = S_LEFT;
return key;
}
if(!(KEY_IN & (1<{
key = S_ESC;
return key;
}
KEY_DDR = (1<00000;
KEY_OUT = ((1<delay_us();
if(!(KEY_IN & (1<{
key = S_UP;
return key;
}
if(!(KEY_IN & (1<{
key = S_RIGHT;
return key;
}
return (0);
// 扫描不到按键返回 0
}
unsigned char key_code = 0; // 存放按键值的全局变量
// GetKey 函数
// 返回当前键值,后清空按键
unsigned char GetKey(void)
{
unsigned char key;
key = key_code;
if(key)
{
key_code = 0;
return (key);
}
else
{
return 0;
}
}
unsigned char kpush,key_h;
unsigned int key_l;
#pragma interrupt_handler timer0_ovf_isr:12 //iv_TIM0_OVF
void timer0_ovf_isr(void)
{
unsigned char key;
TCNT0 = 0x70; //reload counter value
key = ScanKey();
if (key == 0) //按键扫描
{
if ((key_l>3)&&(key_l<160)&&(key_h>6)) //释放按键,如果之前按键时间少于1 秒,读入键值
{
key_code = kpush;
}
if ((++key_h)>40)key_h=40;
key_l=0;
if (key_code>=0x80) key_code=0; //如果之前的按键为长按1 秒,清除键值
}
else
{
kpush = key;
key_l++;
if ((key_l>160)&&(key_h>6)) //如果按键超过1 秒,键值加0x80 标志长按键
{
key_code = kpush|0x80;
key_h=0;
key_l=0;
}
}
}
0
|
|
|
头像被屏蔽
· 2013-5-16 22:38:54
|
|
|
|
|