当前位置: 首页 > news >正文

51单片机——按键实验

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

普中开发板是采用软件消抖,一般来说一个简单的按键消抖就是先读取按键的状态,如果得到按键按下之后,延时 10ms,再次读取按键的状态,如果按键还是按下状态,那么说明按键已经按下。其中延时10ms 就是软件消抖处理 

1、独立按键实验

P3.1控制K1, P3.0控制K2, P3.2控制K3, P3.3控制K4

软件去抖动方法:

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

(2)读取 IO 口电平确认是否有按键按下

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

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

(5)执行按键控制程序

要实现的功能是:通过开发板上的独立按键K1控制D1指示灯亮灭 

#include "reg51.h"
typedef unsigned int u16;
typedef unsigned char u8;
void delay(u16 time){
    while(time--);
}
//控制D1-D4指示灯
sbit LED1=P2^0;
sbit LED2=P2^1;
sbit LED3=P2^2;
sbit LED4=P2^3;
//使用宏定义的方法定义独立按键的键值
#define KEY1_PRESS 1
#define KEY2_PRESS 2
#define KEY3_PRESS 3
#define KEY4_PRESS 4
#define KEY_UNPRESS 0
//定义按键对应的管脚口
sbit KEY1=P3^1;
sbit KEY2=P3^0;
sbit KEY3=P3^2;
sbit KEY4=P3^3;
//封装一个函数,按键返回一个键值
u8 key_scan(u16 mode){  //mode:模式,有0和1操作,如果操作0,单次扫描;如果操作1,连续扫描
    //打一个标志
    static u16 key=1;
    if(mode==1){
        key=1;
    }
    if(key==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0)){
        //消抖处理,需要延时5ms-10ms
        delay(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){
            LED1=!LED1; 

            delay(1000);  //加一下延时可以验证单次扫描和连续扫描的情况
        }else if(key==KEY2_PRESS){
            LED2=!LED2;
        }else if(key==KEY3_PRESS){
            LED3=!LED3;
        }else if(key==KEY4_PRESS){
            LED4=!LED4;
        }
    }
}

2、矩阵按键实验

 

P1端控制矩阵键盘 

P1.7连接矩阵键盘的第1行,P1.6连接矩阵键盘的第2行,P1.5连接矩阵键盘的第3行,P1.4连接矩阵键盘的第4行

P1.3连接矩阵键盘的第1列,P1.2连接矩阵键盘的第2列,P1.1连接矩阵键盘的第3列,P1.0连接矩阵键盘的第4列

  0          0         0          0          0         0         0         0

--------------------------------------------------------------------------

P1.7    P1.6    P1.5    P1.4    P1.3    P1.2    P1.1    P1.0  

        独立键盘有一端固定为低电平,此种方式编程比较简单。 而矩阵键盘两端都与单片机 I/O 口相连,因此在检测时需编程通过单片机 I/O 口送出低电平

单片机 I/O 口送出低电平检测方法有多种,最常用的是行列扫描和线翻转法:

        (1)行列扫描法:先送一列为低电平,其余几列全为高电平(此时我们确定了列数),然后立即轮流检测一次各行是否有低电平,若检测到某一行为低电平(这时我们又确定了行数),则我们便可确认当前被按下的键是哪一行哪一列的

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

 2.1 行列扫描法

行列扫描法:先送一列为低电平,其余几列全为高电平(此时我们确定了列数),然后立即轮流检测一次各行是否有低电平,若检测到某一行为低电平(这时我们又确定了行数),则我们便可确认当前被按下的键是哪一行哪一列的

#include "reg51.h"
typedef unsigned int u16;
typedef unsigned char u8;
void delay(u16 time){
    while(time--);
}
//使用宏定义定义矩阵按键的管脚
#define KEY_MATRIX_PORT P1
//数码管:静态数码管操作
#define SMG_A_DP_PORT P0
//0-F
u16 gmsg_code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

