找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3913|回复: 7
打印 上一主题 下一主题
收起左侧

单片机按键数码管的组合使用 附源程序

[复制链接]
跳转到指定楼层
楼主
        这次我们用4个独立按键和8位数码管来做一个正计数器和倒计时器,到时间后(正计时最大值,倒计时最小值)LED灯闪烁10秒熄灭(大家可以先自己想好步骤,再看一下我下面的思路步骤)我用的单片机是STC89C52

主要的步骤:1、先思考正计数,倒计数需要定时器中断。还需要按键处理函数。另外需要一个数码管显示函数。


        2、如何将这三个程序有序的排列组合起来形成一个完整的程序,这时我们可以从正计时器入手(也可以从倒计时入手)(由简入深,抓住主干)先规定K1代表正计数器的开和关,K2代表秒分时的移位,K3代表自加,K4代表自减。还有就是正计数到达最大值的时候LED灯进行闪烁。


        3、这时就要用标志位来分清关系。
        第一部分按键程序,具体操作就是用flag0代表正计数器的开关,knum代表K2按下的时候到底是秒分时哪个 ,K3代表按一下加,K4代表按一下减,这时我们的按键程序基本完成;
        第二部分就是我们的定时器中断函数,因为定时器我选的时16位非自动重装10ms,所以要累计100次到一秒,大家要注意如果你选的是1ms定时,就需要累计1000次,记着你的数据类型要选int或者unsigned int,这部分容易忽略。还有当K2按下,标志位knum进行改变也就代表着秒分时要开始闪烁。这时要进行计数操作也就是当计数时间到时,flag1进行改变,控制秒分时的闪烁时间间隔。当计数时间到的时候还需要flag2的改变这样控制LED灯的闪烁频率以及时间。
        第三部分就是我们的数码管显示程序,这个程序要根据knum的值进行改变,当knum=0时它直接进行显示,当knum!=0也就是K2按下的时候,根据flag1的值来闪烁。
        第四部分就是我们要看到效果,当正计数器到达最大值的时候LED灯开始闪烁。只需在正计数结束的时候控制flag2。
        第五部分当你把前四部分都解决了之后,那么你就可以着手做互锁关系了,当我们正计数的时候我们不能进行移位操作,也就是说正计数器的开启与移位操作形成互锁(我们可以加if语句这样就实现了)。
        接下来就是K3,4长按和短按操作,短按加减一次,长按连加减。
        我们想要实现的还有倒计时器的设定这时我们可以将K1也设定为长按和短按,长按倒计时器,短按正计数器。同时此时也会出现两者的相互干扰情况,于是再设定一个互锁,这样就就避免了(用if语句来解决,就用我们现成的标志位)。因为我们将K1,K3,K4都用了长按短按,所以就让K2的长按也有功能,就是全体清零,LED灯闪烁。
        第六部分就是大家发现了吗?就是在进行长按的时候,由于我们这时候还想要数码管继续显示,所以我在长按的while循环里做了显示,但这个显示函数单次显示只用了1ms,这样我们显示了八次,再加上一次延时1ms,我近似认为一次长按循环所需时间为10ms,这一点大家做长按,短按的时候会遇到的,还有就是数码管显示函数的延时时间长短,会改变数码管亮度。大家可以自己写一下这个程序,写完就理解我为什么要这样写了。
        有错误请指出,谢谢。

