普中51

您所在的位置:网站首页 普中51单片机开发攻略 普中51

普中51

2024-07-12 22:34| 来源: 网络整理| 查看: 265

独立按键实验

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

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

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

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

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

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

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

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

执行按键控制程序。

独立按键电路构成是由各个按键的一个管脚连接在一起接地,按键其他引脚 分别接到单片机 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 状态

结束!!!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3