找回密码
 立即注册

QQ登录

只需一步,快速开始

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

带详细注释的单片机闹钟程序

[复制链接]
跳转到指定楼层
楼主
ID:102668 发表于 2016-1-16 05:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. #include<reg52.h> //头文件
  2. #include<intrins.h>
  3. #define uchar unsigned char//宏定义
  4. #define uint  unsigned int
  5. sbit key1=P1^0;   //位声明
  6. sbit key2=P1^1;
  7. sbit key3=P1^2;
  8. sbit fmq=P3^3;//闹钟
  9. uchar code table[]={0xc0,0xf9,0xa4,//数码管显示的数值
  10. 0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,
  11. 0x40,0x79,0x24,//带小数点的数值
  12. 0x30,0x19,0x12,0x02,0x78,0x00,0x10};
  13. void jia();   //函数声明
  14. void jian();
  15. uchar table_1[6]; //定义数组,数组内含有6个数值
  16. uchar table_2[6];
  17. uchar shi=23,fen=59,miao=50; //显示初始值
  18. uchar shi1,fen1,miao1,shi2,fen2,miao2,shi3,fen3,miao3;//定义全局变量
  19. uchar flag,flag1,cnt,count;//定义全局变量
  20. void delay(uchar i)  //延时函数,用于动态扫描数码管
  21. {
  22.      uchar x,y;
  23.      for(x=i;x>0;x--)
  24.           for(y=110;y>0;y--);
  25. }
  26. void init()   //初始化函数
  27. {
  28.      TMOD=0X01; //工作方式1
  29.      TH0=(65536-50000)/256; //定时时间为:50ms
  30.      TL0=(65536-50000)%256;
  31.      ET0=1;     //打开定时器
  32.      EA=1;    //开总中断
  33.      TR0=1;    //启动定时器
  34. }
  35. void display()  //显示子函数,用于显示时间数值
  36. {
  37.      uchar i,j;
  38.      table_1[0]=miao%10;  //分离秒的各位与十位
  39.      table_1[1]=miao/10;
  40.      table_1[2]=fen%10+11;  //分离分的各位与十位
  41.      table_1[3]=fen/10;
  42.      table_1[4]=shi%10+11; //分离时的各位与十位
  43.      table_1[5]=shi/10;
  44.      j=0x7f;    //从秒到时的扫描(位选)
  45.      for(i=0;i<6;i++)
  46.      {
  47.       P2=j;
  48.       P0=table[table_1[i]];//显示数值
  49.       delay(10);
  50.       j=_cror_(j,1);//循环右移
  51.      }
  52. }
  53. void display_1() //显示子函数,用于显示定时时间
  54. {
  55.      uchar i,j;
  56.      table_2[0]=miao2%10;  //以下含义同上
  57.      table_2[1]=miao2/10;
  58.      table_2[2]=fen2%10+11;
  59.      table_2[3]=fen2/10;
  60.      table_2[4]=shi2%10+11;
  61.      table_2[5]=shi2/10;
  62.      j=0x7f;
  63.      for(i=0;i<6;i++)
  64.      {
  65.           P2=j;
  66.           P0=table[table_2[i]];
  67.           delay(10);
  68.           j=_cror_(j,1);
  69.      }
  70. }
  71. void shijian() //时间子函数
  72. {
  73.      if(flag>=20)  //判断是否到一秒
  74.      {
  75.           flag=0;  //到了,则标志位清零
  76.           miao++;  //秒加1
  77.           if(miao>=60) //判断秒是否到60s
  78.           {
  79.                miao=0;//到了,则清零
  80.                fen++; //分加1
  81.                if(fen>=59) //以下含义同上
  82.                {
  83.                     fen=0;
  84.                     shi++;
  85.                     if(shi>23)
  86.                          shi=0;
  87.                }
  88.           }
  89.      }
  90. }
  91. void key_scan() //键盘扫描子函数
  92. {
  93.      uchar i;   //定义局部变量
  94.      if(key1==0)
  95.      {
  96.           while(!key1)  //防止掉显
  97.           {
  98.                if(cnt==0||cnt==1||cnt==2||cnt==3||cnt==4||cnt==8)
  99.                {
  100.                     display();
  101.                }
  102.                if(cnt==5||cnt==6||cnt==7)
  103.                {
  104.                     display_1();
  105.                }
  106.           }
  107.           cnt++; //记下按键key1按下的次数
  108.           if(cnt==1) //第一次按下,停止计数
  109.           TR0=0;
  110.           if(cnt==2)   //第二次按下
  111.           {
  112.                miao1=miao; //保存秒的数值
  113.                miao=99;//显示99,表示可以调节秒的数值了
  114.                for(i=0;i<100;i++)
  115.                 display(); //显示99
  116.                miao=miao1; //恢复前一刻秒的数值
  117.           }
  118.           if(cnt==3) //以下含义同上
  119.           {
  120.                fen1=fen;
  121.                fen=99;
  122.                for(i=0;i<100;i++)
  123.                     display();
  124.                fen=fen1;
  125.           }
  126.           if(cnt==4)
  127.           {
  128.                shi1=shi;
  129.                shi=99;
  130.                for(i=0;i<100;i++)
  131.                     display();
  132.                shi=shi1;
  133.           }
  134.           if(cnt==5)
  135.           {
  136.                miao1=miao2;
  137.                miao2=88;
  138.                for(i=0;i<100;i++)
  139.                     display_1();
  140.                miao2=miao1;
  141.           }
  142.           if(cnt==6)
  143.           {
  144.                fen1=fen2;
  145.                fen2=88;
  146.                for(i=0;i<100;i++)
  147.                     display_1();
  148.                fen2=fen1;
  149.           }
  150.           if(cnt==7)
  151.           {
  152.                shi1=shi2;
  153.                shi2=88;
  154.                for(i=0;i<100;i++)
  155.                     display_1();
  156.                shi2=shi1;
  157.           }
  158.           if(cnt==8) //第八次按下
  159.           {
  160.                TR0=1;  //开始计数
  161.                cnt=0; //按下次数清零
  162.           }
  163.      }
  164.      if(key2==0)   //判断key2是否按下
  165.      {
  166.           while(!key2)  //防止掉显
  167.           {
  168.                if(cnt==0||cnt==1||cnt==2||cnt==3||cnt==4||cnt==8)
  169.                {
  170.                     display();
  171.                }
  172.                if(cnt==5||cnt==6||cnt==7)
  173.                {
  174.                     display_1();
  175.                }
  176.           }
  177.           jia();//调用加1的子函数
  178.      }
  179.      if(key3==0)  //判断key3是否按下
  180.      {
  181.           while(!key3)  //防止掉显
  182.           {
  183.                if(cnt==0||cnt==1||cnt==2||cnt==3||cnt==4||cnt==8)
  184.                {
  185.                     display();
  186.                }
  187.                if(cnt==5||cnt==6||cnt==7)
  188.                {
  189.                     display_1();
  190.                }
  191.           }
  192.           jian(); //调用减1子函数
  193.      }
  194. }
  195. void jia()   //加1子函数
  196. {
  197.      if(cnt==2) //判断key1按下的次数是否为2
  198.      {
  199.           miao++; //是,则秒加1
  200.           if(miao>59) //判断秒是否大于59,是,则秒清零
  201.                miao=0;
  202.      }
  203.      if(cnt==3) //以下含义同上
  204.      {
  205.           fen++;
  206.           if(fen>59)
  207.                fen=0;
  208.      }
  209.      if(cnt==4)
  210.      {
  211.           shi++;
  212.           if(shi>23)
  213.                shi=0;
  214.      }
  215.      if(cnt==5)
  216.      {
  217.           miao2++;
  218.           if(miao2>59)
  219.                miao2=0;
  220.      }
  221.      if(cnt==6)
  222.      {
  223.           fen2++;
  224.           if(fen2>59)
  225.                fen2=0;
  226.      }
  227.      if(cnt==7)
  228.      {
  229.           shi2++;
  230.           if(shi2>23)
  231.                shi2=0;
  232.      }
  233. }
  234. void jian()    //减1子函数
  235. {
  236.      if(cnt==2) //判断key1按下的次数是否为2,是则秒减1
  237.      {
  238.           miao--;
  239.           if(miao==255)  //判断秒是否减到255,是,则秒清零
  240.                miao=59;
  241.      }
  242.      if(cnt==3)
  243.      {
  244.           fen--;
  245.           if(fen==255)
  246.                fen=59;
  247.      }
  248.      if(cnt==4)
  249.      {
  250.           shi--;
  251.           if(shi==255)
  252.                shi=23;
  253.      }
  254.      if(cnt==5)
  255.      {
  256.           miao2--;
  257.           if(miao2==255)
  258.                miao2=59;
  259.      }
  260.      if(cnt==6)
  261.      {
  262.           fen2--;
  263.           if(fen2==255)
  264.                fen2=59;
  265.      }
  266.      if(cnt==7)
  267.      {
  268.           shi2--;
  269.           if(shi2==255)
  270.                shi2=23;
  271.      }
  272. }
  273. void clock() //闹铃子函数
  274. {
  275.      if(miao2==miao) //显判断秒的数值是否相等
  276.           if(fen2==fen)  //是,在判断分是否相等
  277.                if(shi2==shi) //是,再判断时是否相等
  278.                {
  279.                     flag1=0; //是,则标志位,flag1清零
  280.                     while(!(flag1==100))  //判断flag1是否到100
  281.                     {
  282.                          fmq=0;  //没有,则,继续驱动蜂鸣器响,时间约为:5s
  283.                          shijian(); //调用时间子函数
  284.                          display(); //调用显示子函数  
  285.                     }
  286.                     fmq=1;//关闭蜂鸣器
  287.                }
  288. }
  289. void main()
  290. {
  291.      init();//调用初始化子函数
  292.      while(1)
  293.      {
  294.           key_scan(); //调用键盘扫描子函数
  295.           shijian(); //时间子函数
  296.           clock(); //闹钟子函数
  297.           //显示子函数
  298.           if(cnt==0||cnt==1||cnt==2||cnt==3||cnt==4||cnt==8)
  299.           {
  300.                display();
  301.           }
  302.           if(cnt==5||cnt==6||cnt==7)
  303.           {
  304.                display_1();
  305.           }
  306.      }
  307. }
  308. void time0() interrupt 1 //定时器0
  309. {
  310.      TH0=(65536-50000)/256; //初值50ms
  311.      TL0=(65536-50000)%256;
  312.      flag++;   //标志位
  313.      flag1++;
  314. }
复制代码


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

使用道具 举报

沙发
ID:99525 发表于 2016-1-21 10:51 | 只看该作者
这个注释比较详细了
回复

使用道具 举报

板凳
ID:47652 发表于 2016-4-21 10:24 | 只看该作者
有清晰的注解太好了
回复

使用道具 举报

地板
ID:312846 发表于 2018-5-6 22:58 | 只看该作者
你这个是无源的蜂鸣器吗
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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