51单片机独立按键以及矩阵按键的使用以及其原理--独立按键 K1 控制 D1 指示灯亮灭以及数码管显示矩阵按键 S1-S16 按下后键值 0-F

news2025/1/18 20:22:58

IO 的使用–按键

本文主要涉及8051单片机按键的使用,包括独立按键以及矩阵按键的使用以及其原理,其中代码实例包括:
1.独立按键 K1 控制 D1 指示灯亮灭
2.通过数码管显示矩阵按键 S1-S16 按下后键值 0-F

文章目录

  • IO 的使用--按键
    • 一、按键消抖
    • 二、独立按键
      • 独立按键 K1 控制 D1 指示灯亮灭
    • 二、 矩阵按键
      • 通过数码管显示矩阵按键 S1-S16 按下后键值 0-F

按键是一种电子开关,使用时轻轻按开关按钮就可使开关接通,当松开手时, 开关断开。

在了解按键之前,我们需要先了解一下按键消抖

一、按键消抖

通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,电压信号
如下图所示:
在这里插入图片描述

由于机械点的弹性作用,按键开关在闭合时不会马上稳定的接通,在断开时也不会一下子断开,因而在闭合和断开的瞬间均伴随着一连串的抖动。抖动时间的长短由按键的机械特性决定的,一般为 5ms 到 10ms。

按键消抖有两种方式,一种是硬件消抖,另一种是软件消抖。为了使电路更加简单,通常采用软件消抖。

常用的软件去抖动方法:
1,先设置 IO 口为高电平(由于开发板 IO 都有上拉电阻,所以默认 IO 为高
电平)。
2,读取 IO 口电平确认是否有按键按下。
3,如有 IO 电平为低电平后,延时几个毫秒
4,再读取该 IO 电平,如果仍然为低电平,说明按键按下。
5,执行按键控制程序。

二、独立按键

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

独立按键的原理图如下:
在这里插入图片描述

从上图中可以看出,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;
//使用宏定义独立按键按下的键值
#define KEY1_PRESS 1
#define KEY2_PRESS 2
#define KEY3_PRESS 3
#define KEY4_PRESS 4
#define KEY_UNPRESS 0

void delay_10us(u16 ten_us)
{
while(ten_us--);
}

u8 key_scan(u8 mode)
{
    static u8 key=1;
    if(mode)key=1;//连续扫描按键
    if(key==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0))//任意按键按下
    {
        delay_10us(1000);//消抖
        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=1;
    }
    return KEY_UNPRESS;
}
void main()
{
u8 key=0;
while(1)
{
    key=key_scan(0);
    if(key==KEY1_PRESS)//检测按键 K1 是否按下
    LED1=!LED1;//LED1 状态翻转
}
}

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

二、 矩阵按键

无论是独立键盘还是矩阵键盘,单片机检测其是否被按下的依据都是一样的,也就是检测与该键对应的 I/O 口是否为低电平。独立键盘有一端固定为低电平,此种方式编程比较简单。 而矩阵键盘两端都与单片机 I/O 口相连,因此在检测时需编程通过单片机 I/O 口送出低电平。检测方法有多种,最常用的是行列扫描线翻转法

行列扫描法检测时,先送一列为低电平,其余几列全为高电平(此时我们确定了列数),然后立即轮流检测一次各行是否有低电平,若检测到某一行为低电平(这时我们又确定了行数),则我们便可确认当前被按下的键是哪一行哪一列的,用同样方法轮流送各列一次低电平,再轮流检测一次各行是否变为低电平,这样即可检测完所有的按键,当有键被按下时便可判断出按下的键是哪一个键。当然我们也可以将行线置低电平,扫描列是否有低电平。从而达到整个键盘的检测。

线翻转法,就是使所有行线为低电平时,检测所有列线是否有低电平,如果有,就记录列线值;然后再翻转,使所有列线都为低电平,检测所有行线的值,由于有按键按下,行线的值也会有变化,记录行线的值。从而就可以检测到全部按键。

在这里插入图片描述

