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

51单片机(国信长天)矩阵键盘的基本操作

在CT107D单片机综合训练平台上,首先将J5处的跳帽接到1~2引脚,使按键S4~S19按键组成4X4的矩阵键盘。在扫描按键的过程中,发现有按键触发信号后(不做去抖动),待按键松开后,在数码管的第一位显示相应的数字:从左至右,从上倒下,依次显示0~F。

训练重点 :
1、矩阵键盘的扫描方式与程序设计思路。2、键码的识别与基本处理。

首先Kiel5中头文件没有设置P4接口,需要我们自己声明一下

矩阵键盘的扫描也是逐行,然后再逐列

#include <REGX52.H>

unsigned char code SMG_duanma[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0x7f};


sfr P4 = 0xC0;   

sbit R1=P3^0;   
sbit R2=P3^1;
sbit R3=P3^2;
sbit R4=P3^3;

sbit C1=P4^4;
sbit C2=P4^2;

sbit C3=P3^5;
sbit C4=P3^4;

//选择实现的锁存器通道

void SelectHC573(unsigned char channel)
{
    switch(channel)
    {
        case 4 :
        P2 = (P2 & 0x1f) | 0x80;
        break;
        case 5 :
        P2 = (P2 & 0x1f) | 0xa0;
        break;
        case 6 :
        P2 = (P2 & 0x1f) | 0xc0;     
//控制数码管的位码
        break;
        case 7 :
        P2 = (P2 & 0x1f) | 0xe0; 
 //控制数码管的段码
        break;
    }
}

//实现上述通道的选择

void Display_SMG(unsigned char value)
{
    SelectHC573(6);
    P0=0x01;
    SelectHC573(7);
    P0=value;
}

按键的扫描以及功能的实现

unsigned char key_num = 0;     //定义一个变量用来显示数字

void ScanfKeysMulti()
{
    R1=0;
    R2=R3=R4=1;
    C1=C2=C3=C4=1;
    if(C1==0)
    {
        while(C1==0);
        key_num=0;
        Display_SMG(SMG_duanma[key_num]);
    }
    else if(C2==0)
    {
            while(C2==0);
            key_num=1;
            Display_SMG(SMG_duanma[key_num]);
    }
    else if(C3==0)
    {
            while(C3==0);
            key_num=2;
            Display_SMG(SMG_duanma[key_num]);
    }
    else if(C4==0)
    {
            while(C4==0);
            key_num=3;
            Display_SMG(SMG_duanma[key_num]);
    }
    
  R2=0;
    R1=R3=R4=1;
    C1=C2=C3=C4=1;
    if(C1==0)
    {
        while(C1==0);
        key_num=4;
        Display_SMG(SMG_duanma[key_num]);
    }
    else if(C2==0)
    {
            while(C2==0);
            key_num=5;
            Display_SMG(SMG_duanma[key_num]);
    }
    else if(C3==0)
    {
            while(C3==0);
            key_num=6;
            Display_SMG(SMG_duanma[key_num]);
    }
    else if(C4==0)
    {
            while(C4==0);
            key_num=7;
            Display_SMG(SMG_duanma[key_num]);
    }
    
    R3=0;
    R2=R1=R4=1;
    C1=C2=C3=C4=1;
    if(C1==0)
    {
        while(C1==0);
        key_num=8;
        Display_SMG(SMG_duanma[key_num]);
    }
    else if(C2==0)
    {
            while(C2==0);
            key_num=9;
            Display_SMG(SMG_duanma[key_num]);
    }
    else if(C3==0)
    {
            while(C3==0);
            key_num=10;
            Display_SMG(SMG_duanma[key_num]);
    }
    else if(C4==0)
    {
            while(C4==0);
            key_num=11;
            Display_SMG(SMG_duanma[key_num]);
    }
    
    R4=0;
    R2=R3=R1=1;
    C1=C2=C3=C4=1;
    if(C1==0)
    {
        while(C1==0);
        key_num=12;
        Display_SMG(SMG_duanma[key_num]);
    }
    else if(C2==0)
    {
            while(C2==0);
            key_num=13;
            Display_SMG(SMG_duanma[key_num]);
    }
    else if(C3==0)
    {
            while(C3==0);
            key_num=14;
            Display_SMG(SMG_duanma[key_num]);
    }
    else if(C4==0)
    {
            while(C4==0);
            key_num=15;
            Display_SMG(SMG_duanma[key_num]);
    }
    
    R1=0;
    R2=R3=R4=1;
    C1=C2=C3=C4=1;
    if(C1==0)
    {
        while(C1==0);
        key_num=0;
        Display_SMG(SMG_duanma[key_num]);
    }
    else if(C2==0)
    {
            while(C2==0);
            key_num=1;
            Display_SMG(SMG_duanma[key_num]);
    }
    else if(C3==0)
    {
            while(C3==0);
            key_num=2;
            Display_SMG(SMG_duanma[key_num]);
    }
    else if(C4==0)
    {
            while(C4==0);
            key_num=3;
            Display_SMG(SMG_duanma[key_num]);
    }
}

