一、独立按键的处理
(1)轮询方式
这种方式需要CPU不断地去检测用户的按键是否按下,CPU对于按键什么时候按下是未知的,因此就需要不断地去检测,而且检测的周期需要的时间不能太长,不然会错过用户的按键。也不能太短不然CPU的资源都会浪费在这个地方。
(2)中断方式
二、轮询方式编程
首先我们通过看原理图发现,所有的独立按键都是一端接地,另一端接在一个端口上。首先我们这里将这个端口接到P1端口上。如果有按键按下,则对应的端口的值会变成0,否则这个按键没有被按下。不同的返回值对应着不同的按键被按下。这种方法是将检测按键和处理按键分开处理,这样当我们想使用按键的时候只需要进行按键的处理函数的编写即可。
//使用轮询的方式进行独立按键的检测
u8 jiance_lunxun(void)
{
if (key1 == 0) //如果按下的是按键1,则返回1
{
return 1;
}
else if (key2 == 0) //其他的按键返回值同理即可
{
return 2;
}
}
但是我们这样处理按键会有两个问题,首先当我们按下按键时,由于硬件电路的问题,会产生很多杂散的波形。也就是我们虽然按下去了,但是由于硬件的原因他并不会直接就变成低电平,而是会经历一个波动才会变成低电平。这样我们的然间就会误判,导致多次的相应。这个问题的解决方法就是当CPU以为有一个按键响应来时,我们先延时一段时间,将那一段波动给放过去,然后在进行判断就可以了。还有一个问题就是当我们一直按下按键的时候,就会一直进行响应,当我们只想按一次相应一次时,我们就需要按的特别快,但是我们怎么可能有电脑快呢。因此我们就需要添加一个标志位,用来判断按键的状态,这样当一次按键只有按下而没有抬起时,就不会进行多次相应。而只会相应一次。下面是代码:注意我只处理了前3个按键,其他的都类似。
u8 flag[8] = 0; //按键标志位 1表示按键被按下 0表示没有按下
//数组不同的位分别表示不同的按键状态
void delay20ms(void) //误差 0us
{
unsigned char a,b;
for(b=215;b>0;b--)
for(a=45;a>0;a--);
}
//使用轮询的方式进行独立按键的检测
u8 jiance_lunxun(void)
{
/****************************************************/
if (key1 == 0) //如果按下的是按键1,则返回1
{
delay20ms();
if (key1 == 0 && flag[0] == 0)
{
flag[0] = 1;
return 1;
}
}
else
{
flag[0] = 0;
}
/****************************************************/
if (key2 == 0) //如果按下的是按键1,则返回1
{
delay20ms();
if (key2 == 0 && flag[1] == 0)
{
flag[1] = 1;
return 2;
}
}
else
{
flag[1] = 0;
}
/****************************************************/
if (key3 == 0) //如果按下的是按键1,则返回1
{
delay20ms();
if (key3 == 0 && flag[2] == 0)
{
flag[2] = 1;
return 3;
}
}
else
{
flag[2] = 0;
}
/****************************************************/
if (key4 == 0) //其他的按键返回值同理即可
{
return 4;
}
/****************************************************/
if (key5 == 0) //其他的按键返回值同理即可
{
return 5;
}
/****************************************************/
if (key6 == 0) //其他的按键返回值同理即可
{
return 6;
}
/****************************************************/
if (key7 == 0) //其他的按键返回值同理即可
{
return 7;
}
/****************************************************/
if (key8 == 0) //其他的按键返回值同理即可
{
return 8;
}