找回密码
 立即注册

QQ登录

只需一步,快速开始

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

充电宝时钟DIY 附单片机源程序

  [复制链接]
跳转到指定楼层
楼主
手里有几个买东西送的充电宝,电池都老化了,于是就用充电宝的外壳做了个电子钟。使用15单片机加DS1302,用单片机推挽直接驱动数码管。只用了不几个元件。

制作出来的实物图如下:


单片机源程序如下:
  1. ///***使用15W408AS单片机,使用IO口直接驱动共阳数码管显示



  2. #include <STC15F2K.h>
  3. #include <DS1302.h>
  4. #define uchar unsigned char
  5. /********************************************************/
  6. unsigned char code shumg[]={
  7.         0x3F,/*0*/
  8.         0x06,/*1*/
  9.         0x5B,/*2*/
  10.         0x4F,/*3*/
  11.         0x66,/*4*/
  12.         0x6D,/*5*/
  13.         0x7D,/*6*/
  14.         0x07,/*7*/
  15.         0x7F,/*8*/
  16.         0x6F,/*9*/



  17. 0x00};
  18. /********************************************************/                                            

  19. sbit LED1=P1^5;        //时间指示灯
  20. sbit LED2=P1^6;        //年月指示灯
  21. sbit LED3=P1^7; //日周指示灯
  22. sbit LED4=P1^0;        //冒号闪烁

  23. sbit S1=P3^0;   //定义按键
  24. sbit S2=P3^1;
  25. sbit S3=P3^2;     //切换
  26. sbit S4=P3^3;

  27. sbit DIG1=P3^7; //数码管位选
  28. sbit DIG2=P3^6;
  29. sbit DIG3=P3^5;
  30. sbit DIG4=P3^4;

  31. char miao_num;                                   //冒号标志
  32. /********************************************************/
  33. unsigned char Time[]={0,0,0,0};//用来储存,时间
  34. unsigned char Dime[]={0,0,0,0};//用来储存,年月
  35. unsigned char Bime[]={0,0,0,0};//用来储存,日期
  36. unsigned char flag;                       //键盘入口
  37. /********************************************************/
  38. SYSTEMTIME  time1;   
  39. /********************************************************/
  40. void keyscan();                       //按键扫描程序
  41. void mao_hao();                                         //冒号声明
  42. /********************************************************/
  43. void delay(unsigned char i)

  44.      //延时子程序  
  45. {
  46.   unsigned char j;
  47.   while((i--)!=0)
  48.   {
  49.     for(j=123;j>0;j--);
  50.   }
  51. }
  52. /********************************************************/
  53. void t0_init()                        //定时50ms一个中断
  54. {
  55.   TMOD=0x11;                                                  //总中断初始化
  56.   TH0=0x3c;                                          //定时50ms一个中断
  57.   TL0=0xb0;                                          //定时50ms一个中断
  58.   EA=1;                                                                  //开启总中断
  59.   ET0=1;                                                       
  60.   TR0=1;                                                          //开启定时器0
  61. }
  62. /********************************************************/
  63. unsigned char button_time(n,x,y)        //时钟调整子程序
  64. unsigned char n,x,y;
  65. {
  66. if(S1==0)                                                        //加
  67.   {
  68.   delay(50);
  69. if(S1==0)
  70. {
  71. n++;
  72. if(n==x)
  73.   n=0;
  74. while(S1==0);
  75.    }
  76. }
  77. /********************************************************/
  78. if(S2==0)                                                //减
  79.     {
  80.    delay(50);
  81. if(S2==0)
  82.     {
  83. if(n==0)
  84.    n=y;
  85. else
  86.     n--;                                               
  87.   while(S2==0);
  88.     }
  89. }
  90. return n;                                                   //函数返回
  91. }
  92. /********************************************************/



  93. void display(shi10,shi1,fen10,fen1)//显示子程序
  94. {         P2M1 = 0x00; P2M0 = 0xFF; //设置P3.4-7推挽模式,就不用数码管驱动了
  95.          P1M1 = 0x00; P1M0 = 0x01; //P1(00000000B,00000001B)

  96.   DIG1=0;
  97. P2=shumg[shi10];   //显示时的十位
  98.   delay(1);                        //延时
  99. P2=0x00;                        //消隐
  100.   DIG1=1;                         //消隐

  101.   DIG2=0;
  102. P2=shumg[shi1];        //显示时的个位
  103.   delay(1);                        //延时
  104.   DIG2=1;                        //消隐
  105. P2=0x00;                        //消隐                                                         
  106.   
  107.   DIG3=0;
  108. P2=shumg[fen10];  //显示分的十位
  109.   delay(1);                        //延时
  110.   DIG3=1;                        //消隐
  111. P2=0x00;                        //消隐
  112.   
  113.   DIG4=0;
  114. P2=shumg[fen1];        //显示分的个位
  115.   delay(1);                        //延时
  116.   DIG4=1;                        //消隐
  117. P2=0x00;                    //消隐
  118. }
  119. /********************************************************/
  120. void main()                                                        //主程序
  121. {  
  122.    Initial_DS1302();                                 //初始化DS1302这个时钟芯片,   
  123.    t0_init();                                                 //中断初始化
  124.    while(1)                                                         //大循环   
  125.    {                                                                 
  126.    mao_hao();                                                 //冒号初始化
  127.           keyscan();                                         //键盘初始化

  128.   DS1302_GetTime(&time1);                       //读取时间参数            
  129.   
  130.   Bime[3]=(time1.Week)%10;                   //把时的个位数据存入Bime[3]
  131.   Bime[2]=(time1.Week)/10;                         //把时的个位数据存入Bime[2]
  132.   Bime[1]=(time1.Day)%10;                       //把时的个位数据存入Bime[1]
  133.   Bime[0]=(time1.Day)/10;                     //把时的个位数据存入Bime[0]
  134.   
  135.   Dime[3]=(time1.Month)%10;                   //把时的个位数据存入Dime[3]
  136.   Dime[2]=(time1.Month)/10;                         //把时的个位数据存入Dime[2]
  137.   Dime[1]=(time1.Year)%10;                   //把时的个位数据存入Dime[1]
  138.   Dime[0]=(time1.Year)/10;                         //把时的个位数据存入Dime[0]
  139.   
  140.   Time[3]=(time1.Minute)%10;                 //把分的个位数据存入Time[3]
  141.   Time[2]=(time1.Minute)/10;                 //把分的十位数据存入Time[2]
  142.   Time[1]=(time1.Hour)%10;                   //把时的个位数据存入Time[1]
  143.   Time[0]=(time1.Hour)/10;                         //把时的十位数据存入Time[0]
  144. }
  145. }
  146. /*******************************************************/
  147. void keyscan()                                //按键扫描程序
  148. {
  149.     if(S3==0)                                    //切换程序
  150.         {
  151.          delay(50);
  152.         if(S3==0)
  153.            {
  154.            TR0=0;                                                        //有按键按下关闭定时器0
  155.                 miao_num=0;                                         //冒号常亮
  156.                  flag++;
  157.                 if(flag>2)                                                //翻页年月日周按两次后启动定时器
  158.                         {
  159.                  flag=0;
  160.                    TR0=1;                                                //启动定时器0
  161.                         }
  162.                 }
  163.         while(S3==0);
  164.         }
  165. /*******************************************************/
  166.         if(S4==0)                                    //设置程序
  167.         {
  168.          delay(50);
  169.         if(S4==0)
  170.            {
  171.           TR0=0;                                                        //有按键按下关闭定时器0
  172.            miao_num=0;                                                //冒号常亮
  173.                 flag++;                                                       
  174.             if(flag>2)                                                //按两次后启动定时器
  175.            {
  176.            TR0=1;                                                        //启动定时器0
  177.                 }
  178.           if(flag>4)                                                //按四次后关闭定时器
  179.            {
  180.            TR0=0;                                                        //关闭定时器0
  181.                 miao_num=0;                                                //冒号常亮
  182.                 }
  183.         if(flag>8)                                                        //显示多少位和翻页按八次启动定时器
  184.                         {
  185.                  flag=0;
  186.                   TR0=1;                                                //启动定时器0
  187.                         }
  188.                 }
  189.         while(S4==0);
  190.         }
  191. switch(flag)
  192.         {
  193. /*******************************************************/
  194.                        
  195.         case 0:display(Time[0],Time[1],Time[2],Time[3]);                //调用子函数display,把存入数组time的数据给显示出来
  196.                         LED1=0;
  197.                         LED3=1;
  198.                         break;
  199.         case 1:display(Dime[0],Dime[1],Dime[2],Dime[3]);                //调用子函数display,把存入数组Dime的数据给显示出来
  200.                         LED1=1;
  201.                         LED2=0;
  202.                         break;
  203.         case 2:display(Bime[0],Bime[1],Bime[2],Bime[3]);                //调用子函数display,把存入数组Bime的数据给显示出来
  204.                         LED2=1;
  205.                         LED3=0;
  206.                         break;
  207. /*******************************************************/       
  208.         case 3:time1.Hour=button_time(time1.Hour,24,23);                //调整时                          
  209.                         DS1302_SetTime(0x84,time1.Hour);
  210.                         display(Time[0],Time[1],10,10);
  211.                         LED1=0;
  212.                         LED3=1;
  213.                         break;

  214.     case 4:time1.Minute=button_time(time1.Minute,60,59);        //调整分                            
  215.                         DS1302_SetTime(0x82,time1.Minute);
  216.                         display(10,10,Time[2],Time[3]);
  217.                         LED1=0;
  218.                         LED3=1;
  219.                         break;
  220. /*******************************************************/
  221.                
  222.         case 5:time1.Year=button_time(time1.Year,100,99);                //调整年                            
  223.                         DS1302_SetTime(0x8c,time1.Year);
  224.                         display(Dime[0],Dime[1],10,10);
  225.                         LED1=1;
  226.                         LED2=0;
  227.                         break;
  228.        
  229.         case 6:time1.Month=button_time(time1.Month,13,12);                //调整月                          
  230.                         DS1302_SetTime(0x88,time1.Month);
  231.                         display(10,10,Dime[2],Dime[3]);
  232.                         LED1=1;
  233.                         LED2=0;
  234.                         break;
  235. /********************************************************/       
  236.                                          
  237.            case 7:time1.Day=button_time(time1.Day,32,31);                        //调整日
  238.                         DS1302_SetTime(0x86,time1.Day);
  239.                         display(Bime[0],Bime[1],10,10);
  240.                         LED2=1;
  241.                         LED3=0;
  242.                         break;
  243.        
  244.         case 8:time1.Week=button_time(time1.Week,8,7);                        //调整周
  245.                         DS1302_SetTime(0x8a,time1.Week);
  246.                         display(10,10,Bime[2],Bime[3]);
  247.                         LED2=1;
  248.                         LED3=0;
  249.                         break;
  250.     }
  251. }
  252. /*******************************************************/
  253. void t0_timer() interrupt 1                                //冒号中断赋值
  254. {
  255.       TH0=0x3c;
  256.       TL0=0xb0;
  257.       miao_num++;
  258. }
  259. /*******************************************************/
  260. void mao_hao()                                        //冒号子程序
  261. {
  262. if(miao_num>=20)
  263.    {
  264.    miao_num=0;
  265.    }
  266.    if(miao_num<10)
  267.      LED4=0;
  268.          if(miao_num>=10)
  269.           LED4=1;
  270. }
