按键介绍:

        按键是一种电子开关,使用时轻轻按开关按钮就可式开关接通,当松手时,开关断开。开发板上使用的按键及内部简易图如下图:

按键管脚两端距离长的表示默认是导通状态,距离短的默认是断开状态,如果按键按下,初始导通状态变为断开,初始断开状态变为导通。

通常的按键所用开关位机械弹性开关,当机械触点断开,闭合时,电压信号如下图所示:

由于机械点的弹性作用,按键开关在闭合时不会马上稳定的接通,在断开时也不会一下子断开,因而在闭合和断开的瞬间均伴随着一连串的抖动。抖动时间在长短由按键的机械特性决定,一般为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 口变为低电平则说明按键被按下,然后执行相应的指令。

硬件设计 :

开发板上的独立按键模 块电路如下图所示:
        从上图中可以看出,4 个独立按键的控制管脚连接到 51 单片机的 P3.0-P3.3 脚上。其中 K1 连接在 P3.1 上,K2 连接在 P3.0 上,K3 连接在 P3.2 上,K4 连接 在 P3.3 上。4 个按键另一端全部连接在 GND,当按键按下后,对应 IO 口即为低 电平。
软件设计
/********************************************************************
****************** 实验名称:独立按键实验
接线说明:
实验现象:下载程序后,按下“独立按键”模块中 K1 键,控制 D1 指示灯亮灭
注意事项:
*********************************************************************
******************/
#include "reg52.h"
typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
//定义独立按键控制脚
sbit KEY1=P3^1;
sbit KEY2=P3^0;
sbit KEY3=P3^2;
sbit KEY4=P3^3;
//定义 LED1 控制脚
sbit LED1=P2^0;
/*
使用宏定义独立按键按下返回的键值
为什么要定义这个宏呢?是为了方便与我们在程序当中直接使用这个返回值,这样
后期在调用这个函数扫描的时候,得到它的返回值可以直接用KEY1_PRESS来代表,而
不是直接用1 2 3 4来表示 。1 2 3 4在我们用户在看着这个程序的时候,不知道1代表什么
2代表什么,现在KEY1_PRESS 通过英文字母我们可以知道是K1按键按下
当然觉得能看懂,也可以不用宏定义,直接用1 2 3 4 0 来表示这几个
*/
#define KEY1_PRESS 1
#define KEY2_PRESS 2
#define KEY3_PRESS 3
#define KEY4_PRESS 4
#define KEY_UNPRESS 0
/********************************************************************
***********
* 函 数 名 : delay_10us
* 函数功能 : 延时函数,ten_us=1 时,大约延时 10us
* 输 入 : ten_us
* 输 出 : 无
*********************************************************************
**********/
void delay_10us(u16 ten_us)
{while(ten_us--);
}
/********************************************************************
***********
* 函 数 名 : key_scan
* 函数功能 : 检测独立按键是否按下,按下则返回对应键值
* 输 入 : mode=0:单次扫描按键
mode=1:连续扫描按键
* 输 出 : KEY1_PRESS:K1 按下
KEY2_PRESS:K2 按下
KEY3_PRESS:K3 按下
KEY4_PRESS:K4 按下
KEY_UNPRESS:未有按键按下
*********************************************************************
**********/
u8 key_scan(u8 mode)
{static u8 key=1;//static 修饰符,key的值不会被改变,会保存上次的值
//if(mode)key=1;同if(mode==1)key=1,mode=1为真,就进入这个if,key=1,就是连续检测
//mode=1时候 mode==1不成立,为假,就不执行这个if语句,是单次检测if(mode)key=1;if(key==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0))//任意按键按下的时候为低电平{delay_10us(1000);//延时进行消抖处理
/*按键按下后key=0,不松开就不会在进入这个if,再次进行扫描按键,不会在返回这个简
return KEY1_PRESS......这几个键值了,如果没有这个key=0,不松开程序就不停的在进入
这个if在进行扫描
*/key=0;if(KEY1==0)return KEY1_PRESS;else if(KEY2==0)return KEY2_PRESS;else if(KEY3==0)return KEY3_PRESS;else if(KEY4==0)return KEY4_PRESS;}else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1) //无按键按下的时候全部都为高电平{
/*前面按键下的时候key=0,如果没有这个key=1,下次按键按下的时候key=0就不满足if(key==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0))这个,不能进行扫描,不采集的,所以在按键松开后(就是没有按键按下的时候)会执行else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1) 扫描后把赋值,更改为key=1退出程序,下次按键在按下的时候key=1,继续执行if里面的语句。
*/key=1;}
//如果按键按下,执行完return KEY1_PRESS 这条语句,返回的函数直接返回出去了,就直接
//退出这个函数了,自然后面的语句就不会在执行,如果没有按键按下,第二个if语句有而不会
//执行下去,直接就执行后面的语句,所以这条语句放在else if 的里面或者外面都可以return KEY_UNPRESS;
}
/********************************************************************
***********
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*********************************************************************
**********/
void main()
{
//因为这个ey_scan(u8 mode)是有返回值的,所以要定义一个U8类型的值来保存这个返回的键值u8 key=0;while(1){key=key_scan(0);//传入0的值是按键的单次检测,连续检测为0if(key==KEY1_PRESS)//检测按键 K1 是否按下LED1=!LED1;//按键按下的时候LED默认为高电平,所以!LED1为低电平,LED点亮,//再次按键的时候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 状态。

51单片机——独立按键实验,小白讲解,相互学习相关推荐

  1. 51单片机 | 独立按键实验

    文章目录 一.按键介绍 二.硬件设计 三.软件设计 四.实验现象   开发板上板载 4 个独立按键.通过开发板上的独立按键 K1 控制 D1 指示灯亮灭.通过独立按键实验来介绍 IO 口作为输入的使用 ...

  2. 51单片机-独立按键控制LED

    1.   51单片机独立按键的位置: 独立按键的定义:独立按键相当于一种电子开关,按下时开关接通,松开时开关断开,实现原理是通过轻触按键内部的金属弹片受力弹动来实现接通和断开: 在整个51开发板的左下 ...

  3. 自学51单片机 - 矩阵按键实验

    自学51单片机 - 矩阵按键实验 1.开发板原理图 2.程序 2.1 行列式扫描法 2.2 线翻转扫描法 3.结果 1.开发板原理图 2.程序 2.1 行列式扫描法 /**************** ...

  4. 51单片机独立按键和矩阵按键实现

    这里写目录标题 独立按键实验 矩阵按键实验 独立按键实验 按键是一种电子开关,使用时轻轻按开关按钮就可使开关接通,当松开手时, 开关断开.我们开发板上使用的按键及内部简易图如下图所示 管脚与管脚之间( ...

  5. 51单片机独立按键学习中,出现的问题以及心得

    文章目录 前言 一.出现的问题 1.问题1 2.问题2 二:心得 独立按键的短按 独立按键按住时间不同实现功能不同 总结 前言 Hello大家好,这里是万某,今天学习的是51单片机的独立按键,在此记录 ...

  6. 51单片机 | 矩阵按键实验

    文章目录 一.矩阵按键介绍 二.硬件设计 三.软件设计 四.实验现象   开发板上板载了一个 4*4 矩阵键盘.本节所要实现的功能是:通过开发板上的矩阵键盘控制静态数码管显示对应的键值 0-F. 一. ...

  7. 51单片机—独立按键的控制

    目录 一.独立按键的介绍 1.按键介绍 2.按键原理图 3.按键抖动 4.按键的消抖 二.独立按键控制LED指示灯亮灭 三.按键实验视频 总结 一.独立按键的介绍 1.按键介绍 轻触按键,相当于一种电 ...

  8. 51单片机独立按键联动数码管LED蜂鸣器

    目录: LED工作原理.电路及源码 蜂鸣器工作原理.电路及源码 数码管工作原理.电路及源码 独立按键工作原理.电路及源码 总结 LED原理,电路及源码 LED原理 LED就是发光二级管,有单向导电性, ...

  9. 51单片机-独立按键,矩阵按键,点阵

    独立按键:实现原理是通过轻触按键内部的金属弹片受力弹动来实现接通和断开. "1,2"和"3,4"管脚之间距离短,初始不导通,"1,3"和&q ...

最新文章

  1. 2019 GDUT Rating Contest I : Problem H. Mixing Milk
  2. wpf计算字符大小占像素_[读书笔记]《计算机科学速成课》——23 屏幕与2D图像显示...
  3. C实现socket编程
  4. 容器安全最佳实践入门
  5. SQLServer 系统数据库
  6. Idea Marketplace 加载很慢 加载不出来
  7. NB-IoT将为无线烟感带来哪些改变?
  8. WIN10在服务器上找不到共享打印机,win10搜索不到共享打印机怎么办
  9. RISV-Reader小结
  10. Vue项目-手机app瑞幸咖啡详解(全网最细) 从脚手架搭建到前后端数据交互(二)
  11. Maven与Git速识
  12. 实验记录 | SpeedSeq安装
  13. com.stardust.autojs.core.web
  14. 【AndroidManifest.xml详解】Manifest属性之versionCode,versionName
  15. BackTrack5 学习笔记5 扫描 Nmap
  16. JavaScript 学习总结(全)
  17. maya批量操作mel_MAYA运行单个MEL命令方法图文介绍
  18. 电脑打印机卡住端口(打印机无显示)
  19. 哪个牌子蓝牙耳机打电话清晰?通话最清晰的蓝牙耳机推荐
  20. 学科实践活动感悟50字_初中学科实践活动50字

热门文章

  1. 1561_AURIX_TC275_电源管理以及监控
  2. centos8 配置 dns_centos 8 集群Linux环境搭建 - 凭栏莫听雨落
  3. HP C7000刀片服务器学习三
  4. 【转】中国行政区域(县区级带坐标经纬度)
  5. 【Rhapsody学习笔记(三)】常用通讯点
  6. 信息图表设计入门_50信息量和精心设计的信息图表
  7. 东大22春《大学英语(三)》在线平时作业1答案非答案
  8. 【研究型论文】Encrypted Malware Traffic Detection via Graph-based Network Analysis
  9. 本地使用Maven编译报错: Unknown lifecycle phase “ompile“解决办法
  10. AZ-900免费培训+考试