普中51-独立按键实验

独立按键实验

通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,电压信号

如下图所示:
在这里插入图片描述
由于机械点的弹性作用,按键开关在闭合时不会马上稳定的接通,在断开时 也不会一下子断开,因而在闭合和断开的瞬间均伴随着一连串的抖动。抖动时间 的长短由按键的机械特性决定的,一般为 5ms 到 10ms。按键稳定闭合时间的长 短则由操作人员的按键动作决定的,一般为零点几秒至数秒。按键抖动会引起按 键被误读多次。为了确保 CPU 对按键的一次闭合仅作一次处理,必须进行消抖。

按键消抖有两种方式,一种是硬件消抖,另一种是软件消抖。为了使电路更 加简单,通常采用软件消抖。我们开发板也是采用软件消抖,一般来说一个简单 的按键消抖就是先读取按键的状态,如果得到按键按下之后,延时 10ms,再次 读取按键的状态,如果按键还是按下状态,那么说明按键已经按下。其中延时 10ms 就是软件消抖处理,至于硬件消抖,大家可以百度了解下,网上都有非常 详细的介绍。

这里给大家列出单片机常用的软件去抖动方法:

  1. 先设置 IO 口为高电平(由于开发板 IO 都有上拉电阻,所以默认 IO 为高 电平)。

  2. 读取 IO 口电平确认是否有按键按下。

  3. 如有 IO 电平为低电平后,延时几个毫秒。

  4. 再读取该 IO 电平,如果仍然为低电平,说明按键按下。

  5. 执行按键控制程序。

独立按键电路构成是由各个按键的一个管脚连接在一起接地,按键其他引脚 分别接到单片机 IO 口。

我们知道单片机的 IO 口既可作为输出也可作为输入使用,当检测按键时用 的是它的输入功能,独立按键的一端接地, 另一端与单片机的 I/O 口相连,开 始时先给该 IO 口赋一高电平,然后让单片机不断地检测该 I/O 口是否变为低 电平,当按键闭合时,即相当于该 I/O 口通过按键与地相连,变成低电平,程 序一旦检测到 I/O 口变为低电平则说明按键被按下,然后执行相应的指令。

原理图如下:
在这里插入图片描述

/*
*独立按键实验
*效果:通过按键1控制LED1,进行暗亮操作
*/
#include "reg52.h"

typedef unsigned int u16;//对系统的默认数据类型重新命名
typedef unsigned char u8;

//对独立按键管脚进行定义
sbit KEY_PRESS1 = P3^1;
sbit KEY_PRESS2 = P3^0;
sbit KEY_PRESS3 = P3^2;
sbit KEY_PRESS4 = P3^3;

//对LED1进行定义
sbit LED1 = P2^0;

//使用宏定义独立按键按下的键值
#define KEY_PRESS1_value 1
#define KEY_PRESS2_value 2
#define KEY_PRESS3_value 3
#define KEY_PRESS4_value 4
#define UN_PRESS_value 0


/*
*延时函数:当ten_us=1时延时10us	
*作用:进行消抖
*/
void delay_10us(u16 ten_us){
	
	while(ten_us--);

}

/*
*键位检查函数: model = 0 时单次扫描 model= 1时连续扫描
*
*作用:检查键位是否已经按下
*/
u8 Key_Scan(u8 model){
		static u8 key = 1;
		if(model){
			//连续扫描模式
			key = 1;
		}
		if (key==1&&(KEY_PRESS1==0||KEY_PRESS2==0||KEY_PRESS3==0||KEY_PRESS4==0)){
			delay_10us(1000);//消抖操作,防止误读
			key = 0;
			if(KEY_PRESS1 == 0){
				//按键1 按下
				return KEY_PRESS1_value;
			}else if (KEY_PRESS2 == 0){
				//按键2 按下
				return KEY_PRESS2_value;
			}else if (KEY_PRESS3 == 0){
				//按键3 按下
				return KEY_PRESS3_value;
			}else if (KEY_PRESS4 == 0){
				//按键4 按下
				return KEY_PRESS4_value;
			}
		}else if(KEY_PRESS1==1&&KEY_PRESS2==1&&KEY_PRESS3==1&&KEY_PRESS4==1){
			key = 1;
		}
		return UN_PRESS_value;
}
/*
*主函数
*/
void main(){
	u8 key = 0;
	while(1){
		key = Key_Scan(0);//调用键位检查函数,单次扫描
		if(key == KEY_PRESS1_value){//判断按键是否为按键1
			LED1 = !LED1;//led灯状态翻转
		}
	}
	
}

key_scan 函数带一个形参 mode,该参数用来设定是否连续扫描按键,如果 mode 为 0,只能操作一次按键,只有当按键松开后才能触发下次的扫描,这样 做的好处是可以防止按下一次出现多次触发的情况。如果 mode 为 1,函数是支 持连续扫描的,即使按键未松开,在函数内部有 if(mode==1)这条判断语句,因 此 key 始终是等于 1 的,所以可以连续扫描按键,当按下某个按键,会一直返 回这 个按键的键值,这样做的好处是可以很方便实现连按操作。函数内的 delay_10us(1000)即为软件消抖处理,通常延时 10ms 即可。

key_scan 函数还带有一个返回值,如果未有按键按下,返回值即为 KEY_UNPRESS,否则返回值即为对应按键的键值,如 KEY1_PRESS、KEY2_PRESS、 KEY3_PRESS、 KEY4_PRESS,这都是程序开头定义好的宏,方便大家理解和使用。 函数内定义了一个 static 变量 key,相当于全局变量,所以该函数不是一个可 重入函数。还有一点要注意的就是该函数按键的扫描是有优先级的,因为函数内 用了 if…else if…else 格式,所以最先扫描处理的按键是 KEY1,其次是 KEY2,然后是 KEY3,最后是 KEY4。如果需要将其优先级设置一样,那么可以全 部用 if 语句。

main 函数中主要就是调用 key_scan 函数用于检测按键,此时传入的 mode 值为 0,表示单次扫描按键,然后将扫描按键的值保存在变量 key 中,最后通过if 判断语句控制 LED1 状态

结束!!!文章来源地址https://uudwc.com/A/pjrgg

原文地址:https://blog.csdn.net/qq_53037676/article/details/132957749

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

上一篇 2023年09月17日 23:36
【Obsidian】中编辑模式和阅读模式光标乱跳问题以及编辑模式中段落聚集的问题解决
下一篇 2023年09月17日 23:41