4*4 矩阵按键引出的 8 根控制线直接连接到 51 单片机的P1 口上。电路中的 P17 连接矩阵键盘的第 1 行,P13 连接矩阵键盘第 1 列

通过数码管显示矩阵按键 S1-S16 按下后键值 0-F

#include "reg52.h"
typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
#define KEY_MATRIX_PORT P1 //使用宏定义矩阵按键控制口
#define SMG_A_DP_PORT P0 //使用宏定义数码管段码口
//共阴极数码管显示 0~F 的段码数据
u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

void delay_10us(u16 ten_us)
{
    while(ten_us--);
}
//行列式扫描方式
u8 key_matrix_ranks_scan(void)
{
    u8 key_value=0;
    KEY_MATRIX_PORT=0xf7;//给第一列赋值 0,其余全为 1
    if(KEY_MATRIX_PORT!=0xf7)//判断第一列按键是否按下
    {
    delay_10us(1000);//消抖
    switch(KEY_MATRIX_PORT)//保存第一列按键按下后的键值
    {
        case 0x77: key_value=1;break;
        case 0xb7: key_value=5;break;
        case 0xd7: key_value=9;break;
        case 0xe7: key_value=13;break;
    }
    }
    while(KEY_MATRIX_PORT!=0xf7);//等待按键松开
    KEY_MATRIX_PORT=0xfb;//给第二列赋值 0,其余全为if(KEY_MATRIX_PORT!=0xfb)//判断第二列按键是否按下
    {
    delay_10us(1000);//消抖
    switch(KEY_MATRIX_PORT)//保存第二列按键按下后的键值
    {
        case 0x7b: key_value=2;break;
        case 0xbb: key_value=6;break;
        case 0xdb: key_value=10;break;
        case 0xeb: key_value=14;break;
    }
    }
    while(KEY_MATRIX_PORT!=0xfb);//等待按键松开
    KEY_MATRIX_PORT=0xfd;//给第三列赋值 0,其余全为 1
    if(KEY_MATRIX_PORT!=0xfd)//判断第三列按键是否按下
    {
    delay_10us(1000);//消抖
    switch(KEY_MATRIX_PORT)//保存第三列按键按下后的键值
    {
        case 0x7d: key_value=3;break;
        case 0xbd: key_value=7;break;
        case 0xdd: key_value=11;break;
        case 0xed: key_value=15;break;
    }
    }
    while(KEY_MATRIX_PORT!=0xfd);//等待按键松开
    KEY_MATRIX_PORT=0xfe;//给第四列赋值 0,其余全为 1
    if(KEY_MATRIX_PORT!=0xfe)//判断第四列按键是否按下
    {
    delay_10us(1000);//消抖
    switch(KEY_MATRIX_PORT)//保存第四列按键按下后的键值
    {
        case 0x7e: key_value=4;break;
        case 0xbe: key_value=8;break;
        case 0xde: key_value=12;break;
        case 0xee: key_value=16;break;
    }
    }
    while(KEY_MATRIX_PORT!=0xfe);//等待按键松开
    return key_value;
}

//线翻转式扫描方式
u8 key_matrix_flip_scan(void)
{
static u8 key_value=0;
KEY_MATRIX_PORT=0x0f;//给所有行赋值 0,列全为 1
if(KEY_MATRIX_PORT!=0x0f)//判断按键是否按下
{
    delay_10us(1000);//消抖
    if(KEY_MATRIX_PORT!=0x0f)
{
//测试列
KEY_MATRIX_PORT=0x0f;
switch(KEY_MATRIX_PORT)//保存行为 0,按键按下后的列值
{
    case 0x07: key_value=1;break;
    case 0x0b: key_value=2;break;
    case 0x0d: key_value=3;break;
    case 0x0e: key_value=4;break;
}
//测试行
KEY_MATRIX_PORT=0xf0;
switch(KEY_MATRIX_PORT)//保存列为 0,按键按下后的键值
{
    case 0x70: key_value=key_value;break;
    case 0xb0: key_value=key_value+4;break;
    case 0xd0: key_value=key_value+8;break;
    case 0xe0: key_value=key_value+12;break;
}
    while(KEY_MATRIX_PORT!=0xf0);//等待按键松开
    }
    }
    else
    key_value=0;
    return key_value;
}


