蓝桥杯单片机训练[3]---矩阵键盘


CD107D开发板原理图中的矩阵键盘如图所示,乍一看好像没什么问题,写程序一测试,咦不对啊,键值怎么不对呢?这里有个小坑,原理图上给的是个是STC89C52连接的引脚,而我们实际用的是IAP15F61S2的转接板,其中P36和P37引脚位置换成了P42,P44。


批注 2020-02-26 123147

转接板如下

 
                         批注 2020-02-26 123709

到这里有的同学可能有些不知所措,因为当初学习51矩阵键盘是直接接到一个P端口的,可以直接读取端口,再转化为键值,现在引脚换了,还能那样写吗?Open-mouthed smile 当然不能!


既然不能按照以前学习那种方法写,那我们就换种方式,我们从矩阵键盘键值扫描原理出发,无非是分别扫描行和列,然后得到唯一键值,在得到键值后按照传统的方式我们必须进行消抖处理,一般我们采用软件消抖,更加方便,常规操作就是延时重复判断是否按下,这种方式在任务较少的情况下很实用,但如果在你的主线程存在着十几个任务,那么如果不引入操作系统来管理,那么任何一个任务都不宜添加任何影响其他任务的延时操作。


在这里针对按键扫描处理我们用状态转移法,就像前面数码管处理方式一样,如果一次性处理不完,我们可以选择分多次进行,具体来说,当有按键按下时,我把键值存下来,但不进行处理,待下次再执行到这里进行键值的任务处理,处理完后再次将状态转移,当再下次任务到来时如果键值已经消失,那么将状态恢复到初始时。听起来比较绕,直接看代码吧Winking smile

声明:

#include "key.h"
#include "basic.h"
//行定义
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;
u8 keybuf=0;//存储键值

函数:

void key(void)
{
    static keystate=0,a=0,b=1;
    r1=r2=r3=r4=0;
    c1=c2=c3=c4=1;
    if(!c1)a=1;
    else if(!c2)a=2;
    else if(!c3)a=3;
    else if(!c4)a=4;
    else if(c1&&c2&&c3&&c4)a=0;

    r1=r2=r3=r4=1;
    c1=c2=c3=c4=0;
    if(!r1)b=1;
    else if(!r2)b=2;
    else if(!r3)b=3;
    else if(!r4)b=4;
    else if(r1&&r2&&r3&&r4)b=1;

    keybuf=a+b*4-4;

    r1=r2=r3=r4=1;
    c1=c2=c3=c4=1;  //采集完按键必须把所有按键恢复

    switch(keystate)
    {
    case 0:
        if(keybuf!=0) keystate=1;
        break;
    case 1:
        switch(keybuf)

        {
        case 1: buff[0]=1;
            break;
        case 2: buff[0]=2;
            break;
		default: break;
        }
        keystate=2;
        break;
    case 2:
        if(keybuf==0) keystate=0;
        break;
    }

}


通过以上代码,将一次按键处理分三次执行完毕,并且由于没有任何冗余的延时函数,直接放到中断中也是OK滴,放在循环中的话,最好有其他任务进行缓冲,以保证相邻两次调用时间间隔不会太短,经过我实际测试,识别准确度还是可以的,在使用过程中还没有出现过错误识别。























猜你喜欢

转载自www.cnblogs.com/masterwayne/p/12366578.html