1 前言
2021年2月在学习蓝桥杯单片机的时候,遇到矩阵键盘的扫描问题。当时由于初步接触单片机,因此使用的是软件扫描,消除抖动使用的是延迟函数。这就出现了两个问题: 一是使用延迟函数delay可以消除抖动的,只要延迟5ms即可,但是在实践中还是发现,有时候无法扫描到触发,或者一次按下被触发多次。十分不稳定。 二是由于使用延迟函数,因此,在延迟的这段时间里,CPU无法进行其他操作,大大降低了CPU的利用率,浪费资源在进行延迟。 2021年11月,在学习单片机的课程的时候,我尝试使用另外一种高效的键盘扫描的方法——状态机。 状态机不仅完美的解决了以上使用软件延迟造成的稳定性低、浪费CPU资源两个问题,同时也为我们写其他程序提供了一种新的思路。
2 状态机
2.1 什么是状态机
有限状态机是一种概念性机器,它能采取某种操作来响应一个外部事件。具体采取的操作可以取决于接收到的事件,也可以取决于各个事件的相对发生顺序。
机器能跟踪一个内部状态,它会在收到事件后进行更新。为一个事件而响应的行动不仅取决于事件本身,还取决于机器的内部状态。另外,采取的行动还会决定并更新机器的状态。 这样一来,任何逻辑都可建模成一系列事件/状态组合。
按:这种状态机很类似,使用中断定时1ms,用时一个内部的count去数中断次数,达到获取任意一个时间间隔的准确定时。
比如:要定时1s,则当count=1000时,使用一个1s标志位,如flag1s=1。在使用完这个flag1s的标志位后再对它复位——flag1s=0.
2.2 状态机的概念
状态机可归纳为四个要素,即现态、条件、动作、次态。
①现态:是指当前所处的状态。 ②条件:又称为“事件”,当一个条件被满足,将会触发一个动作,或者执行一次状态的迁移。 ③动作:条件满足后执行的动作。动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。动作不是必需的,当条件满足后,也可以不执行任何动作,直接迁移到新状态。 ④次态:条件满足后要迁往的新状态。“次态”是相对于“现态”而言的,“次态”一旦被激活,就转变成新的“现态”了。
2.3 使用状态机写键盘的思路
3 代码实例
3.1 使用软件
操作系统:Windows10 仿真软件:protues8 professional 编程软件:Keil5 C51
3.2 protues电路图
3.2 状态机部分程序
状态机的一些变量定义
#define uchar unsigned char
#define uint unsigned int
#define S1 1
#define S2 2
#define S3 3
#define S4 4
uchar State=S1;
uchar Key;
状态机按键扫描程序 将以下Key_Scan()函数放在中断服务函数,没10ms扫描一次即可消除抖动,且实现20ms消抖操作
uchar Key_scan()
{
uchar row,rank,locate;
uchar num=0;
P1=0xf0;
rank=P1;
rank=rank&0xf0;
P1=0x0f;
row=P1;
row=row&0x0f;
locate=row|rank;
switch(State)
{
case 1:{
if(locate!=0xff)
{
State=S2;
break;
}
else
break;
}
case 2:{
if(locate!=0xff)
{
State=S3;
switch(locate)
{
case 0x7e:
num=1;break;
case 0xbe:
num=2;break;
case 0xde:
num=3;break;
case 0xee:
num=4;break;
case 0x7d:
num=5;break;
case 0xbd:
num=6;break;
case 0xdd:
num=7;break;
case 0xed:
num=8;break;
case 0x7b:
num=9;break;
case 0xbb:
num=10;break;
case 0xdb:
num=11;break;
case 0xeb:
num=12;break;
case 0x77:
num=13;break;
case 0xb7:
num=14;break;
case 0xd7:
num=15;break;
case 0xe7:
num=16;break;
}
break;
}
else
{
State=S1;
break;
}
}
case 3:{
if(locate!=0xff)
break;
else
{
State=S1;
break;
}
}
}
return num;
}
3.3 Keil工程文件和Protues工程文件
https://download.csdn.net/download/PurpleStrange/38440950 打开下载,可以使用
|