矩阵键盘行列扫描

/*-----------------------------------------------

  内容:如计算器输入数据形式相同 从右至左 使用行列扫描方法
------------------------------------------------*/
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义


#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换
#define KeyPort  P1

sbit LATCH1=P2^2;//定义锁存使能端口 段锁存
sbit LATCH2=P2^3;//                 位锁存

unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
                                       0x77,0x7c,0x39,0x5e,0x79,0x71};// 显示段码值0~F
unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
unsigned char TempData[8]; //存储显示值的全局变量

void DelayUs2x(unsigned char t);//us级延时函数声明 
void DelayMs(unsigned char t); //ms级延时
void Display(unsigned char FirstBit,unsigned char Num);//数码管显示函数
unsigned char KeyScan(void);//键盘扫描
unsigned char KeyPro(void);
void Init_Timer0(void);//定时器初始化
/*------------------------------------------------
                    主函数
------------------------------------------------*/
void main (void)
{
unsigned char num,i,j;                  
unsigned char temp[8];
Init_Timer0();

while (1)         //主循环
  {


 num=KeyPro();
 if(num!=0xff)
   {
    if(i<8)
      {
       temp[i]=dofly_DuanMa[num];
       for(j=0;j<=i;j++)
          TempData[7-i+j]=temp[j];
       }
    i++;
    if(i==9)//多出一个按键输入为了清屏 原本应该为8
      {
      i=0;
           for(j=0;j<8;j++)//清屏
         TempData[j]=0;
       }
   }
  //Display(0,8); //显示全部8位
     //主循环中添加其他需要一直工作的程序
    
  }
}
/*------------------------------------------------
 uS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
 长度如下 T=tx2+5 uS 
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{   
 while(--t);
}
/*------------------------------------------------
 mS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{
     
 while(t--)
 {
     //大致延时1mS
     DelayUs2x(245);
     DelayUs2x(245);
 }
}
/*------------------------------------------------
 显示函数,用于动态扫描数码管
 输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示
 如输入0表示从第一个显示。
 Num表示需要显示的位数,如需要显示99两位数值则该值输入2
------------------------------------------------*/
void Display(unsigned char FirstBit,unsigned char Num)
{
      static unsigned char i=0;
      

       DataPort=0;   //清空数据,防止有交替重影
       LATCH1=1;     //段锁存
       LATCH1=0;

       DataPort=dofly_WeiMa[i+FirstBit]; //取位码 
       LATCH2=1;     //位锁存
       LATCH2=0;

       DataPort=TempData[i]; //取显示数据,段码
       LATCH1=1;     //段锁存
       LATCH1=0;
       
       i++;
       if(i==Num)
          i=0;


}
/*------------------------------------------------
                    定时器初始化子程序
------------------------------------------------*/
void Init_Timer0(void)
{
 TMOD |= 0x01;      //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响             
 //TH0=0x00;          //给定初值
 //TL0=0x00;
 EA=1;            //总中断打开
 ET0=1;           //定时器中断打开
 TR0=1;           //定时器开关打开
}
/*------------------------------------------------
                 定时器中断子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1 
{
 TH0=(65536-2000)/256;          //重新赋值 2ms
 TL0=(65536-2000)%256;
 
 Display(0,8);       // 调用数码管扫描

}

/*------------------------------------------------
        按键扫描函数,返回扫描键值
------------------------------------------------*/
unsigned char KeyScan(void)  //键盘扫描函数,使用行列逐级扫描法
{
 unsigned char Val;
 KeyPort=0xf0;//高四位置高,低四位拉低
 if(KeyPort!=0xf0)//表示有按键按下
   {
    DelayMs(10);  //去抖
    if(KeyPort!=0xf0)
      {           //表示有按键按下
        KeyPort=0xfe; //检测第一行
        if(KeyPort!=0xfe)
              {
              Val=KeyPort&0xf0;
                Val+=0x0e;
                while(KeyPort!=0xfe);
              DelayMs(10); //去抖
              while(KeyPort!=0xfe);
               return Val;
            }
        KeyPort=0xfd; //检测第二行
        if(KeyPort!=0xfd)
              {
              Val=KeyPort&0xf0;
                Val+=0x0d;
                while(KeyPort!=0xfd);
              DelayMs(10); //去抖
              while(KeyPort!=0xfd);
               return Val;
            }
        KeyPort=0xfb; //检测第三行
        if(KeyPort!=0xfb)
              {
              Val=KeyPort&0xf0;
                Val+=0x0b;
                while(KeyPort!=0xfb);
              DelayMs(10); //去抖
              while(KeyPort!=0xfb);
               return Val;
            }
        KeyPort=0xf7; //检测第四行
        if(KeyPort!=0xf7)
              {
              Val=KeyPort&0xf0;
                Val+=0x07;
                while(KeyPort!=0xf7);
              DelayMs(10); //去抖
              while(KeyPort!=0xf7);
               return Val;
            }
     }
   }
  return 0xff;
}
/*------------------------------------------------
         按键值处理函数,返回扫键值
------------------------------------------------*/
unsigned char KeyPro(void)
{
 switch(KeyScan())
 {
  case 0x7e:return 0;break;//0 按下相应的键显示相对应的码值
  case 0x7d:return 1;break;//1
  case 0x7b:return 2;break;//2
  case 0x77:return 3;break;//3
  case 0xbe:return 4;break;//4
  case 0xbd:return 5;break;//5
  case 0xbb:return 6;break;//6
  case 0xb7:return 7;break;//7
  case 0xde:return 8;break;//8
  case 0xdd:return 9;break;//9
  case 0xdb:return 10;break;//a
  case 0xd7:return 11;break;//b
  case 0xee:return 12;break;//c
  case 0xed:return 13;break;//d
  case 0xeb:return 14;break;//e
  case 0xe7:return 15;break;//f
  default:return 0xff;break;
 }
}
 

 

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

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

