嵌入式开发学习(STC51-7-矩阵按键)

内容

按下S1-S16键,对应数码管最左边显示0-F

矩阵按键简介

独立按键与单片机连接时,每一个按键都需要单片机的一个I/O 口,若某单片机系统需较多按键,如果用独立按键便会占用过多的I/O口资源;而单片机
系统中I/O口资源往往比较宝贵,当用到多个按键时为了减少I/O口引脚,引入了矩阵按键;

以4*4矩阵键盘为例,键排成4行4列,第一行将每个按键的一端连接在一起构成行线,第一列将每个按键的另一端连接在一起构成列线,这样便一共有4行4列共8根线,我们将这8根线连接到单片机的8个I/O口上,通过程序扫描键盘就可检测16个键;

用这种方法也可实现3行3列9个键、5行5列25个键、6行6列36个键甚至更多;

无论是独立键盘还是矩阵键盘,单片机检测其是否被按下的依据都是一样的,也就是检测与该键对应的I/O口是否为低电平;

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

检测方法有多种,最常用的是行列扫描和线翻转法:

  • 行列扫描法检测时,(可以看作是每次把一列当作独立按键来检测)依次送一列为低电平,其余几列全为高电平(行全为高电平),如果检测到该列有行电平变低,即该列有按键按下,就可以确定列,然后立即检测该行哪列为低电平,则可确定行,这样我们就可确认当前被按下的键是哪一行哪一列的;当然我们也可以依次将行线置低电平(其余行列为高电平),扫描列是否有低电平;
  • 线翻转法,就是使所有行线为低电平时,检测所有列线是否有低电平,如果有,就记录列线值;然后再翻转,使所有列线都为低电平,检测所有行线的值,由于有按键按下,行线的值也会有变化,记录行线的值;得到的行列值就是按下的按键;

矩阵键盘也少不了按键消抖的环节;

原理图

线路图
在这里插入图片描述
由线路图可知,P17-14控制行,P13-10控制列

思路

使用行列扫描法,每次把一列当作独立按键来检测,依次让每列为低电位,如果某列有行变为低电位,则该行和列即是按下的按键;

注意消抖;

编码

main.c

/*
 * @Description: 矩阵按键-按下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};

/**
 * @description: 延时函数(循环一次大约10us)
 * @param {u16} ten_us
 * @return {*}
 */
void delay_10us(u16 ten_us)
{
	while (ten_us--)
		;
}

/**
 * @description: 使用行列式扫描方法,检测矩阵按键是否按下,按下则返回对应键值
 * @return {u8} key的键值
 */
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,其余全为1
	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;
}

/**
 * @description: 使用线翻转扫描方法,检测矩阵按键是否按下,按下则返回对应键值
 * @return {u8} key的键值
 */
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段码
	}
}

编译和结果

按F7编译,无错误,生成.hex文件,使用pz-isp将hex文件下载到单片机

结果:按下S1-S16键,对应数码管最左边显示0-F
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++利用mutex和thread实现一个死锁

程序 #include<iostream> #include<mutex> #include<thread> using namespace std; mutex mtx1; mutex mtx2; void A(){mtx1.lock();cout<<"a:mtx1"<<endl;this_thread::sleep_for(chrono::milliseconds(1000));mtx2.lock();cout<…

【Sa-Token】9、Sa-Token实现在线用户管理功能

尽管框架将大部分操作提供了简易的封装&#xff0c;但在一些特殊场景下&#xff0c;我们仍需要绕过框架&#xff0c;直达数据底层进行一些操作。 1、官方文档 会话查询 https://sa-token.cc/doc.html#/up/search-sessionSa-Token提供以下API助你直接操作会话列表&#xff1a…

【C++基础】友元总结一些坑

友元类 友元类&#xff08;Friend Class&#xff09;是一种在C中用于实现类之间访问权限的特殊机制。通过友元类&#xff0c;一个类可以允许另一个类访问其私有成员&#xff0c;甚至可以使另一个类成为其友元&#xff0c;使其能够访问所有成员&#xff0c;包括私有成员。这种机…

python爬虫2:requests库-原理

python爬虫2&#xff1a;requests库-原理 前言 ​ python实现网络爬虫非常简单&#xff0c;只需要掌握一定的基础知识和一定的库使用技巧即可。本系列目标旨在梳理相关知识点&#xff0c;方便以后复习。 目录结构 文章目录 python爬虫2&#xff1a;requests库-原理1. 概述2. re…

学习笔记-JVM-对象结构及生命周期

申明&#xff1a;文章内容是本人学习极客时间课程所写&#xff0c;文字和图片基本来源于课程资料&#xff0c;在某些地方会插入一点自己的理解&#xff0c;未用于商业用途&#xff0c;侵删。 原资料地址&#xff1a;课程资料 对象的创建流程 常量池检查:检查new指令是否能在常…

【设计模式——学习笔记】23种设计模式——中介者模式Observer(原理讲解+应用场景介绍+案例介绍+Java代码实现)

文章目录 案例引入案例一普通实现中介者模式 案例二 介绍基础介绍登场角色尚硅谷 《图解设计模式》 案例实现案例一&#xff1a;智能家庭类图实现 案例二&#xff1a;登录页面逻辑实现说明类图实现 总结文章说明 案例引入 案例一 普通实现 在租房过程中&#xff0c;客户可能…

2.5D游戏是如何做出来的呢,2.5D游戏快速制作教程

