IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> [单片机笔记]使用状态机扫描矩阵键盘 -> 正文阅读

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

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
打开下载,可以使用

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-11-09 19:43:26  更:2021-11-09 19:45:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 9:39:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码