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 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 蓝桥杯单片机之按键扫描(状态机) -> 正文阅读

[嵌入式]蓝桥杯单片机之按键扫描(状态机)

???????? 正如比赛官方所说,按键要灵敏,不要出现按键按一下跳转好几次的情况(比如常见的界面),数码管也要消隐。因为可以说这是单片机最重要的输入和输出了。而输入和输出正如人的体验一样,给人最直接而深刻的感受。

由于之前有疑问,是关于按键驱动程序是按键松开后触发还是按下就触发(都仅触发一次),蓝桥官方老师给出的是若题目只考虑到功能描述,即并未说明是按键松开后触发还是按下就触发,那就是随便~。

不过,大部分赛题都是按下就触发,而我做了这么多套题写的都是按键松开触发(不知道会不会有影响)故我总结几种按下就触发的算法(基于状态机触发的且仅触发一次的简洁算法,正所谓大道至简,道法术器!

第一种算法思路(优化前):

根据状态机有且仅有一次在按键扫描函数中从case 1变到case 2,通过定义一个临时变量保存按下的值,松开后初始化为0。

按键扫描函数(越简越好)

void key_scan(){
	
	switch(key_state){
	case 0:
		P3=0x0f;
		P42=0;
		P44=0;
		key_v=0;
		if(P3!=0x0f)	key_state=1;
			
		break;
	case 1:
			P3=0x0f;
			P42=0;
			P44=0;
			if(P3!=0x0f){
			 
			if(!P30)key_v=7;
			else if(!P31)key_v=6;
			else if(!P32)key_v=5;
			else if(!P33)key_v=4;

				
			P3=0xf0;
			P42=1;
			P44=1;
			if(!P34)key_v+=12;
			else if(!P35)key_v+=8;
			else if(!P42)key_v+=4;
			key_state=2;
		}
		else 
			key_state=0;
		break;
	case 2:
		
		P3=0x0f;
		P42=0;
		P44=0;
		if(P3==0x0f){
			key_state=0;		
		}
		break;
	default:
		break;

}
}

main函数驱动:

	if(keytime==20){
			keytime=0;
			key_scan();
			if(key_state==2){	     //     第一次扫描,按键状态机由case0 -case1,
				if(key_v!=keys){    //	第二次扫描  按键状态机由case1 -case2
			switch(key_v){			//第三次扫描  按键状态机case2 -case 0(松开)或保持不变
				case 4:
					     //to do
					break;
				case 8:
					 	 //to do
					break;
				case  9:
					 	 //to do
					break;
				case 5:
					 	 //to do
					break;
			}
		 keys=key_v;
		}
		 
}
	else 
		keys=0;//松手后
}

第二种算法思路(进一步优化):

直接在状态机(按键的状态扫描函数)里保持按键从case1 -case2 的值,但状态机到case 2,将值初始化为0.

按键扫描(状态机):

void key_scan(){
	
	switch(key_state){
	case 0:
		P3=0x0f;
		P42=0;
		P44=0;
		key_v=0;
		if(P3!=0x0f)	key_state=1;
			
		break;
	case 1:
			P3=0x0f;
			P42=0;
			P44=0;
			if(P3!=0x0f){
			 
			if(!P30)key_v=7;
			else if(!P31)key_v=6;
			else if(!P32)key_v=5;
			else if(!P33)key_v=4;

				
			P3=0xf0;
			P42=1;
			P44=1;
			if(!P34)key_v+=12;
			else if(!P35)key_v+=8;
			else if(!P42)key_v+=4;
			key_state=2;
				rkey=key_v;//rkey 保存从case 1跳转到case 2的键值
		}
		else 
			key_state=0;
		break;
	case 2:
		rkey=0;
		P3=0x0f;
		P42=0;
		P44=0;
		if(P3==0x0f){
			key_state=0;	
			 			
		}
		break;
	default:
		break;

}
}

main函数驱动:(伪代码)

if(keytime==20){
      keytime=0;
         switch(rkey){

            case 4://to do
                break;
            case 5://to do
                break;
            case 6://to do
                break;
            case 7://to do
                break;

}
}

若是用独立键盘扫描,则更为简单,需要注意的是在NE555频率测量的时候,由于用了P34引脚,故需在编写按键状态机函数时做诸如P3==0x0f判断时屏蔽掉P34位用P3&0x0f==0x0f替代。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 21:07:25  更:2022-03-21 21:09:20 
 
开发: 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 6:29:43-

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