复制代码

所有资料51hei提供下载:
15共阴.rar (31.37 KB, 下载次数: 48)

截图01.jpg (30.81 KB, 下载次数: 70)

截图01.jpg

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:233015 发表于 2020-1-15 08:40 来自手机 | 只看该作者
不错不错
回复

使用道具 举报

板凳
ID:584814 发表于 2020-1-15 14:44 | 只看该作者
程序里写共阳文件名供阴,共阳还是供阴 ?
回复

使用道具 举报

地板
ID:95809 发表于 2020-1-26 13:14 来自手机 | 只看该作者
man1234567 发表于 2020-1-15 14:44
程序里写共阳文件名供阴,共阳还是供阴 ?

共阴共阳都可以,改一下数码管的段码就行了,手里有什么就用什么,
回复

使用道具 举报

5#
ID:442895 发表于 2020-1-26 15:52 | 只看该作者
man1234567 发表于 2020-1-15 14:44
程序里写共阳文件名供阴,共阳还是供阴 ?

自己不会看吗
回复

使用道具 举报

6#
ID:477512 发表于 2020-1-27 08:34 | 只看该作者
把DS1302换成DS3231就好了,它的精度更高更准。
回复

使用道具 举报

7#
ID:95809 发表于 2020-1-27 15:54 来自手机 | 只看该作者
wbwcf13e 发表于 2020-1-27 08:34
把DS1302换成DS3231就好了,它的精度更高更准。