void main()
{
    while(1)
    {
        ScanfKeysMulti();
    }
}

总结:

一、功能简介

本程序基于 51 单片机(STC89C52),实现了 4×4 矩阵键盘扫描,并使用 数码管 显示按键值。按下键盘上的某个按键后,相应的数码管显示对应的键值。


二、硬件连接

  • 矩阵键盘(4×4) 采用 P3 及 P4 端口 连接:
    • 行(R1~R4):P3.0、P3.1、P3.2、P3.3
    • 列(C1~C4):P4.4、P4.2、P3.5、P3.4
  • 数码管 通过 P0 端口 输出数据,HC573 锁存器 选择数据端口。

三、程序解析

1. 数码管显示部分

unsigned char code SMG_duanma[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0x7f};

这是 共阴极数码管段码表,用于显示 0~F(共 16 个字符)。


2. 矩阵键盘扫描

矩阵键盘由 4 行 4 列组成,共 16 个按键。使用 行扫描法

  1. 行(R1-R4)逐行置低,列(C1-C4)读取状态
  2. 检测到按键按下(低电平),等待松开(防抖)
  3. 更新 key_num,调用 Display_SMG() 显示对应的数字

void ScanfKeysMulti() { R1=0; R2=R3=R4=1; C1=C2=C3=C4=1; if(C1==0) { while(C1==0); key_num=0; Display_SMG(SMG_duanma[key_num]); } else if(C2==0) { while(C2==0); key_num=1; Display_SMG(SMG_duanma[key_num]); } else if(C3==0) { while(C3==0); key_num=2; Display_SMG(SMG_duanma[key_num]); } else if(C4==0) { while(C4==0); key_num=3; Display_SMG(SMG_duanma[key_num]); } R2=0; R1=R3=R4=1; if(C1==0) { while(C1==0); key_num=4; Display_SMG(SMG_duanma[key_num]); } else if(C2==0) { while(C2==0); key_num=5; Display_SMG(SMG_duanma[key_num]); } else if(C3==0) { while(C3==0); key_num=6; Display_SMG(SMG_duanma[key_num]); } else if(C4==0) { while(C4==0); key_num=7; Display_SMG(SMG_duanma[key_num]); } // 继续扫描 R3、R4 ... }

  • 每次置低一行(R1~R4),检查 C1~C4 列 是否有低电平。
  • 若某列为低电平,说明对应按键被按下,读取按键值。
  • while(Cx==0); 等待按键松开,防止按键抖动

3. 主函数

void main() { while(1) { ScanfKeysMulti(); // 不断扫描矩阵键盘 } }

主函数通过 循环扫描键盘,并 实时更新数码管显示


四、程序优化建议

  1. 优化按键去抖

    • 目前是 while(Cx==0); 等待松开,建议增加 延时去抖

    void Delay(unsigned int t) { while(t--); } // 简单延时 if(C1==0) { Delay(1000); while(C1==0); key_num=0; Display_SMG(SMG_duanma[key_num]); }

  2. 结构优化

    • ScanfKeysMulti() 可使用 循环遍历,减少重复代码:
    void ScanfKeysMulti() { unsigned char row, col; for(row=0; row<4; row++) { R1 = R2 = R3 = R4 = 1; // 先全部置高 if(row == 0) R1 = 0; else if(row == 1) R2 = 0; else if(row == 2) R3 = 0; else if(row == 3) R4 = 0; if(C1==0) col = 0; else if(C2==0) col = 1; else if(C3==0) col = 2; else if(C4==0) col = 3; else continue; while(C1==0 || C2==0 || C3==0 || C4==0); // 等待松开 key_num = row * 4 + col; Display_SMG(SMG_duanma[key_num]); } } 

    优点:

    • 减少重复代码,提高可读性和可维护性。
    • 更易扩展到更大矩阵键盘(如 5×5、6×6)

五、总结

  • 行扫描法检测矩阵键盘,逐行拉低,读取列值。
  • 数码管通过 HC573 锁存器进行显示控制
  • 优化代码结构,减少冗余,提高可读性。
  • 可添加延时去抖,提高稳定性

相关文章:

51单片机(国信长天)矩阵键盘的基本操作

在CT107D单片机综合训练平台上&#xff0c;首先将J5处的跳帽接到1~2引脚&#xff0c;使按键S4~S19按键组成4X4的矩阵键盘。在扫描按键的过程中&#xff0c;发现有按键触发信号后(不做去抖动)&#xff0c;待按键松开后&#xff0c;在数码管的第一位显示相应的数字:从左至右&…...

封装一个sqlite3动态库

作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、项目案例 二…...

Transformer以及BERT阅读参考博文

Transformer以及BERT阅读参考博文 Transformer学习&#xff1a; 已有博主的讲解特别好了&#xff1a; 李沐&#xff1a;Transformer论文逐段精读【论文精读】_哔哩哔哩_bilibili知乎&#xff1a;Transformer模型详解&#xff08;图解最完整版&#xff09; - 知乎 个人杂想&…...

AI学习记录 - 最简单的专家模型 MOE

代码 import torch import torch.nn as nn import torch.nn.functional as F from typing import Tupleclass BasicExpert(nn.Module):# 一个 Expert 可以是一个最简单的&#xff0c; linear 层即可# 也可以是 MLP 层# 也可以是 更复杂的 MLP 层&#xff08;active function 设…...

急停信号的含义

前言&#xff1a; 大家好&#xff0c;我是上位机马工&#xff0c;硕士毕业4年年入40万&#xff0c;目前在一家自动化公司担任软件经理&#xff0c;从事C#上位机软件开发8年以上&#xff01;我们在开发C#的运动控制程序的时候&#xff0c;一个必要的步骤就是确认设备按钮的急停…...

单调队列queue

1.单调队列&#xff08;Monotonic Queue&#xff09; 单调队列是一种特殊的队列&#xff0c;它的元素按照单调性&#xff08;递增或递减&#xff09;的顺序排列。简单来说&#xff0c;单调队列会维护一个元素单调递增或递减的顺序&#xff0c;在队列中元素会根据当前队列的元素…...

【漫话机器学习系列】091.置信区间(Confidence Intervals)

置信区间&#xff08;Confidence Intervals&#xff09;详解 1. 引言 在统计学和数据分析中&#xff0c;我们通常希望通过样本数据来估计总体参数。然而&#xff0c;由于抽样的随机性&#xff0c;我们不可能得到精确的总体参数&#xff0c;而只能通过估计值&#xff08;如均值…...

UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0x99

UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0x99 这个错误通常发生在你尝试使用 GBK 编码来解码一个包含非GBK编码字符的文件时。GBK 是一种用于简体中文的字符编码方式&#xff0c;它不支持所有可能的 Unicode 字符。 解决方法 明确文件的正确编码&#xff1a;首…...

DeepSeek应用——与word的配套使用

目录 一、效果展示 二、配置方法 三、使用方法 四、注意事项 1、永久化使用 2、宏被禁用 3、office的生成失败 记录自己学习应用DeepSeek的过程...... 这个是与WPS配套使用的过程&#xff0c;office的与这个类似&#xff1a; 一、效果展示 二、配置方法 1、在最上方的…...

递归乘法算法

文章目录 递归乘法题目链接题目详解解题思路&#xff1a;代码实现&#xff1a; 结语 欢迎大家阅读我的博客&#xff0c;给生活加点impetus&#xff01;&#xff01; 让我们进入《题海探骊》&#xff0c;感受算法之美&#xff01;&#xff01; 递归乘法 题目链接 在线OJ 题目…...

【免费】2004-2020年各省废气中废气中二氧化硫排放量数据

2004-2020年各省废气中废气中二氧化硫排放量数据 1、时间&#xff1a;2004-2020年 2、来源&#xff1a;国家统计局、统计年鉴 3、指标&#xff1a;行政区划代码、地区、年份、废气中二氧化硫排放量(万吨) 4、范围&#xff1a;31省 5、指标说明&#xff1a;二氧化硫排放量指…...

CNN-LSSVM卷积神经网络最小二乘支持向量机多变量多步预测,光伏功率预测

代码地址&#xff1a;CNN-LSSVM卷积神经网络最小二乘支持向量机多变量多步预测&#xff0c;光伏功率预测 CNN-LSSVM卷积神经网络最小二乘支持向量机多变量多步预测&#xff0c;光伏功率预测 一、引言 1、研究背景和意义 光伏发电作为可再生能源的重要组成部分&#xff0c;近…...

【油猴脚本/Tampermonkey】DeepSeek 服务器繁忙无限重试(20250213优化)

目录 一、 引言 二、 逻辑 三、 源代码 四、 添加新脚本 五、 使用 六、 BUG 七、 优化日志 1.获取最后消息内容报错 一、 引言 deepseek每次第一次提问就正常&#xff0c;后面就开始繁忙了&#xff0c;有一点阴招全使我们身上。 greasyfork登不上&#xff0c;不知道…...

单调栈及相关题解

单调递增栈&#xff1a;栈中数据入栈单调递增序列(栈底到栈顶是单调递增)&#xff1b; 单调递减栈&#xff1a;栈中数据入栈单调递减序列(栈底到栈顶是单调递减)。 单调递增栈&#xff1a; 维护单调递增栈:遍历数组中每一个元素&#xff0c;执行入栈&#xff1a;每次入栈前先…...

每日温度问题:如何高效解决?

给定一个整数数组 temperatures&#xff0c;表示每天的温度&#xff0c;要求返回一个数组 answer&#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会升高&#xff0c;请在该位置用 0 来代替。 问题分析 我们需要计算…...

#渗透测试#批量漏洞挖掘#致远互联AnalyticsCloud 分析云 任意文件读取

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…...

统计安卓帧率和内存

using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class AnalysisTool : MonoBehaviour { private void Awake() { DontDestroyOnLoad(gameObject); } public Text mmText; // 用于显示FPS的UI …...

大数据学习之PB级百战出行网约车二

21.订单监控_Redis工具类 package com . itbaizhan . utils ; import redis . clients . jedis . Jedis ; import redis . clients . jedis . JedisPool ; import redis . clients . jedis . JedisPoolConfig ; /** * 操作 redis 数据库 62 */ public class Redis…...

C语言第18节:自定义类型——联合和枚举

1. 联合体 C语言中的联合体&#xff08;Union&#xff09;是一种数据结构&#xff0c;它允许在同一内存位置存储不同类型的数据。不同于结构体&#xff08;struct&#xff09;&#xff0c;结构体的成员各自占有独立的内存空间&#xff0c;而联合体的所有成员共享同一块内存区域…...

C++病毒(^_^|)(2)

第二期 声明&#xff1a; 仅供损害电脑&#xff0c;不得用于非法。损坏电脑&#xff0c;作者一律不负责。此作为作者原创&#xff0c;转载请经过同意。 直接上代码 #include <bits/stdc.h> #include <windows.h> using namespace std; HHOOK g_hHook;void lrud(…...

SAR ADC性能优化:电压基准设计与THD改善方案

1. 电压基准对SAR ADC性能的影响机制在精密数据采集系统设计中&#xff0c;工程师们常常花费大量精力选择高性能的模数转换器(ADC)和优化输入驱动电路&#xff0c;却容易忽视一个关键因素——电压基准的质量及其驱动能力。对于逐次逼近型(SAR)ADC而言&#xff0c;基准电压的稳定…...

DenseNet参数量比ResNet少?从Bottleneck和Transition层设计,聊聊模型轻量化的核心思路

DenseNet与ResNet参数效率对比&#xff1a;从结构设计看模型轻量化本质 在深度学习模型设计中&#xff0c;参数量与计算效率一直是工程师们关注的核心指标。当DenseNet首次提出时&#xff0c;许多研究者对其参数效率感到惊讶——看似复杂的密集连接结构&#xff0c;实际参数量却…...

GPU内核优化:R3框架与分层自动调优实践

1. GPU内核优化的挑战与机遇在现代高性能计算和人工智能领域&#xff0c;GPU已经成为不可或缺的计算引擎。然而&#xff0c;随着硬件架构的快速迭代&#xff0c;保持应用程序的高性能表现变得越来越具有挑战性。传统的手工优化方法需要开发者投入数月时间&#xff0c;在算法设计…...

搜搜果:一种面向AI生成内容验真与品牌可见度监测的实现方案

1. 问题定义 随着大语言模型&#xff08;LLM&#xff09;广泛集成到搜索、问答、推荐等场景中&#xff0c;出现两个可观测的问题&#xff1a; 内容可信性问题&#xff1a;模型会以高置信度输出事实上不存在的实体、事件或引用&#xff08;幻觉&#xff0c;hallucination&#…...

STM32F103C8T6驱动5V LCD1602,开漏输出+上拉电阻的硬件连接与代码避坑指南

STM32F103C8T6驱动5V LCD1602的硬件设计与代码实战指南 当3.3V的STM32遇到5V供电的LCD1602模块时&#xff0c;电平不匹配问题常常让初学者头疼不已。本文将深入解析开漏输出配合上拉电阻的解决方案&#xff0c;通过硬件原理分析、示波器实测对比和完整代码示例&#xff0c;带你…...

Go+SQLite构建极简自托管笔记共享平台:从原理到部署实战

1. 项目概述&#xff1a;一个极简、自托管的笔记共享平台最近在折腾个人知识管理工具时&#xff0c;我一直在寻找一个能让我快速分享单篇笔记或代码片段&#xff0c;同时又不想依赖第三方云服务的方案。市面上的Pastebin类工具很多&#xff0c;但要么功能臃肿&#xff0c;要么隐…...

深入理解 Tool Use 机制:AI Agent Harness Engineering 如何调用外部工具

深入理解 Tool Use 机制:AI Agent Harness Engineering 如何调用外部工具 引言 背景介绍 相信所有使用过大模型的开发者都遇到过这些典型痛点:问ChatGPT“今天北京的气温是多少”,它会告诉你“我的知识截止到2023年10月,无法提供实时天气信息”;让它计算“12345.67 * 9…...

挖掘MCU硬件加速潜力:以R80515的Double DPTR和MDU为例,在Keil C51中开启性能外挂

挖掘MCU硬件加速潜力&#xff1a;R80515双DPTR与MDU在Keil C51中的实战优化 当你在Keil C51环境下为资源受限的8051架构编写代码时&#xff0c;是否曾为缓慢的数据搬运和复杂的数学运算而头疼&#xff1f;现代增强型8051内核如R80515通过硬件加速单元提供了突破性能瓶颈的可能…...

CANN/asc-devkit bfloat16转half API

__bfloat162half_ru 【免费下载链接】asc-devkit 本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言&#xff0c;原生支持C和C标准规范&#xff0c;主要由类库和语言扩展层构成&#xff0c;提供多层级API&#xff0c;满足多维场景算子开发诉求。 项目地址: https://git…...

【信息科学与工程学】【通信工程】第四十三篇 骨干网方案设计-02跨境网络

一、方案 1.1 整体方案设计概要 设计的云网融合方案,综合考虑其全球互联需求、安全合规性、性能优化及跨国运营挑战: ​1.1.1、需求分析 ​网络互联需求:​​ ​国内互通:​​ 安全、稳定、低延迟连接中国大陆(严格合规要求)。 ​国际互通:​​ 高性能连接美国(东西海…...