相关文章

杀死僵尸进程ZooKeeperMain

关闭Hadoop后jps发现还有个进程ZooKeeperMain没有关闭&#xff0c;使用kill -9 <>也没有用&#xff0c;这种就是僵尸进程&#xff0c;需要用父进程ID来杀死 解决方法 话不多说&#xff0c;直接上解决方案&#xff0c; 1. 第一步 清楚需要关闭的进程ID&#xff0c;我…

项目配置vue.config jsconfig babel.config .prettierc .env .eslintrc

.env 在一个产品的前端开发过程中&#xff0c;一般来说会经历本地开发、测试脚本、开发自测、测试环境、预上线环境&#xff0c;然后才能正式的发布。对应每一个环境可能都会有所差异&#xff0c;比如说服务器地址、接口地址、websorket地址…… 等等。在各个环境切换的时候&am…

小程序 | 小程序后端用什么语言开发比较好

目录 ♣️ 引言 选择合适的后端语言 推荐使用Node.js Node.js 的优点 其他备选语言 ♣️ 小结 ♣️ 引言 小程序的兴起已经成为了当今移动互联网时代的热点之一&#xff0c;而小程序后端的好坏直接影响着小程序的使用体验&#xff0c;因此&#xff0c;选择一种好的语言来…

一键批量转换,轻松将TS视频转为MP4视频,实现更广泛的播放和分享!

在享受精彩视频内容的同时&#xff0c;有时我们可能会面临一个问题&#xff1a;某些视频格式可能不太适合我们的播放设备或分享平台。特别是TS格式的视频&#xff0c;在一些情况下可能无法直接播放或上传。但是不用担心&#xff0c;因为我们为您提供了一款强大的视频剪辑工具&a…

数据特征选择 | Lasso特征选择(Python)

文章目录 效果一览文章概述源码设计小结效果一览 文章概述 Lasso算法是一种经典的线性回归算法,被广泛应用于特征选择和降维问题。相较于传统的线性回归算法,Lasso算法能够在保持预测准确性的同时,自动筛选出对目标变量影响较大的特征变量,从而达到降低模型复杂度、提高泛化…

Python文件读写实战:处理日常任务的终极工具!

更多资料获取 &#x1f4da; 个人网站&#xff1a;涛哥聊Python Python文件的读写操作时&#xff0c;有很多需要考虑的细节&#xff0c;这包括文件打开方式、读取和写入数据的方法、异常处理等。 在本文中&#xff0c;将深入探讨Python中的文件操作&#xff0c;旨在提供全面的…

TSINGSEE青犀智慧城市数字基座解决方案,助力城市数字化转型

一、行业背景 我国“十四五”规划纲要中提出&#xff0c;分级分类推进新型智慧城市建设&#xff0c;将物联网感知设施、通信系统等纳入公共基础设施统一规划建设&#xff0c;推进市政公用设施、建筑等物联网应用和智能化改造。完善城市信息模型平台和运行管理服务平台&#xf…

Godot2D角色导航-自动寻路教程(Godot设置导航代理的目标位置)

文章目录 创建导航NavigationAgent2D节点设置目标位置其他文章 创建导航 首先&#xff0c;创建一个基本的场景&#xff0c;下面的文章讲解了如何创建一个基本的导航场景&#xff0c;点击如下链接前往该文章&#xff1a; Godot2D角色导航-自动寻路教程 NavigationAgent2D节点 …

