找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5673|回复: 0
收起左侧

单片机简易时钟(带流水灯,断电保存)

[复制链接]
ID:198493 发表于 2017-6-8 05:09 | 显示全部楼层 |阅读模式
一个简单的四位数码管的时钟,可以调节、暂停、清零时间,断电保存并且在设定的时间内有流水灯亮起。(附有程序和接线图)
如果有哪里做得不好的还请大家多指教。
0.png 0.png 0.png

单片机源程序如下:
  1. /*********************************************************************
  2. 简易时钟: 1. 四位数码管显示(分秒计时)。
  3.            2. 每到30~40秒时有流水灯亮起。
  4.            3. 可断电保存
  5.            4. 按键1——暂停
  6.              按键2——清零
  7.              按键3——加10秒
  8.              按键4——减10秒
  9.              按键5——加10分
  10.              按键6——减10分  
  11. *********************************************************************/
  12. #include<reg51.h>
  13. #include"i2c.h"               
  14. #include <intrins.h>
  15. #define uint unsigned int
  16. #define uchar unsigned char
  17. unsigned char m=0;
  18. uchar z=0;
  19. sbit key1=P1^0;                           //定义各按键对应的IO口
  20. sbit key2=P1^1        ;
  21. sbit key3=P1^2;
  22. sbit key4=P1^3;
  23. sbit key5=P1^4;
  24. sbit key6=P1^5;
  25. typedef unsigned char u8;
  26. typedef unsigned int u16;
  27. u8 i;
  28. uchar display2[]={  0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd };           //用于流水灯
  29. uint counter=0;
  30. u8 smgduan[16]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,
  31.                       0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71,};// 段选
  32. u8 smgduan1[16]={0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,};  //百位的段选

  33. u8 smgwei[8]={0x00,0x04,0x08,0x0c,0x10,0x14,0x18,0x1c}; //位选
  34. u8 a[4];//保存时钟的数据
  35. u8 sec,min;
  36. void delay(u16 i)                           //延迟函数
  37. {
  38. while(i--);
  39. }
  40. /*******************************************************************************
  41. * 函 数 名         : void At24c02Write(unsigned char addr,unsigned char dat)
  42. * 函数功能                   : 往24c02的一个地址写入一个数据
  43. *******************************************************************************/

  44. void At24c02Write(unsigned char addr,unsigned char dat)        //把dat的值存放到addr地址上
  45. {
  46.         I2C_Start();
  47.         I2C_SendByte(0xa0, 1);//发送写器件地址
  48.         I2C_SendByte(addr, 1);//发送要写入内存地址
  49.         I2C_SendByte(dat, 0);        //发送数据
  50.         I2C_Stop();
  51.        
  52. }
  53. /*******************************************************************************
  54. * 函 数 名         : unsigned char At24c02Read(unsigned char addr)
  55. * 函数功能                   : 读取24c02的一个地址的一个数据
  56. *******************************************************************************/

  57. unsigned char At24c02Read(unsigned char addr)
  58. {
  59.         unsigned char sec;
  60.         I2C_Start();
  61.         I2C_SendByte(0xa0, 1); //发送写器件地址
  62.         I2C_SendByte(addr, 1); //发送要读取的地址
  63.         I2C_Start();
  64.         I2C_SendByte(0xa1, 1); //发送读器件地址
  65.         sec=I2C_ReadByte(); //读取数据
  66.         I2C_Stop();
  67.         return sec;       
  68. }

  69. /***********************************
  70.            显示函数
  71. ************************************/
  72. void display()                       
  73. {
  74. a[0]=smgduan[sec%10];
  75. a[1]=smgduan[sec/10];

  76. a[2]=smgduan1[min%10];
  77. a[3]=smgduan[min/10];
  78. for(i=0;i<4;i++)       
  79. {
  80. P0=a[i];
  81. P2=smgwei[4-i];
  82. delay(300);          //不同的延时时间对数码管显示亮度会产生很大的影响,时间越短影响越大
  83. }
  84. }

  85. initial()                                         //定时器0初始化
  86. { TMOD=0x01;        //选择定时器工作模式
  87. TH0=55536/256;                                   //设置定时初值
  88.   TL0=55536%256;
  89.    EA=1;
  90.     ET0=1;                                                 
  91.          TR0=1; }

  92. void time1init()
  93. {                                                                        //定时器1初始化
  94. TMOD=0x01;
  95. TL1 = 0xCB;               
  96.         TH1 = 0xF3;       
  97. EA=1;             //总中断
  98. ET1=1;             //中断允许开关
  99. TR1=1;             //定时器开关
  100. }

  101. /***********************
  102.     按键扫描函数
  103. ************************/
  104. void keyscan()                          
  105. {
  106. delay(200);
  107. if(key2==0)                         //清零
  108. {
  109. delay(200);
  110. min=0;
  111. sec=0;
  112. while (!key2);}
  113. if(key1==0)                           //暂停
  114. {
  115. delay(200);
  116. while (!key1);
  117. TR1=~TR1;                                 //停止或启动定时器1
  118. }
  119. if(key3==0)        //增加10s,若此时秒大于50则在增加后进min进一,sec照量改变
  120. {
  121. delay(200);
  122. if(sec<=49)
  123. sec +=10;
  124. else                                               
  125. {min+=1;
  126. sec-=50;}
  127. while(!key3);
  128. }
  129.   if(key5==0)                                //增加10m
  130.   {
  131.   delay(200);
  132.   min+=10;
  133.   while(!key5);}
  134.   if(min>=60)                                 //min满60后全部归零
  135.   {delay(200);
  136.   min=0;
  137.   sec=0;
  138.   while(!key5);}
  139.   delay(200);
  140.   if(key6==0)                //减少10m,若此时时间少于10m,则时间归零                        
  141.   {
  142.   delay(200);
  143.   if(min>=10)
  144.   {
  145.   min-=10;
  146.   while(!key6);}
  147.   else
  148.   {delay(200);
  149.   min=0        ;                                     
  150.   sec=0;
  151.   while(!key6);}
  152.   }         
  153. if(key4==0)                  //减少10秒
  154. {
  155. delay(200);
  156. if(sec>=10)
  157. {delay(200);
  158. sec-=10;
  159. while(!key4);
  160.   }
  161.   else if(min>=1&&sec<=10)
  162.   {delay(200);
  163.   min-=1;
  164.   sec+=50;
  165.   while(!key4);
  166.   }
  167.   else if(min==0&&sec<=10) //时间少于10s的在按下key4后归零
  168.   {delay(200);
  169.   min=0;
  170.   sec=0;
  171.   while(!key4);
  172.   }
  173.   }
  174.   }
  175. /**********************
  176.      主函数
  177. ***********************/               
  178. void main()
  179. {
  180.    if(m==0)                                 //断电后读数
  181.   { sec=At24c02Read(1);
  182.   min=At24c02Read(2);
  183.           }
  184.           time1init();                                          //调用各种子函数
  185.            while(1)
  186. {  At24c02Write(1,sec);       
  187. keyscan();
  188. display();
  189. initial();
  190. }
  191. }       

  192.    
  193. void T0_int () interrupt 1                           //定时器0控制流水灯
  194. { TR0=0;
  195. ET0=0;
  196. TH0=55536/256;                 //设置初值
  197. TL0=55536%256;
  198. if(sec>=30&&sec<=40)                                 //在30s~40s时流水灯亮起
  199. {
  200. if(z<14)
  201. { counter++;
  202. if(counter==30)                                                  //定时控制LED灯的改变
  203. {  z++;  
  204. counter=0;
  205. }  
  206. P3=display2[z]; }
  207.   if(z==14)
  208.   {  P3=0xff;
  209.    z=0; }
  210. ……………………

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

所有资料51hei提供下载:
时钟.zip (526.98 KB, 下载次数: 28)

评分

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

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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