矩阵键盘扫描原理

2019-04-15 12:55发布

        当一个按键两端分别接一个IO口,一个IO口置高电平另一个置低电平,当按下按键时高电平IO口电平被拉低,另一端还是为低电平,这时检测IO口值就是两个低电平。       把上述方法应用到矩阵键盘上,如果把4个行引脚接P2前4位IO口(P2.0~P2.3),都置低电平,把4个列引脚接P2后4位IO口(P2.4~P2.7),都置高电平,这时P2=0xf0, 如果按下第一列第一行按键,那么第一列的IO口电平变低,其他IO口电平不变,这时保存P2值,确定了列值。       同样,用这种方法确定行值,就是在保存列值后把4个行引脚置高电平,4个列引脚置低电平,P2=0x0f(这时按键还处于按下的状态),确定行值,最后把列值行值进行或运算得出一个保存了行值和列值的数(每个按键都有一个对应的数值) 这是我的程序:       每按下一个按键就点亮对应数量的led, #include"reg52.h" int zhi=1; void iojiance();   //检测P2 I/O口信号输入
void led(int);         //点亮LED函数,使用总线方式
void delay1s(); main()
  {
      
        while(1)
          {    
                iojiance();
                if(zhi!=1)
                        led(zhi);
            }
    } void iojiance()
  {
      int lieshu=0,hangshu=0,anjian=0,a;
        P2=0xf0;             //P2口后4位置高电平前4位置低电平,当有按键按下时确定列数
        while(P2==0xf0);     //判断P2口是否有信号输入
        lieshu=P2;         //保存列数       for(a=0;a<200;a++);         P2=0x0f;                 //P2口后4位置低电平前4位置高电平,当有按键按下时确定行数
        while(P2==0x0f);        //判断P2口是否有信号输入
        hangshu=P2;         //保存行数
        anjian=lieshu | hangshu;
        P2=0xf0;      //初始化P0         switch(anjian)
          {
                case 0x77: zhi=0x7f;break;
                case 0x7b: zhi=0xbf;break;
                case 0x7d: zhi=0xdf;break;
                case 0x7e: zhi=0xef;break;                 case 0xb7: zhi=0xf7;break;
                case 0xbb: zhi=0xfb;break;
                case 0xbd: zhi=0xfd;break;
                case 0xbe: zhi=0xfe;break;                 case 0xd7: zhi=0x3f;break;
                case 0xdb: zhi=0x5f;break;
                case 0xdd: zhi=0x6f;break;
                case 0xde: zhi=0x77;break;                 case 0xe7: zhi=0x7b;break;
                case 0xeb: zhi=0x7d;break;
                case 0xed: zhi=0x7e;break;
                case 0xee: zhi=0x1f;break;
                default:zhi=0;
            }     } void led(int x)
  {
      int a;
        P1=0xff;         //初始化P1         if(x==0)
          while(1)
              P1=0xf0;
    for(a=0;a<200;a++);       P1 = x;         
        delay1s();     //点亮相应led 1s
        P1 = 0xff;        //关闭全部led
        for(a=0;a<6000;a++);         P1 = 0;  
        delay1s(); //打开led 1s         P1 = 0xff;        //初始化
    } void delay1s(void)   //延时1s
{
    unsigned char a,b,c;
    for(c=13;c>0;c--)
        for(b=247;b>0;b--)
            for(a=142;a>0;a--);
}