[单片机笔记]使用状态机扫描矩阵键盘

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       //按键初始状态1
#define S2 2       //判断按键是否按下
#define S3 3       //确定按键按下
#define S4 4       //松手检测状态
uchar State=S1;//状态量,初始值为1
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//未按下,状态量不变为此未S1
				break;
		}
		case 2:{
			if(locate!=0xff)
			{
				State=S3;
				switch(locate)
				{
					case 0x7e://1 0b0111 1110
						num=1;break;
					case 0xbe://2
						num=2;break;
					case 0xde://3
						num=3;break;
					case 0xee://++
						num=4;break;
					case 0x7d://4
						num=5;break;
					case 0xbd://5
						num=6;break;
					case 0xdd://6
						num=7;break;
					case 0xed://--
						num=8;break;
					case 0x7b://7
						num=9;break;
					case 0xbb://8
						num=10;break;
					case 0xdb://9
						num=11;break;
					case 0xeb://START
						num=12;break;
					case 0x77://
						num=13;break;
					case 0xb7://0
						num=14;break;
					case 0xd7://
						num=15;break;
					case 0xe7://PAUSE
						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
打开下载,可以使用

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值