热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

单片机:矩阵按键(行列法和线翻转法都有)

硬件部分(A2-A4和A5-A7芯片有所不同)A2-A4A5-A7(考虑兼容性,推荐8-1端口依次使用P10-P17&#

硬件部分(A2-A4和A5-A7芯片有所不同)

A2-A4

 A5-A7

(考虑兼容性,推荐8-1端口依次使用P10-P17)

 

软件部分:

 

行列法

#include"reg52.h"

typedef unsigned char u8;
typedef unsigned int u16;

#define SMG_A_DP_PORT    P0//数码管对应端口定义

#define KEY_MATRIX_PORT  P1//矩阵按键函数端口定义


//共阴数码管输入以下值分别会显示0-F
u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,
                    0x7d,0x07,0x7f,0x6f,0x77,0x7c,
                    0x39,0x5e,0x79,0x71};

//延时函数                                    
void time_delay(u16 delay_time)
{
    while(delay_time--);
}

//矩阵按键函数
u8 key_matrix_ranks_scan(void)//不需要形参
{
    u8 key_value=0;//定义接收返回值,使之可读性高
    
    //赋值使之第一列矩阵按键为0,低电平
    KEY_MATRIX_PORT=0xf7;
    if(KEY_MATRIX_PORT!=0xf7)//此时按键按下
    {
            time_delay(1000);//消抖
        switch(KEY_MATRIX_PORT)//为真就是!=0
        {
            //只有四种情况,0x77,0xb7,0xd7,0xe7,
            //分别给固定输出结果
            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,低电平
    KEY_MATRIX_PORT=0xfb;
    if(KEY_MATRIX_PORT!=0xfb)//此时按键按下
    {
            time_delay(1000);//消抖
        switch(KEY_MATRIX_PORT)
        {
            //只有四种情况,0x7b,0xbb,0xdb,0xeb,
            //分别给固定输出结果
            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,低电平
    KEY_MATRIX_PORT=0xfd;
    if(KEY_MATRIX_PORT!=0xfd)//此时按键按下
    {
            time_delay(1000);//消抖
        switch(KEY_MATRIX_PORT)
        {
            //只有四种情况,0x7d,0xbd,0xdd,0xed,
            //分别给固定输出结果
            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,低电平
    KEY_MATRIX_PORT=0xfe;
    if(KEY_MATRIX_PORT!=0xfe)//此时按键按下
    {
            time_delay(1000);//消抖
        switch(KEY_MATRIX_PORT)
        {
            //只有四种情况,0x7e,0xbe,0xde,0xee,
            //分别给固定输出结果
            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()
{
    u8 key=0;
    while(1)
    {
        key=key_matrix_ranks_scan();
        if(key!=0)
            SMG_A_DP_PORT=gsmg_code[key-1];
    }
}

 

线翻转法:

#include"reg52.h"

//对数据类型进行重定义
typedef unsigned char u8;
typedef unsigned int u16;

//宏定义数码管段码口
#define SMG_A_DP_PORT          P0

//宏定义矩阵按键控制口
#define KEY_MATRIX_PORT        P1

//共阴极数码管显示0~F的段码数据
u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};    

//延时函数
void time_delay(u16 delay_time)
{
    while(delay_time--);
}

u8 key_matrix_ranks_scan(void)//线翻转法
{
    static u8 key_value=0;
    KEY_MATRIX_PORT=0x0f;//给所有行赋值0,列赋值1
  if(KEY_MATRIX_PORT!=0x0f)//判断按键是否按下
    {
        time_delay(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];
    }
}

 


推荐阅读
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文介绍了一个Java猜拳小游戏的代码,通过使用Scanner类获取用户输入的拳的数字,并随机生成计算机的拳,然后判断胜负。该游戏可以选择剪刀、石头、布三种拳,通过比较两者的拳来决定胜负。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
author-avatar
投资改变生活-青岛_688
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有