void main()
{
u8 key=0;
while(1)
{
key=key_matrix_ranks_scan();
if(key!=0)
SMG_A_DP_PORT=gsmg_code[key-1];//得到的按键值减 1 换算成数组下标
对应 0-F 段码
}
}

上述学习资料都是来自普中科技😀

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1298897.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MobaXterm成功连接到开发环境后,过一段时间会自动断开。

问题现象 MobaXterm成功连接到开发环境后,过一段时间会自动断开。 原因 配置MobaXterm工具时,没有勾选“SSH keepalive”或专业版MobaXterm工具的“Stop server after”时间设置太短。

8. MySQL 触发器

目录 概述 定义 触发器特性: 基础操作 创建触发器 NEW和OLD 其他操作 查看触发器 删除触发器 注意事项 概述 定义 触发器,就是一种特殊的存储过程。触发器和存储过程一样是一个能够完成特定功能、存储在数据库服务器上的SQL片段,但是触…

跨平台的文本编辑器——CudaText

CudaText 是一个轻量级、跨平台的文本编辑器,它免费开源,启动速度非常快,有拓展功能,可安装插件。 下载 浏览器搜索框输入CudaText - Home进行搜索, 选择官网进入, 进入官网界面如下:选择点击…

C++初阶-vector的介绍及使用

vector的介绍及使用 一、vector的介绍1.1 vector的概念 二、vector的使用2.1 vector的定义2.2 vector iterator的使用2.3 vector空间增长问题2.4 vector的增删改查2.5 vector的整体代码实现2.5.1 vector的常用内置函数使用2.5.2 vector的访问方式及测试函数 三、vector迭代器失…

15.Java程序设计-基于SSM框架的微信小程序校园求职系统的设计与实现

摘要: 本研究旨在设计并实现一款基于SSM框架的微信小程序校园求职系统,以提升校园求职流程的效率和便捷性。通过整合微信小程序平台和SSM框架的优势,本系统涵盖了用户管理、职位发布与搜索、简历管理、消息通知等多个功能模块,为…

Ubuntu与Windows通讯传输文件(FTP服务器版)(没用的方法,无法施行)

本文介绍再Windows主机上建立FTP服务器,并且在Ubuntu虚拟机上面访问Windows上FTP服务器的方法 只要按照上图配置就可以了 第二部:打开IIS管理控制台 右击网站,新建FTP站点。需要注意的一点是在填写IP地址的时候,只需要填写Window…

python操作MySQL数据库简单示例

通过python的pymysql模块,实现数据库表的创建、插入以及查询的简单示例。 1. 数据库表创建。 # -*- coding:utf-8 -*- """ 使用python操作MySQL数据库示例 执行sql_create语句建立数据库表books """import pymysqldef main():# 首先…

nodejs微信小程序+python+PHP北京地铁票务APP-计算机毕业设计推荐 -安卓

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性:…

postgresql自带指令命令系列三

目录 简介 bin目录 28.pg_verifybackup 29.pg_waldump 30.postgres 31.postmaster -> postgres 32.psql 33.reindexdb 34.vacuumdb 35.vacuumlo 总结: 简介 在安装postgresql数据库的时候会需要设置一个关于postgresql数据库的PATH变量 export PATH/…

PTA 输出三角形面积和周长

#include<stdio.h> #include<math.h>//使用sqrt需要使用此头文件 int main() {int a, b, c, d;float s, area, perimeter;scanf("%d %d %d", &a, &b, &c);if (a b < c || a c < b || b c < a)//三角形任意两边之和大于第三边pri…

【小白专用】在 vs 中使用 nuget 安装NPOI

