三行代码搞定独立按键

三行代码

uchar cont,trg;    //triger触发 continue连续
void KeyScan()
{
	    uchar ReadData =  PINB^0xff;
		trg = ReadData&(ReadData^cont);
		cont = ReadData;
}

原理

(1) 没有按键的时候
端口为0xff,ReadData读端口并且异或,很显然,就是 0x00 了。
Trg = ReadData & (ReadData ^ Cont); (初始状态下,Cont也是为0的)很简单的数学计算,因为ReadData为0,则它和任何数“相与”,结果也是为0的。
Cont = ReadData; 保存Cont 其实就是等于ReadData,为0;
结果就是:
ReadData = 0;
Trg = 0;
Cont = 0;
(2) 第一次PB0按下的情况
端口数据为0xfe,ReadData读端口并且异或,很显然,就是 0x01 了。
Trg = ReadData & (ReadData ^ Cont); 因为这是第一次按下,所以Cont是上次的值,应为为0。那么这个式子的值也不难算,也就是 Trg = 0x01 & (0x01^0x00) = 0x01
Cont = ReadData = 0x01;
结果就是:
ReadData = 0x01;
Trg = 0x01;Trg只会在这个时候对应位的值为1,其它时候都为0
Cont = 0x01;
(3) PB0按着不松(长按键)的情况
端口数据为0xfe,ReadData读端口并且异或是 0x01 了。
Trg = ReadData & (ReadData ^ Cont); 因为这是连续按下,所以Cont是上次的值,应为为0x01。那么这个式子就变成了 Trg = 0x01 & (0x01^0x01) = 0x00
Cont = ReadData = 0x01;
结果就是:
ReadData = 0x01;
Trg = 0x00;
Cont = 0x01;
因为现在按键是长按着,所以MCU会每个一定时间(20ms左右)不断的执行这个函数,那么下次执行的时候情况会是怎么样的呢?
ReadData = 0x01;这个不会变,因为按键没有松开
Trg = ReadData & (ReadData ^ Cont) = 0x01 & (0x01 ^ 0x01) = 0 ,只要按键没有松开,这个Trg值永远为 0 !!!
Cont = 0x01;只要按键没有松开,这个值永远是0x01!!
(4) 按键松开的情况
端口数据为0xff,ReadData读端口并且异或是 0x00 了。
Trg = ReadData & (ReadData ^ Cont) = 0x00 & (0x00^0x01) = 0x00
Cont = ReadData = 0x00;
结果就是:
ReadData = 0x00;
Trg = 0x00;
Cont = 0x00;
很显然,这个回到了初始状态,也就是没有按键按下的状态。
这个代码完美解决了延时消抖的问题,而且代码简洁方便,实用性很高,因为三行代码相当于是检测按键的状态来判断按键是否有按下,所以我们可以不用中断来写按键,下面我就放上我用51写的不用中断的按键扫描实验。有长按键和短按键的扫描。
网上关于三行代码的资料很多,我在这里只是当一个搬运工,有些见解颇偏,欢迎各位高人指点。

独立按键实验代码

#include<reg52.h>

#define uchar unsigned char
#define uint unsigned int

uchar cont,trg; 
static uchar k;

//三行代码实现按键扫描

void keyscan()
{
	uchar ReadData = P3^0xff;
	trg = ReadData&(ReadData^cont);
	cont = ReadData;
}

void Delay100ms()		//@11.0592MHz
{
	unsigned char i, j;

	i = 180;
	j = 73;
	do
	{
		while (--j);
	} while (--i);
	k++;
}


//按键功能

void keyfun()
{
	if(trg & 0x01)
	{
		P1=~0x01;
	}
	else if(trg & 0x02)
	{
		P1=~0x02;
	}
	else if(trg & 0x04)
	{
		P1=~0x04;
	}
	else if(cont & 0x01)
	{ 
		Delay100ms();
	 if(k == 20)//长按键
		{
			P1=0xff;
			k=0;
		}
	}
}

void main()
{
	while(1)
	{
		keyscan();
		keyfun();
	}
}

发布了9 篇原创文章 · 获赞 11 · 访问量 1356

猜你喜欢

转载自blog.csdn.net/FuckerGod/article/details/90300098