找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2560|回复: 8
打印 上一主题 下一主题
收起左侧

关于单片机矩阵键盘程序的理解 求解释,困惑了好长时间了

[复制链接]
跳转到指定楼层
楼主
附件是矩阵键盘的原理图
以下是矩阵键盘扫描程序以及在数码管显示0-f


请问如果第一个按键被按下,P1口应该是0x07,但进入到测试列的程序中时,P1口被重新赋值为0x0f,那么P1口怎么还会一直保留原来的0x07?到测试行时又被重新赋值为0xf0,怎么还会保留原来的值呢?
跪求大佬解答,详细,感激不尽!!!!

单片机源程序如下:
#include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器

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

#define GPIO_DIG P0
#define GPIO_KEY P1


u8 KeyValue;        //用来存放读取到的键值


u8 code smgduan[17]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
                                        0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//显示0~F的值共阴
void delay(u16 i)
{
        while(i--);        
}
void KeyDown(void)
{
        char a=0;
        GPIO_KEY=0x0f;
        if(GPIO_KEY!=0x0f)//读取按键是否按下
        {
                delay(1000);//延时10ms进行消抖
                if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
                {        
                        //测试列
                        GPIO_KEY=0X0F;
                        switch(GPIO_KEY)
                        {
                                case(0X07):        KeyValue=0;break;
                                case(0X0b):        KeyValue=1;break;
                                case(0X0d): KeyValue=2;break;
                                case(0X0e):        KeyValue=3;break;
                        }
                        //测试行
                        GPIO_KEY=0XF0;
                        switch(GPIO_KEY)
                        {
                                case(0X70):        KeyValue=KeyValue;break;
                                case(0Xb0):        KeyValue=KeyValue+4;break;
                                case(0Xd0): KeyValue=KeyValue+8;break;
                                case(0Xe0):        KeyValue=KeyValue+12;break;
                        }
                        
                }
        }
        while((a<50)&&(GPIO_KEY!=0xf0))         //检测按键松手检测
        {
                delay(100);
                a++;
        }
}
void main()
{        

        while(1)
        {        
                KeyDown();                   //按键判断函数
                GPIO_DIG=~smgduan[KeyValue];          //
        }               
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:390416 发表于 2021-1-16 00:56 | 只看该作者

这就是矩阵键盘扫描的代码,主函数循环调用本函数就行 不能有死等延迟。必须计数延迟。定时器调用也行(有些浪费不建议)。
回复

使用道具 举报

板凳
ID:213173 发表于 2021-1-16 07:04 | 只看该作者
预置P1口0x0f,如果第一个按键被按下,P1口应该是0x07,此时P1的低4位当前状态已读取,以键值的方式保存在变量KeyValue中,进入到测试列的步骤时,P1口被重新赋值为0xf0,此时P1的高4位当前状态0X70再被读取并与低4位相加。测试得到的结果是0x77。最终输出KeyValue=0。
回复

使用道具 举报

地板
ID:654028 发表于 2021-1-16 09:12 | 只看该作者
按键抖动
回复

使用道具 举报

5#
ID:633344 发表于 2021-1-16 10:11 | 只看该作者
你想啊。单片机执行速度非常的快,你按下按键的时候(按下的时间很短但对于单片机来说很长了,单片机的处理速度很快)这些操作都已经进行完了,意思就是你虽然进行了赋值,但你还按下了按键,按键改变了你的赋值,然后switch case语句去判断你按下了哪个按键,
回复

使用道具 举报

6#
ID:633344 发表于 2021-1-16 10:18 | 只看该作者
单片机的处理速度很快(按键时间虽短,但在按键的时间内,单片机已经将这些处理进行完毕,意思就是你还按着那个键,赋予新的初值只是软件上的改变,而你还按着这个键就是硬件上给io口改变了赋值)软件上赋值给io口是为检测硬件上的改变(到底按了哪个键)做准备,然后switch case语句去检测到底按下了哪个键

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

7#
ID:536119 发表于 2021-1-16 16:42 | 只看该作者
yousir 发表于 2021-1-16 10:18
单片机的处理速度很快(按键时间虽短,但在按键的时间内,单片机已经将这些处理进行完毕,意思就是你还按着 ...

感谢!!!!!!
回复

使用道具 举报

8#
ID:235954 发表于 2021-1-18 15:43 | 只看该作者
按键行做输出,列做输入,只需检测列那边电平即可
回复

使用道具 举报

9#
ID:332444 发表于 2021-1-19 09:22 | 只看该作者
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表