找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机+数字电子时钟Proteus仿真程序设计

[复制链接]
跳转到指定楼层
楼主
本文件是单片机技术时钟震荡的仿真图,是我设计所作的,需要的可以来自取
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. #include<reg52.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. #define play P0 //数据输出口
  5. sbit LSA=P1^0;
  6. sbit LSB=P1^1;
  7. sbit LSC=P1^2;
  8. sbit led=P2^2; //闹钟检测
  9. sbit k1=P2^7;//        功能切换
  10. sbit k2=P2^6;//设置加
  11. sbit k3=P2^5;//         设置减  
  12. sbit k4=P2^4; //设置位选
  13. sbit beet=P1^5; //蜂鸣器输出口
  14. uchar y;//按键松开
  15. uchar kai;//闹钟开启标志
  16. uchar she;// 位选标志  取值范围0 1 2 3
  17. uchar t;//时间计数
  18. uchar num;//功能切换  取值范围 0 1 2 。0时钟设置,1日期设置,2闹钟设置
  19. uchar fen;
  20. uchar shi;
  21. uchar miao;
  22. uchar yue;
  23. uchar nian;
  24. uchar ri;
  25. uchar shijian[8];//用来临时存放数据的数组 ,存放的是要显示的内容
  26. uchar  shi1; //闹铃时
  27. uchar fen1;         //闹铃分
  28. unsigned char code shuma[16]={
  29. 0x3f,0x06,0x5b,0x4f,
  30. 0x66,0x6d,0x7d,0x07,                  //数码管显示数组0到9, - ,和学号
  31. 0x7f,0x6f,0x40,0x00,                  //8 9 10 11
  32. 0x40,0x40,0x40  };
  33. uchar brunyue[12]={31,28,31,30,31,30,31,31,30,31,30,31};
  34. uchar runyue[12]={31,29,31,30,31,30,31,31,30,31,30,31};
  35. void zhongshe();
  36. void qishe();
  37. void naoshe();
  38. void shezhi();
  39. void delay10ms(void)   //误差 0us
  40. {
  41.     unsigned char a,b,c;
  42.     for(c=1;c>0;c--)
  43.         for(b=38;b>0;b--)
  44.             for(a=130;a>0;a--);
  45. }
  46. void delay(unsigned int a)   //
  47. {
  48.     unsigned int b,c;
  49.     for(c=a;c>0;c--)
  50.         for(b=500;b>0;b--);
  51.            
  52. }
  53. void naozhong()
  54. {   uint a,m;  
  55.         if((shi1==shi)&&(fen1==fen)&&(kai%2))
  56.           {                 for(m=20;m>0;m--)
  57.                for(a=10;a>0;a--)
  58.                    if((k1==0)||(k2==0)||(k3==0)||(k4==0))//按任意键 停止闹铃
  59.                   { kai=0;break;  }        
  60.                     else
  61.                      beet=~beet;         
  62.            }
  63. }
  64. void plays()                          //输出显示数组中的值***********************************************************************************
  65. {
  66.         unsigned char i;
  67.         unsigned int j;
  68.         for(i=0;i<8;i++)
  69.         {
  70.                 switch(i)         //位选,选择点亮的数码管,
  71.                 {
  72.                         case(0):
  73.                                 LSA=0;LSB=0;LSC=0; break;//选中第0位
  74.                         case(1):
  75.                                 LSA=1;LSB=0;LSC=0; break;//选中第1位
  76.                         case(2):
  77.                                 LSA=0;LSB=1;LSC=0; break;//选中第2位
  78.                         case(3):
  79.                                 LSA=1;LSB=1;LSC=0; break;//选中第3位
  80.                         case(4):
  81.                                 LSA=0;LSB=0;LSC=1; break;//选中第4位
  82.                         case(5):
  83.                                 LSA=1;LSB=0;LSC=1; break;//选中第5位
  84.                         case(6):
  85.                                 LSA=0;LSB=1;LSC=1; break;//选中第6位
  86.                         case(7):
  87.                                 LSA=1;LSB=1;LSC=1; break;//选中第7位        
  88.                 }
  89.                  play=shuma[shijian[i]]; //显示数组中选中的元素代表的值
  90.                  if(t>50)
  91.              {                 switch(she)
  92.                      {  
  93.                        case(3):
  94.                           if((i==0)||(i==1))
  95.                           play=0x00; break;
  96.                        case(2):
  97.                           if((i==3)||(i==4))
  98.                           play=0x00; break;
  99.                        case(1):
  100.                           if((i==6)||(i==7))
  101.                           play=0x00; break;
  102.                      }
  103.          }
  104.                  j=10;                                                 //扫描间隔时间设定
  105.                 while(j--);        
  106.                 play=0x00;//消隐
  107.         }
  108. }
  109. void nao()                                //把闹钟赋值给数组
  110. {  shijian[7]=kai; //闹钟开启标志
  111.    shijian[6]=11;
  112.    shijian[5]=11;
  113.    shijian[4]=fen1%10;
  114.    shijian[3]=fen1/10;
  115.    shijian[2]=10;
  116.    shijian[1]=shi1%10;
  117.    shijian[0]=shi1/10;

  118. }
  119. void rili()                                 //日期赋值给数组
  120. {  shijian[7]=ri%10;
  121.    shijian[6]=ri/10;
  122.    shijian[5]=10;
  123.    shijian[4]=yue%10;
  124.    shijian[3]=yue/10;
  125.    shijian[2]=10;
  126.    shijian[1]=nian%10;
  127.    shijian[0]=nian/10;
  128. }
  129. void zhong()                                //电子钟赋值给数组
  130. { shijian[7]=miao%10;
  131.           shijian[6]=miao/10;
  132.           shijian[5]=10;
  133.           shijian[4]=fen%10;
  134.           shijian[3]=fen/10;
  135.           shijian[2]=10;
  136.           shijian[1]=shi%10;
  137.           shijian[0]=shi/10;
  138. }
  139. void xuehao()                                //学号赋值给数组************************************************************************
  140. {     shijian[0]=10;
  141.           shijian[1]=2;
  142.           shijian[2]=3;
  143.           shijian[3]=12;
  144.           shijian[4]=13;
  145.           shijian[5]=14;
  146.           shijian[6]=2;
  147.           shijian[7]=8;
  148. }
  149. void chushizhuangtai()//初始状态设置 上电复位后 依次显示学号 和制造日期************************************************************************************************
  150.     {
  151.               uint csj;
  152.               for(csj=500;csj>1;csj--)
  153.                   { xuehao();
  154.                plays();
  155.                    delay(1);
  156.                plays();//显示学号
  157.                   }
  158.                   for(csj=300;csj>1;csj--)
  159.                   { rili();
  160.                plays();
  161.                delay(1);//显示日期
  162.                     plays();
  163.                   }
  164.         }
  165. void InitTimer0(void)//开定时器0中断 设定10ms**************************************************************************
  166. {
  167.      TMOD = 0x01;
  168.     TH0 = 0x0D8;
  169.     TL0 = 0x0F0;
  170.     EA = 1;
  171.     ET0 = 1;
  172.     TR0 = 1;
  173. }        //*****************************************************************************************************************
  174. void shezhi()//在有位选信号(也就是she不等于零)的条件下,判断k2,k3是否有键按下,并根据当前所处的模式切换到对应的处理函数
  175. {  if((she!=0)&&((k2==0)||(k3==0))) //
  176.    {  delay10ms();
  177.    if((she!=0)&&((k2==0)||(k3==0))) //如果 有加减键按下 且标志位 she 在不在 0 状态
  178.          {
  179.            switch(num)
  180.                  { case(0):   
  181.                                     zhongshe(); break;
  182.                    case(1):
  183.                           qishe(); break;
  184.                    case(2):
  185.                                      naoshe();break;
  186.                  }
  187.          }
  188.    }
  189. }
  190. //*******************************************************************************************
  191. void main()
  192. {
  193.    
  194.     num=0;kai=1;she=0;        
  195.         fen1=1;shi1=12;
  196.         miao=0;fen=0;        shi=12;
  197.     ri=21;        yue=6;        nian=16;
  198.         chushizhuangtai();         
  199.     InitTimer0();
  200.         while(1)
  201.         {  
  202.         if(k1==0)
  203.            {delay10ms();
  204.                     if(k1==0)
  205.                          {num=(num+4)%3;
  206.                           she=0;}
  207.                          led=~led;
  208.                          while(!k1) ;}
  209.          if(k4==0)
  210.            {delay10ms();
  211.                     if(k4==0)
  212.                   she=(she+5)%4;
  213.                   while(!k4) ;
  214.            }
  215.      shezhi();
  216.          naozhong();
  217.                  plays();         
  218.          
  219.         }
  220. }
  221. //**********************************************************************************************************************
  222. void Timer0Interrupt(void) interrupt 1                //作用。 1,每秒加一计数。2,处理模式转换标志 实现模式切换
  223. {
  224.     TH0 = 0x0D8;
  225.     TL0 = 0x0F0;     //初值 55536 一次中段时间 10ms
  226.           t++;
  227.           if(t==100)
  228.                 { t=0;
  229.                   miao++;        
  230.                   if(miao>59)
  231.                   { miao=0;
  232.                           fen++;
  233.                           if(fen>59)
  234.                           {
  235.                             fen=0;
  236.                             shi++;        
  237.                               if(shi>23)
  238.                                    {
  239.                                     shi=0;
  240.                                         ri++;
  241.                                                 if(nian%4==0)
  242.                                                 { if(ri>runyue[yue-1])
  243.                                                         {   ri=1;
  244.                                    yue++;  }
  245.                                                         if(yue>12)
  246.                                                           {  yue=1;
  247.                                                                 nian++;        }        
  248.                                                  }
  249.                                                  else
  250.                                                  {if(ri>brunyue[yue-1])
  251.                                                       {
  252.                                                                ri=0;
  253.                                                                      yue++;  
  254.                                                          }
  255.                                                                   if(yue>12)
  256.                                                                   {
  257.                                                                    yue=0;
  258.                                                                    nian++ ;
  259.                                                                    }

  260.                                                    }
  261.                              }
  262.                         }
  263.                       }
  264.                 }
  265.         switch(num)
  266.         {  
  267.            case(0):
  268.                    zhong();break; // 把时钟的值装入数组。
  269.            case(1):
  270.                    rili();break;// 把日期的值装入数组。
  271.            case(2):
  272.                    nao();break;        // 把闹钟的值装入数组。
  273.            default:
  274.                    zhong();//
  275.         }
  276. }
  277. //***********************************************************************************************************************
  278. void zhongshe()//处于时钟状态下,当有加减信号时的处理
  279. {         
  280.    switch(she)
  281.      {        
  282.        case(1):
  283.                 miao=0;InitTimer0();break;        
  284.        case(2): // 位选信号为分
  285.                if(k2==0)
  286.                             fen=(fen+61)%60;//如果加信号,则分加一。否则减一
  287.                    else   
  288.                     fen=(fen+59)%60;
  289.                    break;
  290.        case(3):        //位选信号为时
  291.                    if(k2==0)
  292.                                shi=(shi+25)%24;
  293.                    else
  294.                               shi=(shi+23)%24;
  295.                               break;
  296.      }        
  297.   while((!k2)||(!k3)) ;        //松手检测                 
  298. }
  299. void naoshe() //同上
  300. {                 
  301.        switch(she)
  302.          {        
  303.            case(1):
  304.                    if(kai==1)
  305.                           kai=0;
  306.                        else kai=1; break;//闹钟的开关        
  307.            case(2):
  308.                    if(k2==0)
  309.                                   fen1=(fen1+61)%60;
  310.                        else   
  311.                           fen1=(fen1+59)%60;
  312.                        break;
  313.            case(3):
  314.                        if(k2==0)
  315.                                      shi1=(shi1+25)%24;
  316.                        else
  317.                                     shi1=(shi1+23)%24;
  318.                                   break;
  319.           }
  320.        while((!k2)||(!k3)) ;
  321. }
  322. void qishe()  //同上
  323. {         
  324.      switch(she)
  325.         {        
  326.            case(1):
  327.                    if(k2==0)
  328.                      {
  329.                                            if(nian%4==0)
  330.                                   ri=(ri+runyue[yue-1]+2)%(runyue[yue-1]+1) ;        
  331.                                else
  332.                                       ri=(ri+brunyue[yue-1]+2)%(brunyue[yue-1]+1);
  333.                      }               
  334.                                    
  335.                        else   
  336.                      {         
  337.                                            if(nian%4==0)
  338.                                    ri=(ri+runyue[yue-1])%(runyue[yue-1]+1) ;        
  339.                        else
  340.                                   ri=(ri+brunyue[yue-1])%(brunyue[yue-1]+1);
  341.                      }                                 
  342.                           break;
  343.             case(2):
  344.                        if(k2==0)
  345.                            yue=(yue+14)%13;
  346.                        else
  347.                            yue=(yue+12)%13;
  348.                        break;
  349.              case(3):
  350.                         if(k2==0)
  351.                            nian++;
  352.                        else
  353.                            nian--;
  354.           }        
  355.       while((!k2)||(!k3)) ;
  356. }                        
复制代码

所有资料51hei提供下载:
数字电路设计.rar (720.29 KB, 下载次数: 77)

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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