找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1460|回复: 9
收起左侧

51单片机矩阵键盘有行代码不明白

[复制链接]
ID:1028013 发表于 2022-5-19 21:17 | 显示全部楼层 |阅读模式
50黑币
就是标准红色的那两行,我不明白的是第一行已经赋值给KEY_MATRIX_PORT了,那第二行里面的条件肯定是进不去的啊,头疼了一个下午,不知道是怎么回事,求指点



/*******************************************************************************
* 函 数 名       : key_matrix_ranks_scan
* 函数功能                 : 使用行列式扫描方法,检测矩阵按键是否按下,按下则返回对应键值
* 输    入       : 无
* 输    出             : key_value:1-16,对应S1-S16键,
                                   0:按键未按下
*******************************************************************************/
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;               
}

最佳答案

查看完整内容

那你可能还没弄懂准双向IO口的运作 准双向IO口赋1时会设为高阻+弱上拉 准双向IO口赋0时会设为开漏接地 并在任何时侯都可以读取IO口的电平 即是说对IO口赋值不单是设高低电平 同还改变了IO口的结构 P1=0xF7; S17按下(或者S17在P1=0xF7;前已被按下) P17的弱上拉不足以为持高电平 到 if(KEY_MATRIX_PORT!=0xf7)时 读取到KEY_MATRIX_PORT的值是0x77 KEY_MATRIX_PORT!=0xf7成立
回复

使用道具 举报

ID:161164 发表于 2022-5-19 21:17 | 显示全部楼层
nanshancc 发表于 2022-5-20 10:09
s14按下,P17就是0,P1就是 0111 1110=7E

我不太明白的地方是不管怎么按键,程序不都是循环扫描顺序执 ...

那你可能还没弄懂准双向IO口的运作
准双向IO口赋1时会设为高阻+弱上拉
准双向IO口赋0时会设为开漏接地
并在任何时侯都可以读取IO口的电平
即是说对IO口赋值不单是设高低电平
同还改变了IO口的结构

P1=0xF7;
S17按下(或者S17在P1=0xF7;前已被按下)
P17的弱上拉不足以为持高电平
到 if(KEY_MATRIX_PORT!=0xf7)时
读取到KEY_MATRIX_PORT的值是0x77
KEY_MATRIX_PORT!=0xf7成立

评分

参与人数 1黑币 +12 收起 理由
nanshancc + 12 看来还要补一下一些基础的东西,非常感谢!

查看全部评分

回复

使用道具 举报

ID:161164 发表于 2022-5-19 23:10 | 显示全部楼层
81d504bbc68a2e31e081a0431edee34a.jpg
这是一个矩阵键盘
当P1 = 0xFE时只有P10为低
如果这时S14按下P17的电平是什么?
P1的值又是多少?是否还是0xFE?

回复

使用道具 举报

ID:390416 发表于 2022-5-20 07:59 | 显示全部楼层
代码 矩阵键盘.jpg
主函数不断地扫描这个函数即可完成矩阵键盘的扫描,你的代码太长了点
回复

使用道具 举报

ID:584814 发表于 2022-5-20 08:23 | 显示全部楼层
只搞个片断无法回答;只要程序运行能得到想要的结果就没问题。
比如那个看似无解的,如果存在中断且可以重新赋值的就呵呵呵。
可仔细研读一下网文或图书上关于矩阵键盘的叙述,会扫描就好。
回复

使用道具 举报

ID:123289 发表于 2022-5-20 09:05 | 显示全部楼层
按下任何一键,都会使某两个IO口短路在一起,即等值!
例如:S14按下后:P17=P10。你要掌握一个关键点,就是1服从于0。这也是扫描键盘的原理!!!
1、让P14-P17=1111,理论上你再回读也应该是1111,如果不是0,如0110,则必是P14T和P17被接0了。
在这张图上,只有下列情况出现P14T和P17才能为0:
以P14=0解说。
S2-5中必至少有一个按下了,且按下的键的另一端是0。
这时,如果事先你让P10=0,则S2按下了。如果P13=0,则S5按下了。
这就是为何要让P10、P11、P12、P13依次为0的目的,如果有两个同时为0(P10和P13),就分不出是哪个键按下了(S2?S4?)。
如你所说:
P1=FE,即P10-17=01111111,这时P10=0。
这时,S2按下,读值为:01110111
S2S6S10S14,全部按下:01110000。
明白了吗?
回头再细想想,扫键的原理就清楚了。

评分

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

查看全部评分

回复

使用道具 举报

ID:965189 发表于 2022-5-20 09:06 | 显示全部楼层
while(KEY_MATRIX_PORT!=0xf7);//等待按键松开。这是进入下一行的条件。
回复

使用道具 举报

ID:1028013 发表于 2022-5-20 10:09 | 显示全部楼层
lkc8210 发表于 2022-5-19 23:10
这是一个矩阵键盘
当P1 = 0xFE时只有P10为低
如果这时S14按下P17的电平是什么?

s14按下,P17就是0,P1就是 0111 1110=7E

我不太明白的地方是不管怎么按键,程序不都是循环扫描顺序执行的吗

KEY_MATRIX_PORT=0xf7;//给第一列赋值0,其余全为1
        if(KEY_MATRIX_PORT!=0xf7)//判断第一列按键是否按下
        {
难道说如果有按键按下了,不会去执行第一句的赋值语句,直接就进入if判断语句了?
按键按下了,赋值语句没起作用?

我的意思就是不管怎么按键,但是在代码里面都进行了重新的赋值,那样按键好像就没起到作用(也不会进入while)。。
回复

使用道具 举报

ID:369312 发表于 2022-5-20 10:09 | 显示全部楼层
应该是按键按下的时候KEY_MATRIX_PORT的值会变化,进入判断
回复

使用道具 举报

ID:735831 发表于 2022-5-20 11:08 | 显示全部楼层
nanshancc 发表于 2022-5-20 10:09
s14按下,P17就是0,P1就是 0111 1110=7E

我不太明白的地方是不管怎么按键,程序不都是循环扫描顺序执 ...

既然是顺序执行那就得按程序先后顺序来。你这个程序明显是先赋值后判断,cpu是顺序执行,对应的键值按照判断应该也是唯一的,也不存在误判的问题。对于随时可能触发的按键,赋值语句在你开始供电的到你第一次按下按键的时候已经被执行了几百乃至几万次了,也不存在赋值语句没有执行的问题,而且你按下按键的时候,不论怎么赋值,这个硬件位置的值始终会被拉低,对应到程序上也是始终处于!0xf7。即使你重新赋值,硬件位的电压已经被拉低,那他也不会保持在0xf7状态了。

评分

参与人数 1黑币 +5 收起 理由
nanshancc + 5 可能这就是硬件程序和软件程序的区别吧

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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