C语言写的,移植性较好
程序是别人写的,我仅做了注释!刘玉宏
unsigned char Trg; //按键是否触发
unsigned char Cont;//上次读到的按键端口的值
void KeyRead( void )
{
unsigned char ReadData = KEYPORT^0xff; // 读按键端口并求反,即按键低电平有效
Trg = ReadData & (ReadData ^ Cont); // 首先,本次按键端口值跟上次的按键状态异或,若按键状态发生变化,此异或值肯定非0,也就是发生状态转换的那个按键位为1(例如P07按键按下,此值为0x80).问题是不论按键按下或释放都发生状态转换,也就是说ReadData ^ Cont为非0可能是按键按下,也可能是按键释放.(注意cpu在人按松按键的过程中会多次执行这个程序,是这个程序能正确工作的前题,即按键按下,程序执行一次.ReadData ^ Cont为非0,我们知道按键按下了,在人还没来的及释放按键,这个程序又被执行一遍,这时.ReadData ^ Cont为0了,按键还没释放程序再执行一遍,ReadData ^ Cont还是0,按键释放了,程序再次执行一遍ReadData ^ Cont为非0,程序再执行一遍.ReadData ^ Cont变成0)如果我们只需要在按键按下时记录按下事件,并不需要记录按键释放事件,那么我们需要把本次端口值和(ReadData ^ Cont),相与运算就可以了!因为按键释放此按键的位读到的是0,和(ReadData ^ Cont),相当与屏蔽了按键释放事件.好了,总结一下吧,按键按下时TRG为非0,直到下次本条语句再次执行前,再次执行后TRG=0不论按键是否释放与否.
Cont = ReadData; // 保存按键端口当前状态,如果下次读端口时按键状态并未改变,那么这个值是不会发生变化的,即持续按键按下时此值是跟上次读到的端口状态是相同的.若按键状态发生变化,此值就发生了变化.利用这个特性我们可以判断一个按键是否被持续按下,进而按键的长按和短按执行不同的工作.
}
举个例子来说明这个程序怎么使用吧!
#define KEY1 0x01 // 1号按键
#define KEY_PLUS 0x02 // 加
while(1)
{
KeyRead( ); //执行按键扫描
if (Trg & KEY1) // 如果按下的是KEY1,而且你长按这按键也没有用,
{ //它是不会执行第二次的哦 , 必须先松开再按下
key1fun( ); / / 执行的key1功能代码
}
if (Cont & KEY_PLUS) // 如果“加”按键被按着不放
{
cnt_plus++; // 计时
if (cnt_plus > 100) // 20ms*100 = 2S 如果时间到
{
key_puls_Func(); // 你需要的执行的程序
}
}
}
其实这种晦涩难懂的程序我是不推荐的,仅仅是看这好玩,做做脑力运动而已。其实这程序的综合效率也不会比别的写法更高