Spring Data Envers 支持有条件变动纪录的保存和查询

数据审计是业务系统的一个基本能力&#xff0c;需要系统能够将关键数据的变动纪录都保存下来&#xff0c;并支持变动纪录的查询。 通过spring-data-envers可以很容易的实现数据变动纪录的保存和查询。 有些情况下&#xff0c;我们需要只保存满足特定条件的数据变动纪录&#…

蓝桥杯(迷宫,C++)

输入&#xff1a; 思路&#xff1a; 1、注意输入用字符串。 2、采用广度搜素的方法来求解。 3、因为最后要求字典序最小且D<L<R<U,所以在遍历四个方向的时候&#xff0c; 先向下&#xff0c;再向左、右&#xff0c;最后向上。 #include<iostream> #include…

thinkphp6

unexpected , expecting case (T_CASE) or default (T_DEFAULT) or } 在模板中应用{switch}{/switch}标签,报错,其实是switch的问题&#xff0c;模板解析后&#xff0c;switch:和第一个case:之间不能有有输出的&#xff0c;一个空格也不行&#xff0c;所以第一个要紧跟着 Thi…

基于Jaya优化算法的电力系统最优潮流研究(Matlab代码实现)

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

数据库管理-第109期 19c OCM考后感(20231015)

数据库管理-第109期 19c OCM考后感&#xff08;202301015&#xff09; 距离上一篇又过了两周多&#xff0c;为啥又卡了这么久&#xff0c;主要是后面几个问题&#xff1a;1. 9月1日的19c OCM upgrade考试木有过&#xff0c;因为有一次免费补考机会就又预约了10月8日的考试&…

网络工程师知识点3

41、各个路由协议&#xff0c;在华为设备中的优先级&#xff1f; 直连路由 0 OSPF 10 静态 60 42、OSPF&#xff1a;开放式最短路径优先路由协议&#xff0c;使用SPF算法发现和计算路由 OSPF的优点&#xff1a; 1、收敛速度快&#xff0c;无路由自环&#xff0c;适用于大型网络…

FPGA面试题(6)

一.Verilog中什么情况会产生锁存器&#xff1f; 组合逻辑中&#xff1a;case语句分支不完整&#xff1b;case语句中没有default组合逻辑中&#xff1a;always语句中用if但没有else 二.FPGA和C语言有什么联系&#xff1f;Verilog与C语言的区别&#xff1f; FPGA和C语言的联系…

Docker系列--镜像和容器备份与恢复的方法

原文网址&#xff1a;Docker系列--镜像和容器备份与恢复的方法_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍备份和恢复Docker镜像与容器的方法。 命令对比 保存与导出 docker save&#xff1a;保存的是镜像&#xff08;image&#xff09;。&#xff08;保存的是分层的…

解密人工智能:KNN | K-均值 | 降维算法 | 梯度Boosting算法 | AdaBoosting算法

文章目录 一、机器学习算法简介1.1 机器学习算法包含的两个步骤1.2 机器学习算法的分类 二、KNN三、K-均值四、降维算法五、梯度Boosting算法和AdaBoosting算法六、结语 一、机器学习算法简介 机器学习算法是一种基于数据和经验的算法&#xff0c;通过对大量数据的学习和分析&…

通用人工智能技术(深度学习,大模型,Chatgpt,多模态,强化学习,具身智能)

目录 前言 1.通用人工智能 1.1 生物学分析 1.2具身智能 1.2.1当前的人工智能的局限 1.2.2 具身智能实现的基础 1.2.3 强化学习&#xff08;决策大模型&#xff09; 2.结论 往期文章 参考文献 前言 目前的人工智能实质上只是强人工智能&#xff0c;或者说单个领域的通…

软件设计师_面向对象_学习笔记

文章目录 1 面向对象基本概念2 设计模式3 UML4 设计模式4.1 设计模式的基本概念4.2 设计模式的分类4.3 创建型模式 1 面向对象基本概念 2 设计模式 3 UML 4 设计模式 4.1 设计模式的基本概念 模式&#xff1a;通俗的来说就是成功方案的复用。 架构模式从全局看待问题。设计模式…

LiveGBS流媒体平台GB/T28181功能-国标流媒体服务同时兼容内网收流外网收流多网段设备收流

LiveGBS流媒体平台GB/T28181功能-国标流媒体服务同时兼容内网收流外网收流多网段设备收流 1、背景2、设备接入播放2.1、查看通道2.2、直播播放 3、默认收流地址配置4、其它网络设备收流配置5、搭建GB28181视频直播平台 1、背景 服务器部署的时候&#xff0c;可能有多个网卡多个…