u16 key_matrix_scan(){
    //定义一个变量返回
    u16 key_value=0;
    //给第一列赋值0,其余全为1
    KEY_MATRIX_PORT=0xf7;
    if(KEY_MATRIX_PORT!=0xf7){
        //消抖
        delay(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);
    
    
    //给第二列赋值0,其余全为1
    KEY_MATRIX_PORT=0xfb;
    if(KEY_MATRIX_PORT!=0xfb){
        //消抖
        delay(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);
    
    
    //给第三列赋值0,其余全为1
    KEY_MATRIX_PORT=0xfd;
    if(KEY_MATRIX_PORT!=0xfd){
        //消抖
        delay(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);
    
    
    //给第四列赋值0,其余全为1
    KEY_MATRIX_PORT=0xfe;
    if(KEY_MATRIX_PORT!=0xfe){
        //消抖
        delay(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;
}

void main(){
    u16 key=0;
    while(1){
        key=key_matrix_scan();
        if(key!=0){
            SMG_A_DP_PORT=gmsg_code[key-1];
        }
    }
}

2.2 线翻转法

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

 #include "reg51.h"
typedef unsigned int u16;
typedef unsigned char u8;
void delay(u16 time){
    while(time--);
}
//使用宏定义定义矩阵按键的管脚
#define KEY_MATRIX_PORT P1
//数码管:静态数码管操作
#define SMG_A_DP_PORT P0
//0-F
u16 gmsg_code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

u16 key_matrix_flip_scan(){
    u16 key_value=0;
    //使所有行线为低电平,列线为高电平
    KEY_MATRIX_PORT=0x0f;
    if(KEY_MATRIX_PORT!=0x0f){
        //消抖
        delay(1000);
        if(KEY_MATRIX_PORT!=0x0f){
            //测试列,使所有行线为低电平,列线为高电平
            KEY_MATRIX_PORT=0x0f;
            switch(KEY_MATRIX_PORT){
                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){
                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(){
    u16 key=0;
    while(1){
        key=key_matrix_flip_scan();
        if(key!=0){
            SMG_A_DP_PORT=gmsg_code[key-1];
        }
    }
}

相关文章:

51单片机——按键实验

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

QT c++ 自定义按钮类 加载图片 美化按钮

如果你有需要利用图片美化按钮的情况&#xff0c;本文能帮助你。 鼠标左键按下按钮和松开&#xff0c;按钮显示不同的图片。 1.按钮类 //因为此类比较简单&#xff0c;1个头文件搞定&#xff0c;没有cpp文件 #ifndef CUSTOMBUTTON_H #define CUSTOMBUTTON_H #include <Q…...

Django:构建高效Web应用的强大框架

在当今快速发展的Web开发领域&#xff0c;选择一个合适的框架对于项目的成功至关重要。Django&#xff0c;作为Python编程语言中最受欢迎的Web框架之一&#xff0c;凭借其强大的功能、高度的可扩展性和简洁的语法&#xff0c;成为了众多开发者心中的首选。本文将深入探讨Django…...

代码随想录算法【Day11】

150. 逆波兰表达式求值 class Solution { public:int evalRPN(vector<string>& tokens) {// 力扣修改了后台测试数据&#xff0c;需要用longlongstack<long long> st; for (int i 0; i < tokens.size(); i) {if (tokens[i] "" || tokens[i] &…...

[SeaTunnel] [MySql CDC] Generate Splits for table db.table error

在使用 SeaTunnel 的 MySQL CDC 时报错&#xff1a; Caused by: org.apache.seatunnel.engine.common.exception.SeaTunnelEngineException: java.lang.RuntimeException: Generate Splits for table db.table error SeaTunnel 版本为 2.3.8 在 GitHub 上找到一种解决方法&am…...

Spring Boot | 基于MinIO实现文件上传和下载

关注&#xff1a;CodingTechWork 介绍 在现代的 web 应用中&#xff0c;文件上传和下载是常见的需求。MinIO 是一个开源的高性能分布式对象存储服务&#xff0c;可以用来存储和管理大量的非结构化数据&#xff0c;如图片、视频、日志文件等。本文将介绍如何在 Spring Boot 应用…...

企业手机号搜索API接口

每日免费每次消耗&#xff1a;按量每日限制&#xff1a;10 次每次请求积分消耗&#xff1a;50 积分 / 次总次数限制&#xff1a;10000 次每次请求间隔&#xff1a;0 秒&#xff0c;并发&#xff1a;50 请求地址 http(s)://api.aiqimao.com/index/apiphoneget/ 调试 请求方法…...

VirtualBox Main API 学习笔记

1. Philosophy 1.1 对于Python&#xff0c;推荐使用"WEBSERVICE"连接方式 Gemini 2.0 Flash Experimental: 对于 Java 和 Python&#xff1a; 文档建议您首先使用"WEBSERVICE"&#xff0c;因为它提供了一种更直观的方式来使用 API。 2. Configuration pi…...

[Linux]Mysql9.0.1服务端脱机安装配置教程(redhat)

前言 本教程适用于在yum源不可用的LInux主机上安装Mysql的场景。 以redhat系主机做操作示例&#xff0c;debian系主机可参照步骤&#xff0c;将对应的rpm -ivh命令换成dpkg -i。 1. 官网下载安装包 https://dev.mysql.com/downloads/mysql/ 1.1 版本分类 MySQL Enterprise…...

uniapp--HBuilder开发

提示&#xff1a;本文为学习内容&#xff0c;若有错误&#xff0c;请联系作者&#xff0c;谦虚受教。 文章目录 前言一、下载HBuilder二、添加modbus相关库1.下载nodejs2.下载modbus库3.项目添加modbus库 三、HBuilder相关功能语句1.文件夹说明2.消息信息框3.开关按钮4.选中按钮…...

计算机毕业设计学习项目-P10080 基于springboot+vue的社团管理系统的设计与实现

项目说明 本号所发布的项目均由我部署运行验证&#xff0c;可保证项目系统正常运行&#xff0c;以及提供完整源码。 如需要远程部署/定制/讲解系统&#xff0c;可以联系我。定制项目未经同意不会上传&#xff01; 项目源码获取方式放在文章末尾处 注&#xff1a;项目仅供学…...

with as提高sql的执行效率

实战sql with cte(UNIT_ID, UNIT_NAME, PARENT_UNIT_ID, UNIT_CODE ) as (select UNIT_ID, UNIT_NAME, PARENT_UNIT_ID , UNIT_CODEfrom HPFM_UNITunion allselect t.UNIT_ID, t.UNIT_NAME, t.PARENT_UNIT_ID, t.UNIT_CODEfrom HPFM_UNIT tjoin cte on t.PARENT_UNIT_ID cte.U…...

【银河麒麟高级服务器操作系统实例】tcp半链接数溢出分析及处理全过程

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://document.kylinos.cn 服务器环境以及配置 系统环境 物理机/虚拟机/云…...

计算机毕业设计Python中华古诗词知识图谱可视化 古诗词智能问答系统 古诗词数据分析 古诗词情感分析模型 自然语言处理NLP 机器学习 深度学习

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

分布式ID生成-雪花算法实现无状态

雪花算法这里不再赘述&#xff0c;其缺点是有状态&#xff08;多副本隔离时&#xff0c;依赖手动配置workId和datacenterId&#xff09;&#xff0c;代码如下&#xff1a; /*** 雪花算法ID生成器*/ public class SnowflakeIdWorker {/*** 开始时间截 (2017-01-01)*/private st…...

【问题】配置 Conda 与 Pip 源

通常情况下,使用 conda 命令或者 pip 命令都是从国外的服务器上下载需要的模块包的,这在网速不佳的情况下会消耗大量的时间。所以这里建议更换国内的源来进行模块下载,速度会大大提升。 具体方法如下: 打开命令行 cmd 工具,输入以下命令。 ① Conda 换源 conda config…...

Zookeeper是如何保证事务的顺序一致性的?

大家好&#xff0c;我是锋哥。今天分享关于【Zookeeper是如何保证事务的顺序一致性的?】面试题。希望对大家有帮助&#xff1b; Zookeeper是如何保证事务的顺序一致性的? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Zookeeper 通过多个机制来保证事务的顺序一…...

东土科技参股广汽集团飞行汽车初创公司,为低空经济构建新型产业生态

近日&#xff0c;广汽集团旗下专注于飞行汽车领域的初创公司广东高域科技有限公司于2024年12月31日正式成立&#xff0c;在穿透后的股东信息中&#xff0c;东土科技通过广州瓴云科技投资合伙企业&#xff08;有限合伙&#xff09;赫然在列。 此前12月18日&#xff0c;广汽集团…...

Oracle 中的各种名称(*_name)参数的含义与作用

Oracle 中的各种名称&#xff08;*_name&#xff09;参数的含义与作用 目录 Oracle 中的各种名称&#xff08;*_name&#xff09;参数的含义与作用一、数据库名&#xff1a;db_name二、数据库所在的域&#xff1a;db_domain三、全局数据库名&#xff1a;global_name四、服务名&…...

前端页面的内容格式

TaskBuilder可以编辑的前端页面类型分为HTML和tfp&#xff08;Taskmsg Front Page&#xff09;两种格式&#xff0c;HTML格式只能用代码编辑器编辑&#xff0c;这种模式基本很少有人用&#xff0c;大家都用tfp格式&#xff0c;因为使用TaskBuilder向导创建的前端页面都是采用的…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观&#xff0c;可持续性好高效率高复用&#xff0c;可移植性好高内聚&#xff0c;低耦合没有冗余规范性&#xff0c;代码有规可循&#xff0c;可以看出自己当时的思考过程特殊排版&#xff0c;特殊语法&#xff0c;特殊指令&#xff0c;必须…...