前言 【Unity实战篇 】 | 如何制作一款2.5D游戏&#xff0c;2.5D游戏制作案例一、2.5D 游戏概念二、绘制地图三、添加玩家动画和移动等操作四、视角配置4.1 调整摄像机与场景对象的角度4.2 增加镜头旋转功能 五、游戏效果展示 总结 前言 玩过游戏的朋友都知道&#xff0c;市面…

HarmonyOS NEXT,生命之树初长成

在不同的神话体系中&#xff0c;都有着关于生命之树的记载。 比如在北欧神话中&#xff0c;一株巨大的树木联结着九大世界&#xff0c;其被称为“尤克特拉希尔”Yggdrasill。在中国的《山海经》中&#xff0c;也有着“建木”的传说&#xff0c;它“有九欘&#xff0c;下有九枸&…

idea添加翻译插件并配置有道翻译

1、安装Translation插件 2、 创建有道云应用 有道智云控制台 3、设置idea 4、效果&#xff08;选中文本右键翻译&#xff0c;默认快捷键CtrlShiftY&#xff09;

安达发制造工业迈向智能化:APS高级计划排程助力提升生产效率

随着市场竞争的加剧&#xff0c;制造企业纷纷寻求提高生产效率和降低成本的方法。近年来&#xff0c;越来越多的制造企业开始采用APS(高级计划与排程)系统&#xff0c;以优化生产计划和排程&#xff0c;提高生产效率&#xff0c;并在竞争中取得优势。 现代制造业通常面临复杂的…

Idea中maven无法下载源码

今天在解决问题的时候想要下载源码&#xff0c;突然发现idea无法下载&#xff0c;这是真的蛋疼&#xff0c;没办法查看原因&#xff0c;最后发现问题的原因居然是因为Maven&#xff0c;由于我使用的idea的内置的Bundle3的Maven&#xff0c;之前没有研究过本地安装和内置的区别&…

ESP 32 蓝牙虚拟键盘链接笔记本电脑的键值问题

由于打算利用esp32 通过蓝牙链接电脑后实现一些特俗的键盘功能&#xff0c;所以就折腾了一下&#xff0c;折腾最耗费时间的却是键值问题&#xff0c;让一个20多年的老司机重新补充了知识 过程曲折就不说了&#xff0c;直接说结果。 我们通过网络搜索获取的键值和蓝牙模拟键盘传…

Leetcode-每日一题【剑指 Offer 11. 旋转数组的最小数字】

题目 把一个数组最开始的若干个元素搬到数组的末尾&#xff0c;我们称之为数组的旋转。 给你一个可能存在 重复 元素值的数组 numbers &#xff0c;它原来是一个升序排列的数组&#xff0c;并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如&#xff0c;数组 [3,4…

【论文阅读】对抗溯源图主机入侵检测系统的模仿攻击(NDSS-2023)

作者&#xff1a;伊利诺伊大学芝加哥分校-Akul Goyal、Gang Wang、Adam Bates&#xff1b;维克森林大学-Xueyuan Han、 引用&#xff1a;Goyal A, Han X, Wang G, et al. Sometimes, You Aren’t What You Do: Mimicry Attacks against Provenance Graph Host Intrusion Detect…

docker容器监控:Cadvisor +Prometheus+Grafana的安装部署

目录 Cadvisor PrometheusGrafana的安装部署 一、安装docker&#xff1a; 1、安装docker-ce 2、阿里云镜像加速器 3、下载组件镜像 4、创建自定义网络 二、部署Cadvisor 1、被监控主机上部署Cadvisor容器 2、访问cAdvisor页面 三、安装prometheus 1、部署Prometheus…

20230806将ASF格式的视频转换为MP4

20230806将ASF格式的视频转换为MP4 2023/8/6 18:47 缘起&#xff0c;自考中山大学的《计算机网络》&#xff0c;考试《数据库系统原理》的时候找到视频&#xff0c;由于个人的原因&#xff0c;使用字幕更加有学习效率&#xff01; 由于【重型】的PR2023占用资源较多&#xff0c…

Spring security之JWT

JWT 这里写目录标题 JWT一级目录二级目录三级目录1.什么是JWT 2.JWT的组成部分3.编码/解码4.特点5. 为什么使用JWT5.1传统的验证方式 5.2基于JWT的验证方式6.JWT进行登录验证6.1依赖安装6.2编写UserDetailServiceImpl类6.3编写UserDetailsImpl类6.4 实现config.SecurityConfig类…

算法与数据结构(二十二)动态规划解题套路框架

动态规划解题套路框架 此文只在个人总结 labuladong 动态规划框架&#xff0c;仅限于学习交流&#xff0c;版权归原作者所有&#xff1b; 动态规划问题&#xff08;Dynamic Programming&#xff09;应该是很多读者头疼的&#xff0c;不过这类问题也是最具有技巧性&#xff0c…

替换开源LDAP,某科技企业用宁盾目录统一身份,为业务敏捷提供支撑

客户介绍 某高科技企业成立于2015年&#xff0c;是一家深耕于大物流领域的人工智能公司&#xff0c;迄今为止已为全球16个国家和地区&#xff0c;120余家客户打造智能化升级体验&#xff0c;场景覆盖海陆空铁、工厂等货运物流领域。 该公司使用开源LDAP面临的挑战 挑战1 开源…

【用于全变分去噪的分裂布雷格曼方法】实施拆分布雷格曼方法进行总变异去噪研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…