单片机源程序如下:
  1. #include"digdisplay.h"
  2. sbit k1=P3^1;                        //短按进行计数操作,长按进行倒计时操作
  3. sbit k2=P3^0;                        //短按进行秒分时的移位闪烁,长按进行秒分时归零,没有移位闪烁,LED灯闪烁开始
  4. sbit k3=P3^2;                        //短按进行秒分时(看K2让谁闪烁)的加一操作 ,长按进行连加操作(K2让谁闪烁)
  5. sbit k4=P3^3;                        //短按进行秒分时(看K2让谁闪烁)的减一操作 ,长按进行连减操作(K2让谁闪烁)
  6. sbit led=P2^0;                        //当计数到最大值时LED灯开始闪烁,当倒计时到零时开始闪烁
  7. u8 datenume[6]={0,0,0,0,0,0};         //当做存储秒分时的值,通过运算转换为数码管显示的值
  8. u8 miao=0,fen=0,shi=0,count,knum=0,flag0=0,time=0,flag1=0,flag2=0,flag3=0,time_count=0;                  //flag0是否进行计数操作,falg1秒分时的闪烁标志位,falg2是定时或计数到时LED灯进行闪烁,flag3是否进行倒计时操作,knum进行移位操作的标志性
  9. u8 a,b,c,d,e;                          //这几个都代表数值,计算时间用的,你可以在程序中发现它们

  10. void Delay5ms()                //@12.000MHz
  11. {
  12.         unsigned char i, j;

  13.         i = 10;
  14.         j = 183;
  15.         do
  16.         {
  17.                 while (--j);
  18.         } while (--i);
  19. }


  20. void keyprogress()                        //对四个固定按键进行操作,具体操作如下
  21. {
  22.            if(!k1)
  23.         {
  24.            Delay5ms();
  25.            if(!k1)
  26.            {
  27.              while(!k1)
  28.                  {
  29.                      digdisplay(0,datenume[0]);
  30.                  digdisplay(1,datenume[1]);
  31.                  digdisplay(2,16);
  32.                  digdisplay(3,datenume[2]);
  33.                  digdisplay(4,datenume[3]);
  34.                  digdisplay(5,16);
  35.                  digdisplay(6,datenume[4]);
  36.                  digdisplay(7,datenume[5]);
  37.                     d++;
  38.                         Delay1ms();
  39.                         if(d==100)
  40.                         {
  41.                           if(knum==0&&flag0==0&&(miao!=0||fen!=0||shi!=0))          //计数器和倒计时形成互锁当秒分时都为零时不能进行倒计时
  42.                           {
  43.                            flag3=!flag3;  //开启倒计时和关闭倒计时
  44.                       }
  45.                         }
  46.                  }
  47.                  if(d<100)
  48.                  {
  49.               if(knum==0&&flag3==0)           //当没进行移位操作时才可以启动计数器,解决了移位时计数器开启问题,互锁
  50.                   {                                                   //计数器和倒计时形成互锁
  51.                 flag0=!flag0;                   //开启计数器和关闭计数器
  52.                   }
  53.                  }
  54.                  d=0;
  55.            }
  56.         }
  57.         if(!k2)
  58.         {
  59.            Delay5ms();
  60.            if(!k2)
  61.            {
  62.              while(!k2)
  63.                  {
  64.                      digdisplay(0,datenume[0]);
  65.                  digdisplay(1,datenume[1]);
  66.                  digdisplay(2,16);
  67.                  digdisplay(3,datenume[2]);
  68.                  digdisplay(4,datenume[3]);
  69.                  digdisplay(5,16);
  70.                  digdisplay(6,datenume[4]);
  71.                  digdisplay(7,datenume[5]);
  72.                             e++;
  73.                          Delay1ms();
  74.                          if(e==100)                 //全体归零LED灯闪烁
  75.                          {
  76.                                    flag0=0;
  77.                                 flag1=0;
  78.                                 flag2=1;
  79.                                 flag3=0;
  80.                                 knum=0;
  81.                                 shi=0;
  82.                                 fen=0;
  83.                                 miao=0;
  84.                          }
  85.                  }
  86.              if(flag0==0&&e<100)                //解决了当移位操作时计数器开启问题,形成必须要计数器关闭才能开始移位,形成互锁
  87.                 {
  88.               knum++;
  89.                   if(knum==4)
  90.                   {
  91.                     knum=0;
  92.                   }
  93.                 }
  94.                 e=0;
  95.            }
  96.         }
  97.         if(!k3)                                                        //必须在有移位操作的时候才能加,也算一个锁定
  98.         {
  99.          Delay5ms();
  100.           if(!k3)
  101.          {
  102.           while(!k3)
  103.           {
  104.           digdisplay(0,datenume[0]);
  105.           digdisplay(1,datenume[1]);
  106.           digdisplay(2,16);
  107.           digdisplay(3,datenume[2]);
  108.           digdisplay(4,datenume[3]);
  109.           digdisplay(5,16);
  110.           digdisplay(6,datenume[4]);
  111.           digdisplay(7,datenume[5]);
  112.             Delay1ms();
  113.                 a++;
  114.                 if(a==100)
  115.                 {
  116.                   a=50;
  117.                    if(knum==1)
  118.                    {
  119.                       miao++;
  120.                           if(miao==60)
  121.                           {
  122.                              miao=0;
  123.                           }
  124.                    }
  125.                    else if(knum==2)
  126.                    {
  127.                       fen++;
  128.                           if(fen==60)
  129.                           {
  130.                               fen=0;
  131.                           }
  132.                    }
  133.                    else if(knum==3)
  134.                    {
  135.                       shi++;
  136.                           if(shi==24)
  137.                           {
  138.                               shi=0;
  139.                           }
  140.                    }
  141.                 }
  142.           }
  143.                 if(knum!=0)
  144.            {
  145.                 if(a<50)
  146.                 {
  147.                    if(knum==1)
  148.                   {
  149.                    miao++;
  150.                    if(miao==60)
  151.                    {
  152.                      miao=0;
  153.                    }
  154.                   }
  155.                   else if(knum==2)
  156.                   {
  157.                     fen++;
  158.                         if(fen==60)
  159.                         {
  160.                           fen=0;
  161.                         }
  162.                   }
  163.                   else if(knum==3)
  164.                   {
  165.                      shi++;
  166.                          if(shi==24)
  167.                          {
  168.                            shi=0;
  169.                          }
  170.                   }
  171.                 }
  172.            }
  173.        a=0;
  174.          }
  175.         }
  176.         if(!k4)                                                          //必须在有移位操作时才可以自减
  177.         {
  178.           Delay5ms();
  179.            if(!k4)
  180.            {
  181.              while(!k4)
  182.                  {
  183.            digdisplay(0,datenume[0]);
  184.                digdisplay(1,datenume[1]);
  185.                digdisplay(2,16);
  186.                digdisplay(3,datenume[2]);
  187.                digdisplay(4,datenume[3]);
  188.                digdisplay(5,16);
  189.                digdisplay(6,datenume[4]);
  190.                digdisplay(7,datenume[5]);
  191.                Delay1ms();
  192.                    a++;
  193.                    if(a==100)
  194.                    {
  195.                      a=50;
  196.                          if(knum==1)
  197.                          {
  198.                            miao--;
  199.                            if(miao==255)
  200.                            {
  201.                              miao=59;
  202.                            }
  203.                          }
  204.                          if(knum==2)
  205.                          {
  206.                             fen--;
  207.                                 if(fen==255)
  208.                                 {
  209.                                    fen=59;
  210.                                 }
  211.                          }
  212.                          if(knum==3)
  213.                          {
  214.                             shi--;
  215.                                 if(shi==255)
  216.                                 {
  217.                                    shi=23;
  218.                                 }
  219.                          }
  220.                    }
  221.                  }
  222.                  if(a<50)
  223.                  {
  224.               if(knum==1)
  225.                   {
  226.                     miao--;
  227.                         if(miao==255)
  228.                         {
  229.                           miao=59;
  230.                         }
  231.                   }
  232.                   else if(knum==2)
  233.                   {
  234.                      fen--;
  235.                          if(fen==255)
  236.                          {
  237.                            fen=59;
  238.                          }
  239.                   }
  240.                  else if(knum==3)
  241.                   {
  242.                      shi--;
  243.                          if(shi==255)
  244.                          {
  245.                                    shi=23;
  246.                          }
  247.                   }
  248.                  }
  249.                  a=0;
  250.            }
  251.         }
  252. }
  253. void shuma()                                //做数码管显示函数,当knum=0时普通显示,当knum!=0时靠标志位flag1决定闪烁
  254. {
  255.     if(knum==0)
  256.         {
  257.           digdisplay(0,datenume[0]);
  258.           digdisplay(1,datenume[1]);
  259.           digdisplay(2,16);
  260.           digdisplay(3,datenume[2]);
  261.           digdisplay(4,datenume[3]);
  262.           digdisplay(5,16);
  263.           digdisplay(6,datenume[4]);
  264.           digdisplay(7,datenume[5]);
  265.         }
  266.   else if(knum==1)
  267.    {
  268.      if(flag1)
  269.          {                                                                                                                                                                                                                                                                                          
  270.       digdisplay(0,datenume[0]);
  271.           digdisplay(1,datenume[1]);
  272.           digdisplay(2,16);
  273.           digdisplay(3,datenume[2]);
  274.           digdisplay(4,datenume[3]);
  275.           digdisplay(5,16);
  276.           digdisplay(6,datenume[4]);
  277.           digdisplay(7,datenume[5]);
  278.          }
  279.          else
  280.          {
  281.           digdisplay(0,17);
  282.           digdisplay(1,17);
  283.           digdisplay(2,16);
  284.           digdisplay(3,datenume[2]);
  285.           digdisplay(4,datenume[3]);
  286.           digdisplay(5,16);
  287.           digdisplay(6,datenume[4]);
  288.           digdisplay(7,datenume[5]);
  289.          }
  290.    }
  291.   else if(knum==2)
  292.    {
  293.      if(flag1)
  294.          {
  295.       digdisplay(0,datenume[0]);
  296.           digdisplay(1,datenume[1]);
  297.           digdisplay(2,16);
  298.           digdisplay(3,datenume[2]);
  299.           digdisplay(4,datenume[3]);
  300.           digdisplay(5,16);
  301.           digdisplay(6,datenume[4]);
  302.           digdisplay(7,datenume[5]);
  303.          }
  304.          else
  305.          {
  306.           digdisplay(0,datenume[0]);
  307.           digdisplay(1,datenume[1]);
  308.           digdisplay(2,16);
  309.           digdisplay(3,17);
  310.           digdisplay(4,17);
  311.           digdisplay(5,16);
  312.           digdisplay(6,datenume[4]);
  313.           digdisplay(7,datenume[5]);
  314.          }
  315.    }
  316.   else  if(knum==3)
  317.    {
  318.      if(flag1)
  319.          {
  320.       digdisplay(0,datenume[0]);
  321.           digdisplay(1,datenume[1]);
  322.           digdisplay(2,16);
  323.           digdisplay(3,datenume[2]);
  324.           digdisplay(4,datenume[3]);
  325.           digdisplay(5,16);
  326.           digdisplay(6,datenume[4]);
  327.           digdisplay(7,datenume[5]);
  328.          }
  329.          else
  330.          {
  331.           digdisplay(0,datenume[0]);
  332.           digdisplay(1,datenume[1]);
  333.           digdisplay(2,16);
  334.           digdisplay(3,datenume[2]);
  335.           digdisplay(4,datenume[3]);
  336.           digdisplay(5,16);
  337.           digdisplay(6,17);
  338.           digdisplay(7,17);
  339.          }
  340.    }
  341. }
  342. void main()
  343. {
  344.    TMOD &= 0xF0;    //设置定时器模式
  345.    TMOD |= 0x01;    //设置定时器模式
  346.    TL0 = 0xF0;                //设置定时初值                10毫秒定时器
  347.    TH0 = 0xD8;                //设置定时初值
  348.    TF0 = 0;                     //清除TF0标志
  349.    TR0=1;                //定时器开启           定时器在程序运行过程中将一直启动     
  350.    ET0=1;
  351.    EA=1;
  352.    while(1)
  353.    {
  354.       keyprogress();           //按键处理函数分别处理K1,K2,K3,K4的长按和短按程序
  355.           shuma();                           //数码管管显示程序,处理K2按键按下
  356.    }
  357. }
  358. void int0() interrupt 1                                
  359. {
  360.    TL0 = 0xF0;                //设置定时初值
  361.    TH0 = 0xD8;                //设置定时初值
  362.    datenume[0]=miao%10;                        //对秒分时进行数据处理,用数码管显示做铺垫
  363.    datenume[1]=miao/10;
  364.    datenume[2]=fen%10;
  365.    datenume[3]=fen/10;
  366.    datenume[4]=shi%10;
  367.    datenume[5]=shi/10;
  368.    if(flag0&&knum==0)                //进行正向计数,knum判断是否进行了移位操作,flag0判断是否进行了开始操作
  369.   {
  370.    count++;
  371.    if(count==100)
  372.    {
  373.      count=0;
  374.          miao++;
  375.          if(miao==60)
  376.          {
  377.            miao=0;
  378.            fen++;
  379.            if(fen==60)
  380.            {
  381.               fen=0;
  382.                   shi++;
  383.                   if(shi==24)
  384.                   {
  385.                     shi=0;
  386.                         flag2=!flag2;                //开启LED灯的闪烁
  387.                         flag0=!flag0;                //关闭计数器
  388.                   }
  389.            }
  390.          }
  391.    }
  392.   }

  393.   if(flag3&&knum==0)                  //进行倒计时操作
  394.   {
  395.      time_count++;
  396.          if(time_count==100)
  397.          {
  398. ……………………

  399. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
数码管与按键的组合使用.rar (39.3 KB, 下载次数: 26)

评分

参与人数 1黑币 +80 收起 理由
admin + 80 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:673128 发表于 2020-2-12 11:23 | 只看该作者

大哥没有坏啊
回复

使用道具 举报

板凳
ID:135835 发表于 2020-2-12 17:02 | 只看该作者
下了,压缩包没坏,正常解压。
回复

使用道具 举报

地板
ID:328014 发表于 2020-2-15 14:15 | 只看该作者
好东东 很详细啊,,楼主能附个原理图吗?
回复

使用道具 举报

5#
ID:691807 发表于 2020-2-15 14:42 | 只看该作者
谢谢楼主分享
回复

使用道具 举报

6#
ID:24810 发表于 2020-2-15 17:23 | 只看该作者
下来学习下。
回复

使用道具 举报

7#
ID:673128 发表于 2020-2-17 08:47 | 只看该作者
51hei团团 发表于 2020-2-15 14:15
好东东 很详细啊,,楼主能附个原理图吗?

那个我这是用单片机一步步实验出来的,我没有学用仿真软件,思路就是开头的思路。你按照它走一定能做出来的。
回复

使用道具 举报

8#
ID:684248 发表于 2020-2-24 17:22 | 只看该作者
楼主,digdisplay.c的函数能分享下吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表