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

3.14 K1~K4控制数码管移位显示

本例给出不同的识别多位独立按键的方法,并用按键控制数码管的显示。

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

程序设计调试与实训:

本例用直接与P1端口状态进行比较的方法识别独立按键,因为P1端口没有连接其他元件,其状态相对固定,因此使用这种方法也能很有效地识别独立按键。在显示数码时,程序中使用了8位的显示缓冲Display_Buffer,待显示的数码被预先存在Display_Buffer数组中。

读者可将电路中原有的8位数码管改为4位数码管(例如,7SEG-MPX-CA-BLUE),然后修改代码,在4只集成式数码管上实现按键控制移位显示。

图3-12 K1~K4控制数码管移位显示电路

源程序代码

        //-----------------------------------------------------------------
        //  名称: K1~K4 控制数码管移位显示
        //-----------------------------------------------------------------
        //  说明: 按下K1时加1计数并增加显示位,
        //       按下K2时减1计数并减少显示位,
        //       按下K3时清零。
        //-----------------------------------------------------------------
        #include <reg51.h>
        #define uchar unsigned char
        #define uint  unsigned int
        //0~9的段码,0xFF为黑屏
        uchar code  DSY_CODE[] =
        {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF};
        //位码
        uchar code DSY_Index[] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
        //待显示到各数码管的数字缓冲(开始时仅在0位上显示0,其他数码管黑屏)
        uchar Display_Buffer[] = {0,10,10,10,10,10,10,10};
        //-----------------------------------------------------------------
        // 延时
        //-----------------------------------------------------------------
        void DelayMS(uint x)
        {
          uchar t;
          while(x--) for(t = 0; t < 120; t++);
        }
        //-----------------------------------------------------------------
        // 显示
        //-----------------------------------------------------------------
        void Show_Count_ON_DSY()
        {
          uchar i;
          for(i = 0; i < 8; i++)
          {
            P2 = DSY_Index[i];                   //位码
            P0 = DSY_CODE[Display_Buffer[i]] ;  //段码
            DelayMS(2);
          }
        }
        //-----------------------------------------------------------------
        // 主程序
        //-----------------------------------------------------------------
        void main()
        {
          uchar i;
          uchar Key_NO, Key_Counts=0;
          P0 = 0xFF;
          P1 = 0xFF;
          P2 = 0x00;
          while(1)
          {
            Show_Count_ON_DSY();
            P1 = 0xFF;
            Key_NO = P1;
            //P1端口按键状态分别为K1-11111110(0xFE),K2-11111101(0xFD),K3-11111011 (0xFB)
            switch(Key_NO)
            {
              case 0xFE:  Key_Counts++;
                        if (Key_Counts > 8) Key_Counts = 8;
                        Display_Buffer[Key_Counts-1] = Key_Counts;
                        break;
              case 0xFD:  if (Key_Counts > 0) Display_Buffer[--Key_Counts] = 10;
                        if (Key_Counts ==0) Display_Buffer[0] = 0;
                        break;
              case 0xFB:  Display_Buffer[0] = 0;
                        for(i = 1; i < 8; i++) Display_Buffer[i] = 10;
                        Key_Counts = 0;
            }
            //如果按键未释放则仅执行刷新显示,不进行按键扫描
            while (P1 != 0xFF) Show_Count_ON_DSY();
          }
        }