单片机C语言程序设计实训100例
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

3.11 K1~K4控制LED移位

在运行本例时,按下独立按键K1~K4键,可分别上下控制连接在P0,P2端口的LED移位显示。

本例电路如图3-9所示。

图3-9 K1~K4控制LED移位电路

程序设计调试与实训:

因为K1~K4连接在P1端口的高4位,本例在识别按键时,将P1端口的值分别与0x10、0x20、0x40、0x80进行与操作,如果与其中之一相与后结果为0,则表明对应按键按下,这4个数高4位分别是0001(1)、0010(2)、0100(4)、1000(8)。

每当有键按下时,都会立即导致LED移位显示,但按键未释放时不会形成LED连续移位显示,因为按键后Recent_Key保存了P1端口的按键状态信息,在下一个循环中,如果P1端口的按键尚未释放,则P1与Recent_Key相等,if语句内的代码不会执行,Move_LED函数不会被调用,LED不会继续出现移位显示。

每当按键释放时,P1变为0xFF,此时P1与Recent_Key不相等,if语句内的代码又再次执行,Recent_Key也变为0xFF,Move_LED函数被调用,但由于Move_LED函数内部P1 和0x10,0x20,0x40,0x80执行与操作时均不等于0,因此不会导致移位显示。

当再次有键按下时,由于P1不等于值为0xFF的Recent_Key,LED继续移位显示,整个程序的执行如此重复。

读者可以思考如果将K1~K4连接在P1端口的低4位时应该如何修改代码,另外,读者还可在单只数码管显示0~9的案例中添加按键,使按键每次按下时切换数字显示。

源程序代码:

        //-----------------------------------------------------------------
        //  名称: K1~K4控制LED移位
        //-----------------------------------------------------------------
        //  说明: 按下K1时, P0端口LED上移一位
        //       按下K2时, P0端口LED下移一位
        //       按下K3时, P2端口LED上移一位
        //       按下K4时, P2端口LED下移一位
        //-----------------------------------------------------------------
        #include <reg51.h>
        #include <intrins.h>
        #define uchar unsigned char
        #define uint  unsigned int
        //-----------------------------------------------------------------
        // 延时
        //-----------------------------------------------------------------
        void DelayMS(uint x)
        {
          uchar i;
          while(x--) for(i = 0; i < 120; i++);
        }
        //-----------------------------------------------------------------
        // 根据P1端口的按键移动LED
        //-----------------------------------------------------------------
        void Move_LED()
        {
          if    ((P1 & 0x10) == 0) P0 = _cror_(P0, 1);   //K1
          else if((P1 & 0x20) == 0) P0 = _crol_(P0, 1);   //K2
          else if((P1 & 0x40) == 0) P2 = _cror_(P2, 1);   //K3
          else if((P1 & 0x80) == 0) P2 = _crol_(P2, 1);   //K4
        }
        //-----------------------------------------------------------------
        // 主程序
        //-----------------------------------------------------------------
        void main()
        {
          uchar Recent_Key;          //最近按键
          P0 = 0xFE;
          P2 = 0xFE;
          P1 = 0xFF;
          Recent_Key = 0xFF;
          while(1)
          {
              if (Recent_Key != P1)
              {
                Recent_Key = P1;    //保存最近按键
                Move_LED();
                DelayMS(10);
              }
          }
        }