C#操作Excel有多种方法&#xff0c;如通过数据库的方式来读写Excel的OleDb方式&#xff0c;但是OleDb方式需要安装微软office&#xff0c;还可以通过COM组件方式操作Excel&#xff0c;也需要安装微软Excel。如果不想安装微软办公套餐可以使用ClosedXML、EPPlus、NPOI。本文主要…

【Linux】如何对文本文件进行有条件地划分?——cut命令

cut 命令可以根据一个指定的标记&#xff08;默认是 tab&#xff09;来为文本划分列&#xff0c;然后将此列显示。 例如想要显示 passwd 文件的第一列可以使用以下命令&#xff1a;cut –f 1 –d : /etc/passwd cut&#xff1a;用于从文件的每一行中提取部分内容的命令。-f 1&…

windows建立软链 报 无法将“mklink”项识别为 cmdlet、函数、脚本文件或可运行程序的名称

当我执行网上提供的mklink 的时候&#xff0c;出现 mklink : 无法将“mklink”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。怎么回事&#xff0c;原来&#xff0c;要在执行的签名加 cmd /c 当我执行建立软链接时&#xff0c;提示 没有足够的权限&#xff0c;要用管理…

玩转大数据13: 数据伦理与合规性探讨

1. 引言 随着科技的飞速发展&#xff0c;数据已经成为了现代社会的宝贵资产。然而&#xff0c;数据的收集、处理和利用也带来了一系列的伦理和合规性问题。数据伦理和合规性不仅关乎个人隐私和权益的保护&#xff0c;还涉及到企业的商业利益和社会责任。因此&#xff0c;数据…

【ArcGIS微课1000例】0079:ArcGIS Earth根据经纬坐标生成点shapefile

本文以气象台站数据的生成为例,详细介绍ArcGIS Earth中导入X、Y经纬度坐标,生成Shapefile点数据的流程。 文章目录 一、气象台站分布二、添加经纬度坐标三、符号化设置四、另存为一、气象台站分布 根据气象台站的经纬度坐标,可以很方便的在各种GIS平台上生成点,并保存为多…

CPU运行AI模型记录

使用 CPU 运行 AI 模型 目前人工智能很火&#xff0c;但是手头没有合适的显卡&#xff0c;成了瓶颈和门槛&#xff0c;一直没机会试下。正好知乎上看到一篇文章&#xff0c; CPU 运行中文模型&#xff0c;最近换了台机器。垃圾佬 E5 平台&#xff0c;性能不高&#xff0c;但是…

附录A SQL入门之样例表

编写SQL语句需要良好地理解基本数据库设计。如果不知道什么信息存放在什么表中&#xff0c;表与表之间如何互相关联&#xff0c;行中数据如何分解&#xff0c;那么要编 写高效的SQL是不可能的。 强烈建议读者实际练习本书的每个例子。所有课都共同使用了一组数据文件。为帮助你…

Linux CentOS 7.6安装jdk1.8教程

安装教程 第一种方式&#xff08;通过yum安装&#xff09;&#xff1a;第一步&#xff1a;输入查找命令&#xff1a;第二步&#xff1a;输入安装命令&#xff1a;第三步&#xff1a;安装完成&#xff0c;输入安装命令后&#xff0c;等到出现Complete&#xff01;代表安装完成第…

springboot+jdbcTemplate+sqlite编程示例——以沪深300成分股数据处理为例

引言 我们在自己做一些小的项目或者小的数据处理分析的时候&#xff0c;很多时候是不需要用到mysql这样的大型数据库&#xff0c;并且也不需要用到maven这样很重的框架的&#xff0c;取而代之可以使用jdbcTemplatesqlite这样的组合。 本文就介绍一下使用springbootjdbcTempla…

画对比折线图【Python】

出这一期想必是我做某个课程作业遇到了。 由于去各个官网下载对比图要钱&#xff0c;我还是不想花钱的&#xff01;真讨厌&#xff01;浅浅水一期。 以下是要做的对比图的数据&#xff1a; 代码&#xff1a; from matplotlib import pyplot as plt#设置中文显示plt.rcParams[…