1302便宜,我7分钱一个买了一堆,精度也可以接受,3231最便宜也得3块钱。
回复

使用道具 举报

8#
ID:102963 发表于 2020-2-13 09:06 | 只看该作者
缺少电路图
回复

使用道具 举报

9#
ID:694032 发表于 2020-2-16 20:07 | 只看该作者
请问师傅有Keil模拟图吗?
回复

使用道具 举报

10#
ID:315554 发表于 2020-4-2 13:15 | 只看该作者
谢谢分享,确实,要很认真找找在哪里改共阳才行,
回复

使用道具 举报

11#
ID:305511 发表于 2020-4-2 16:02 | 只看该作者
还以为是做了个充电宝呢!
回复

使用道具 举报

12#
ID:95809 发表于 2020-4-3 12:01 来自手机 | 只看该作者
yan1516 发表于 2020-2-16 20:07
请问师傅有Keil模拟图吗?

15单片机没法仿真,你可以用51单片机来代替仿真。
回复

使用道具 举报

13#
ID:95809 发表于 2020-4-3 12:06 来自手机 | 只看该作者
ak333 发表于 2020-4-2 13:15
谢谢分享,确实,要很认真找找在哪里改共阳才行,

段码改为共阳的,位码DIG1~4改成反的,就行了。共阴极DIG=0,共阳极DIG=1,你想是不是这个道理。
回复

使用道具 举报

14#
ID:848824 发表于 2020-12-23 14:54 | 只看该作者
高手,小白来学习看看
回复

使用道具 举报

15#
ID:235691 发表于 2024-1-31 08:48 | 只看该作者
数码管不用限流电阻吗?
回复

使用道具 举报

16#
ID:1112603 发表于 2024-3-26 08:52 | 只看该作者
这个思路不错,物尽其用。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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