电子技术论坛

 找回密码
 快速注册

QQ登录

只需一步,快速开始

搜索
下载方法|用单线程|避免多扣帖子规范|求助必读|发帖建议积分策略|勋章介绍|新人必读获取金币|推广论坛|出售帖子基本礼节|致会员信|版规总则
禁涉政治|反对低俗|举报专帖征集相片|留下足迹|推荐精华上传附件|制作分卷|使用网盘禁发qq群|恶意灌水|纯表情帖加入团队|监督机制|安全上网
查看: 3690|回复: 2

百年历时钟雏形万年历

[复制链接]
发表于 2011-5-22 11:30:58 | 显示全部楼层 |阅读模式

注册家电维修技术论坛,与同行畅聊维修技术,享更多技术论坛功能。

您需要 登录 才可以下载或查看,没有帐号?快速注册

x

  1. #include <AT89X52.H>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. #define lcd_date P0    //lcd 数据口
  5. sbit lcden=P2^7;//lcd
  6. sbit lcdrs=P2^6;//lcd
  7. sbit lcdrw=P2^5;//lcd
  8. void lcd_display();
  9. void keyscan();
  10. char second,minute,hour,week,day,month,year;//年的取值范围0~99
  11. //double temperature;
  12. uchar code table[]= {"2011:05:06"};//10个字符
  13. uchar code table1[]={"  18:00:00  W:5"};//15个字符

  14. sbit key0=P1^0;        //按键
  15. sbit key1=P1^1;
  16. sbit key2=P1^2;
  17. sbit key3=P1^3;
  18. sbit key4=P1^4;
  19. char flag,flag1,move,control;
  20. //sbit fu=P1^7;

  21. sbit DS1302_CLK = P3^6;   //时钟引脚
  22. sbit DS1302_IO  = P3^4;   //数据引脚
  23. sbit DS1302_RST = P3^5;   //复位引脚
  24. sbit ACC0 = ACC^0;
  25. sbit ACC7 = ACC^7;

  26. #define DS1302_SECOND      0x80
  27. #define DS1302_MINUTE      0x82
  28. #define DS1302_HOUR        0x84
  29. #define DS1302_WEEK        0x8A
  30. #define DS1302_DAY         0x86
  31. #define DS1302_MONTH       0x88
  32. #define DS1302_YEAR        0x8C
  33. //*****延时******
  34. void delay(uint z)//定时1ms
  35. {uint x,y;
  36. for(x=z;x>0;x--)
  37. for(y=110;y>0;y--);
  38. }
  39. ///****写入一个字节***///
  40. void DS1302_InputByte(uchar Data)  
  41. {   uchar i;
  42.         ACC = Data;
  43.         for(i=8; i>0; i--)
  44.         {        DS1302_CLK = 0;               
  45.                 DS1302_IO = ACC0;        //由低位到高位               
  46.                 DS1302_CLK = 1;                //上升沿写入数据
  47.                 ACC >>= 1;
  48.         }}
  49. //读取一个字节(内部函数)
  50. uchar DS1302_OutputByte(void)
  51. {   uchar i;
  52.         for(i=8; i>0; i--)
  53.         {        DS1302_CLK = 0;      //下降沿读出DS1302的数据
  54.                 ACC >>= 1;                         //读出由低到高位,只能移7次有效位!!!
  55.                 ACC7 = DS1302_IO;         //第一个数据                                                                                
  56.                 DS1302_CLK = 1;                                                                
  57.         }                                                 
  58.         return (ACC);
  59. }
  60. //在指定地址写入指定的数据
  61. void Write1302(uchar Address, uchar Data)
  62. {   DS1302_RST = 0;
  63.         DS1302_CLK = 0;
  64.         DS1302_RST = 1;
  65.         DS1302_InputByte(Address);
  66.         DS1302_InputByte(Data);
  67.         DS1302_CLK = 1;
  68.         DS1302_RST = 0;
  69. }
  70. //读取1302指定地址中的数据
  71. uchar Read1302(uchar Address)
  72. {   uchar Data;
  73.         DS1302_RST = 0;
  74.         DS1302_CLK = 0;
  75.         DS1302_RST = 1;                                   //RST拉高,启动数据传送
  76.         DS1302_InputByte(Address|0x01);//读取指定地址数据指令
  77.         Data = DS1302_OutputByte();
  78.         DS1302_CLK = 1;
  79.         DS1302_RST = 0;
  80.         return (Data);
  81. }
  82. //是否写入保护***
  83. void DS1302_SetProtect(bit Flag)
  84. {   if(Flag)
  85.                 Write1302(0x8E,0x80);  //0x8e控制字节地址,bit7=WP WP=1 禁止数据写入DS1302
  86.         else
  87.                 Write1302(0x8E,0x00);  //WP=0 允许数据写入DS1302
  88. }
  89. //***设置时间函数*****
  90. void DS1302_SetTime(uchar Address, uchar Value)
  91. {   DS1302_SetProtect(0);
  92.         Write1302(Address,((Value/10)<<4|(Value%10)));
  93.         DS1302_SetProtect(1);
  94. }
  95. //***初始化DS1302******
  96. void DS1302_init()
  97. {   second=Read1302(DS1302_SECOND);
  98.         if(second&0x80)//bit7=CH CH=0 振荡器允许工作,CH=1振荡器停止工作
  99.         DS1302_SetTime(DS1302_SECOND,0);
  100. }

  101. void DS1302_GetTime()
  102. {
  103.         uchar ReadValue;
  104.         ReadValue = Read1302(DS1302_SECOND);
  105.         second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
  106.         ReadValue = Read1302(DS1302_MINUTE);
  107.         minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
  108.         ReadValue = Read1302(DS1302_HOUR);
  109.         hour   = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
  110.         ReadValue = Read1302(DS1302_DAY);
  111.         day    = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
  112.         ReadValue = Read1302(DS1302_WEEK);
  113.         week   = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
  114.         ReadValue = Read1302(DS1302_MONTH);
  115.         month  = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
  116.         ReadValue = Read1302(DS1302_YEAR);
  117.         year   = ((ReadValue&0xF0)>>4)*10 + (ReadValue&0x0f);
  118. }
  119. //*****1602写命令****
  120. void write_com(uchar com)
  121. {   lcdrs=0;
  122.         lcdrw=0;
  123.         lcd_date=com;
  124.         delay(5);//定时(5x1ms=5ms)
  125.         lcden=1;
  126.         delay(5);
  127.         lcden=0;
  128. }
  129. //***1602写数据*****
  130. void write_date(uchar date)
  131. {   lcdrs=1;
  132.         lcdrw=0;
  133.         lcd_date=date;
  134.         delay(5);//定时(5x1ms=5ms)
  135.         lcden=1;
  136.         delay(5);
  137.         lcden=0;
  138. }
  139. ///*****初始化*****
  140. void _1602_init()
  141. {   uchar i;
  142.         lcden=0;
  143.         write_com(0x38);//设置16x2显示5x7. 8位数据接口
  144.         write_com(0x0F);//设置开显示。不显示光标0000 1100
  145.         write_com(0x06);//写一个字符后地址指针自动加1;0000 0110
  146.         write_com(0x01);//显示清0,数据指针清0

  147.         write_com(0x80);
  148.         for(i=0;i<10;i++)
  149.         write_date(table[i]);

  150.         write_com(0x80+0x40);
  151.         for(i=0;i<15;i++)
  152.         write_date(table1[i]);
  153. //****时间初始化****
  154. /*
  155. DS1302_SetTime(DS1302_SECOND,13);
  156. DS1302_SetTime(DS1302_MINUTE,59);
  157. DS1302_SetTime(DS1302_HOUR,23);
  158. DS1302_SetTime(DS1302_WEEK,7);
  159. DS1302_SetTime(DS1302_DAY,31);
  160. DS1302_SetTime(DS1302_MONTH,12);
  161. DS1302_SetTime(DS1302_YEAR,99);
  162.   */

  163. }
  164. void main()
  165. {
  166. //fu=0;//引出一条地线
  167. _1602_init();
  168. DS1302_init(); //由于1302外接晶振32.768khz 即每秒振荡一次
  169.                            //所以不要加定时器
  170. while(1)
  171.   {
  172.        
  173.         DS1302_GetTime();  //获得DS1302时钟数据
  174.         keyscan();
  175.         if(!flag1)
  176.          lcd_display();
  177.          
  178.   }          
  179. }
  180. //****1602 显示***
  181. void lcd_display()
  182. {

  183.    write_com(0x0c);//不显示光标
  184.         write_com(0x80+0x42);//指针定位在小时十位上
  185.         write_date(0x30+hour/10);//刷新 小时的十位
  186.         write_date(0x30+hour%10);//刷新 小时的个位
  187.        
  188.         write_com(0x80+0x45);//指针定位在分钟十位上
  189.         write_date(0x30+minute/10);//刷新 分钟的十位
  190.         write_date(0x30+minute%10);//刷新 分钟的个位
  191.        
  192.         write_com(0x80+0x48);//指针定位在秒钟十位上
  193.         write_date(0x30+second/10);//刷新 秒钟的十位
  194.         write_date(0x30+second%10);//刷新 秒钟的个位
  195.        
  196.         write_com(0x80+0x4e);//指针定位在星期上
  197.         write_date(0x30+week);//刷新 星期

  198.         write_com(0x80+0x02);//指针定位在年十位上
  199.         write_date(0x30+year/10);//刷新 年的十位
  200.         write_date(0x30+year%10);//刷新 年的个位
  201.        
  202.         write_com(0x80+0x05);//指针定位在月十位上
  203.         write_date(0x30+month/10);//刷新 月的十位
  204.         write_date(0x30+month%10);//刷新 月的个位
  205.        
  206.         write_com(0x80+0x08);//指针定位在天十位上
  207.         write_date(0x30+day/10);//刷新 天的十位
  208.         write_date(0x30+day%10);//刷新 天的个位       
  209.        
  210. }
  211. //*******时间按键调节***
  212. void keyscan()
  213. {
  214. if(key4==0)//调节确定 键
  215. {        control++;
  216.         while(!key4);
  217.         if(control==1)
  218.          {        flag=1;//
  219.                  flag1=1;//关闭显示扫描
  220.                 DS1302_SetTime(DS1302_SECOND,0x80);
  221.                
  222.          }
  223. if(control==2)
  224. {
  225. flag=0;
  226. flag1=0;

  227. control=0;
  228. DS1302_SetTime(DS1302_SECOND,0);

  229. }
  230. }
  231. if(flag)
  232. { if(key0==0)//左移       
  233.          {
  234.          move++;
  235.          if(move>6)
  236.                          move=1;
  237.          while(!key0);
  238.          write_com(0x0f);//显示光标
  239.                   
  240.          switch(move)
  241.          {
  242.          case 1: write_com(0xc6);break;//分 个位
  243.          case 2: write_com(0xc3);break;// 时
  244.          case 3: write_com(0x89);break;//天
  245.          case 4: write_com(0x86);break;//月
  246.          case 5: write_com(0x83);break;// 年
  247.          case 6: write_com(0xce);break;// 星期
  248.          }
  249.          }

  250.   if(key1==0)//右移
  251.          {move--;
  252.           if(move<1)
  253.                          move=6;
  254.           while(!key1);
  255.          switch(move)
  256.          {
  257.          case 1: write_com(0xc6);break;//分 个位
  258.          case 2: write_com(0xc3);break;// 时
  259.          case 3: write_com(0x89);break;//天
  260.          case 4: write_com(0x86);break;//月
  261.          case 5: write_com(0x83);break;// 年
  262.          case 6: write_com(0xce);break;// 星期
  263.          }
  264.          }
  265.   if(key2==0)//加数
  266.   {
  267.          if(move==1) //移到分
  268.                  {         minute++;
  269.                     if(minute>=60)
  270.                                    minute=0;
  271.                    DS1302_SetTime(DS1302_MINUTE,minute);
  272.                    lcd_display();
  273.                    write_com(0x0f);//显示光标
  274.                    write_com(0xc6);//指针指在分的各位上               
  275.              }
  276.           if(move==2)//移到时
  277.                  {
  278.                   hour++;
  279.                   if(hour>23)
  280.                                   hour=0;
  281.                   DS1302_SetTime(DS1302_HOUR,hour);
  282.                   lcd_display();
  283.                    write_com(0x0f);//显示光标
  284.                    write_com(0xc3);//指针指在时的各位上       
  285.        
  286.                  }
  287.          if(move==3) //移到天
  288.                  {
  289.                  day++;
  290.                  if(day>31)
  291.                          day=1;
  292.                  DS1302_SetTime(DS1302_DAY,day);
  293.                  lcd_display();
  294.                    write_com(0x0f);//显示光标
  295.                    write_com(0x89);//指针指在天的各位上       
  296.        
  297.                  }
  298.          if(move==4) //移到月
  299.                  {
  300.                  month++;
  301.                  if(month>12)
  302.                            month=1;
  303.                   DS1302_SetTime(DS1302_MONTH,month);
  304.                    lcd_display();
  305.                    write_com(0x0f);//显示光标
  306.                    write_com(0x85);//指针指在月的各位上       
  307.                  }
  308.          if(move==5) //移到年
  309.                  {
  310.                  year++;
  311.                  if(year>99)
  312.                          year=0;
  313.                  DS1302_SetTime(DS1302_YEAR,year);
  314.                   lcd_display();
  315.                    write_com(0x0f);//显示光标
  316.                    write_com(0x83);//指针指在年的各位上       
  317.        
  318.                  }
  319.          if(move==6) //移到星期
  320.                  {
  321.                  week++;
  322.                  if(week>7)
  323.                          week=1;
  324.                  DS1302_SetTime(DS1302_WEEK,week);
  325.                   lcd_display();
  326.                    write_com(0x0f);//显示光标
  327.                    write_com(0xce);//指针指在星期的各位上       
  328.        
  329.                  }
  330.         }
  331. if(key3==0)//减数
  332.    {
  333.          if(move==1)
  334.                  {minute--;
  335.                  if(minute<0)
  336.                          minute=59;
  337.                   DS1302_SetTime(DS1302_MINUTE,minute);
  338.                   lcd_display();
  339.                    write_com(0x0f);//显示光标
  340.                    write_com(0xc6);//指针指在分的各位上       
  341.                  }
  342.           if(move==2)
  343.                  {
  344.                    hour--;
  345.                    if(hour<0)
  346.                            hour=23;
  347.                   DS1302_SetTime(DS1302_HOUR,hour);
  348.                   lcd_display();
  349.                    write_com(0x0f);//显示光标
  350.                    write_com(0xc3);//指针指在时的各位上       
  351.                  }
  352.          if(move==3)
  353.                  {
  354.                   day--;
  355.                   if(day<1)
  356.                                   day=31;
  357.                  DS1302_SetTime(DS1302_DAY,day);
  358.                   lcd_display();
  359.                    write_com(0x0f);//显示光标
  360.                    write_com(0x89);//指针指在天的各位上       
  361.                  }
  362.          if(move==4)
  363.                  {
  364.                   month--;
  365.                    if(month<1)
  366.                            month=12;
  367.                   DS1302_SetTime(DS1302_MONTH,month);
  368.                    lcd_display();
  369.                    write_com(0x0f);//显示光标
  370.                    write_com(0x85);//指针指在月的各位上       
  371.              }
  372.          if(move==5)
  373.                  {
  374.                  year--;
  375.                  if(year<0)
  376.                          year=99;
  377.                  DS1302_SetTime(DS1302_YEAR,year);
  378.                   lcd_display();
  379.                    write_com(0x0f);//显示光标
  380.                    write_com(0x83);//指针指在年的各位上       
  381.                  }         
  382.          if(move==6)
  383.                  {
  384.                  week--;
  385.                  if(week<1)
  386.                          week=7;
  387.                   DS1302_SetTime(DS1302_WEEK,week);
  388.                    lcd_display();
  389.                    write_com(0x0f);//显示光标
  390.                    write_com(0xce);//指针指在星期的各位上       
  391.             }
  392.          }
  393. }
  394. }
复制代码
 楼主| 发表于 2011-5-22 11:40:47 | 显示全部楼层
要更详细的!或者其他的!练习我!
发表于 2013-12-12 13:25:57 | 显示全部楼层
wang87587427 发表于 2011-5-22 11:40
要更详细的!或者其他的!练习我!

电路图有没有?
您需要登录后才可以回帖 登录 | 快速注册

本版积分规则

手机版|家电维修技术论坛 ( 鄂ICP备09003585号-2 )

GMT+8, 2024-5-13 08:28 , Processed in 0.066795 second(s), 5 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

CopyRight © 电子技术论坛
电子邮箱:8794149@qq.com | 联系 QQ:3081868839 | 官方网址:www.dzdu.com

Qiji. All Rights Reserved


服务条款 | 站长声明

Wuhan Qiji Technology Co., Ltd.武汉奇迹科技有限公司版权所有


鄂ICP备09003585号-2鄂公网安备42010602000420号

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