3.13 K1~K4分组控制LED

本例区别于前两种方法,给出了新的识别按键的方法,在得出键号后分别对LED执行4种不同操作。

本例电路及运行效果如图3-11所示。

图3-11 K1~K4分组控制LED电路

程序设计调试与实训:

程序将4只按键所在的P1端口高4位移到低4位,如果有键按下,则这4位中必有一位为0,为便于对这一位0所在位置进行判断,代码将其预先取反,然后再右移4位,这样处理后的8位中,仅低4位中有一位为1,其他7位均为0,接下来的循环在该值不等于全0时累加按键号,并将该值向右移位,循环中止时即可得出按键号1~4,最后根据按键号执行相应操作。

读者可修改程序代码,在K1按键的长按、短按以及双击上实现不同的显示效果。

源程序代码:

        //-----------------------------------------------------------------
        //  名称: K1~K4 分组控制LED
        //-----------------------------------------------------------------
        //  说明:每次按下K1时递增点亮一只LED,全亮时再按下则再次循环开始,
        //       K2按下后点亮上面4只LED,
        //       K3按下后点亮下面4只LED,
        //       K4按下后关闭所有LED。
        //-----------------------------------------------------------------
        #include <reg51.h>
        #define uchar unsigned char
        #define uint  unsigned int
        //-----------------------------------------------------------------
        // 延时
        //-----------------------------------------------------------------
        void DelayMS(uint x)
        {
          uchar t;
          while(x--)  for(t = 0; t < 120; t++);
        }
        //-----------------------------------------------------------------
        // 主程序
        //-----------------------------------------------------------------
        void main()
        {
          uchar k,t,Key_State;
          P0 = 0xFF;
          P1 = 0xFF;
          while(1)
          {
            t = P1;
            if (t != 0xFF )
            {
                DelayMS(10);
                //再次检查按键
                if ( t != P1 ) continue;
                //取得4位按键值,由模式XXXX1111(X中有一位为0,其他均为1)
                //变为模式0000XXXX(X中有一位为1,其他均为0)
                Key_State = ~t >> 4 ;
                k = 0;
                //检查1所在位置,累加获取按键号k
                while (Key_State != 0)
                {
                  k++;
                  Key_State >>= 1;
                }
                //根据按键号k进行4种处理
                switch(k)
                {
                  case 1:  if (P0 == 0x00) P0 = 0xFF;
                          P0 <<= 1 ;
                          DelayMS(200);
                          break;
                  case 2:  P0 = 0xF0;  break;
                  case 3:  P0 = 0x0F;  break;
                  case 4:  P0 = 0xFF;
                }
            }
          }
        }