找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机+Ds1302+lcd1602万年历,可设置时间

  [复制链接]
跳转到指定楼层
楼主
单片机万年历1602仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. //此为主程序,查看完成下载附件,包含仿真,可运行
  2. #include "reg52.h"
  3. #include "main.h"
  4. #include "LCD1602.h"  //显示模块函数在LCD1602.c文件中
  5. //屏幕中第一行和第二行显示的框架
  6. code char lcd_line[2][16]={
  7. "Date 20__-__-__ ",        //显示日期
  8. "Time  __:__:__  ",        //显示时间
  9. };
  10. //按键
  11. sbit S1 = P3^1;  //设置
  12. sbit S2 = P3^5;  //加
  13. sbit S3 = P3^6;  //减
  14. //当前时间
  15. char time_hour=23;
  16. char time_min=59;
  17. char time_sec=55;

  18. char time_year=18;
  19. char time_month=6;
  20. char time_day=30;
  21. uchar mode = 0;                 //当前模式


  22. //STC89系列单片机延时1ms
  23. void delay_ms(unsigned int x)
  24. {
  25.         char j=0;
  26.         while(x--)
  27.                 for(j=0;j<125;j++)
  28.                         ;
  29. }
  30. //读取时间数据
  31. void read_ds1302_all()
  32. {
  33.         time_hour = ds1302_read_hour();//读取小时
  34.         time_min = ds1302_read_min();//分钟
  35.         time_sec = ds1302_read_sec();        //秒钟
  36.         time_year = ds1302_read_year();
  37.         time_month = ds1302_read_month();
  38.         time_day = ds1302_read_day();

  39. }      
  40. //显示
  41. void display_time()
  42. {
  43.         //时分秒
  44.         lcd_write_char(6,1,time_hour/10+'0');
  45.         lcd_write_char(7,1,time_hour%10+'0');
  46.         lcd_write_char(9,1,time_min/10+'0');
  47.         lcd_write_char(10,1,time_min%10+'0');
  48.         lcd_write_char(12,1,time_sec/10+'0');
  49.         lcd_write_char(13,1,time_sec%10+'0');
  50.         //年月日
  51.         lcd_write_char(7,0,time_year/10+'0');
  52.         lcd_write_char(8,0,time_year%10+'0');
  53.         lcd_write_char(10,0,time_month/10+'0');
  54.         lcd_write_char(11,0,time_month%10+'0');
  55.         lcd_write_char(13,0,time_day/10+'0');
  56.         lcd_write_char(14,0,time_day%10+'0');
  57. }                 
  58. //按键扫描
  59. char key_scan()
  60. {
  61.         if(S1==0 || S2==0 || S3==0)                                        // 如果按下了
  62.         {
  63.                 delay_ms(5);                                                                                                                   //去抖动
  64.                 if(S1==0 || S2==0 || S3==0)                           //确实按下了
  65.                 {
  66.                         if(S1==0){while(S1==0); return 1;}          //按键1确实按下了。依此类推。
  67.                         if(S2==0){while(S2==0); return 2;}          //
  68.                         if(S3==0){while(S3==0); return 3;}          //
  69.                 }
  70.         }
  71.         return 0;                                                                          //没有按键按下
  72. }

  73. //按键动作
  74. void key_action()
  75. {
  76.         char key=0;
  77.         key=key_scan();
  78.     if(key == 0) return;

  79.         if(key==1)
  80.         {
  81.                 mode++;
  82.                 if(mode > 6)
  83.                 {
  84.                         mode = 0;
  85.                         lcd_write(0,0x0c);//显示器开,光标关,字符不闪烁
  86.                 }
  87.         }
  88.         switch(mode)
  89.         {
  90.                 case 1:                 //秒
  91.                 {
  92.                        
  93.                         lcd_write(0,0x0f);                 //光标闪烁      
  94.                         lcd_write(0,0x80+0x40+13);        //位置      
  95.                         if(key==2){time_sec++;}         //秒++
  96.                         if(key==3){time_sec--;}         //秒--
  97.                         if(time_sec>=60){time_sec=0;}
  98.                         if(time_sec<0){time_sec=59;}
  99.                         lcd_write_char(12,1,time_sec/10+'0'); //显示
  100.                     lcd_write_char(13,1,time_sec%10+'0');
  101.                         lcd_write(0,0x80+0x40+13);        //回到原位
  102.                         ds1302_set_sec(time_sec );
  103.                        
  104.                 }
  105.                 break;
  106.                 case 2:                         //分
  107.                 {
  108.                        
  109.                         lcd_write(0,0x0f);                 //光标闪烁      
  110.                         lcd_write(0,0x80+0x40+10);        //定位      
  111.                         if(key==2){time_min++;}         //分++
  112.                         if(key==3){time_min--;}         //分--
  113.                         if(time_min>=60){time_min=0;}
  114.                         if(time_min<0){time_min=59;}
  115.                         lcd_write_char(9,1,time_min/10+'0'); //显示
  116.                         lcd_write_char(10,1,time_min%10+'0');
  117.                         lcd_write(0,0x80+0x40+10);        //回到原位
  118.                         ds1302_set_min(time_min );
  119.                 }
  120.                 break;
  121.                 case 3:                   //时
  122.                 {
  123.                        
  124.                         lcd_write(0,0x0f);                 //光标闪烁      
  125.                         lcd_write(0,0x80+0x40+7);        //定位      
  126.                         if(key==2){time_hour++;}         //时++
  127.                         if(key==3){time_hour--;}         //时--
  128.                         if(time_hour>=24){time_hour=0;}
  129.                         if(time_hour<0){time_hour=23;}
  130.                         lcd_write_char(6,1,time_hour/10+'0'); //显示
  131.                         lcd_write_char(7,1,time_hour%10+'0');
  132.                         lcd_write(0,0x80+0x40+7);        //回到原位
  133.                         ds1302_set_hour(time_hour);
  134.                 }
  135.                 break;
  136.                 case 4:                         //年
  137.                 {
  138.                        
  139.                         lcd_write(0,0x0f);                        
  140.                         lcd_write(0,0x80+8);               
  141.                         if(key==2){time_year++;}         
  142.                         if(key==3){time_year--;}
  143.                         lcd_write_char(7,0,time_year/10+'0');
  144.                         lcd_write_char(8,0,time_year%10+'0');
  145.                         lcd_write(0,0x80+8);        //回到原位         
  146.                         ds1302_set_year(time_year);
  147.                 }
  148.                 break;
  149.                 case 5:                         //月
  150.                 {
  151.                        
  152.                         lcd_write(0,0x0f);                        
  153.                         lcd_write(0,0x80+11);               
  154.                         if(key==2){time_month++;}         
  155.                         if(key==3){time_month--;}      
  156.                         if(time_month>12){time_month=1;}
  157.                         if(time_month<0){time_month=12;}
  158.                         lcd_write_char(10,0,time_month/10+'0');
  159.                         lcd_write_char(11,0,time_month%10+'0');
  160.                         lcd_write(0,0x80+11);        //回到原位
  161.                         ds1302_set_month(time_month);
  162.                 }
  163.                 break;
  164.                 case 6:                        //日
  165.                 {
  166.                        
  167.                         lcd_write(0,0x0f);               
  168.                         lcd_write(0,0x80+14);      
  169.                         if(key==2){time_day++;}         
  170.                         if(key==3){time_day--;}
  171.                         //判断28天30天或31天
  172.                         if(time_min==2)          //2月28天
  173.                         {
  174.                         if(time_day>28){time_day=0;}
  175.                         if(time_day<0){time_day=28;}
  176.                         }
  177.                         if(time_month==4 || time_month==6  || time_month==9  || time_month==11)          //30天
  178.                         {
  179.                         if(time_day>30){time_day=0;}
  180.                         if(time_day<0){time_day=30;}
  181.                         }
  182.                         if(time_month==1 || time_month==3  || time_month==5  || time_month==7  || time_month==8  || time_month==10  || time_month==12 )          //31天
  183.                         {
  184.                         if(time_day>31){time_day=0;}
  185.                         if(time_day<0){time_day=31;}
  186.                         }                       
  187.                         lcd_write_char(13,0,time_day/10+'0');
  188.                         lcd_write_char(14,0,time_day%10+'0');
  189.                         lcd_write(0,0x80+14);        //回到原位         
  190.                         ds1302_set_day(time_day);
  191.                 }
  192.                 break;               
  193.         }

  194. }                        
  195. //主程序
  196. void main()
  197. {
  198.         lcd_init();//LCD1602液晶显示屏初始化
  199.         ds1302_init();
  200.         lcd_write_line(0,lcd_line[0]);//屏幕显示第一行框架        
  201.         lcd_write_line(1,lcd_line[1]);//屏幕显示第二行框架
  202.         ds1302_set_sec(time_sec);
  203.         ds1302_set_min(time_min);      
  204.         ds1302_set_hour(time_hour);
  205.         //
  206.         ds1302_set_day(time_day);
  207.         ds1302_set_month(time_month);
  208.         ds1302_set_year(time_year);
  209.         //主循环
  210.         while(1)
  211.         {      
  212.                 key_action();
  213.                
  214.                 if(!mode)                   //没有进入设定时间
  215.                 {
  216.                          read_ds1302_all();           //显示年月日时分秒
  217.                         display_time();                   //显示
  218.                 }
  219.                 else  //读回设定时间
  220.                 {
  221.                         ds1302_set_sec(time_sec);
  222.                         ds1302_set_min(time_min);      
  223.                         ds1302_set_hour(time_hour);
  224.                         //
  225.                         ds1302_set_day(time_day);
  226.                         ds1302_set_month(time_month);
  227.                         ds1302_set_year(time_year);      
  228.                 }
  229.                
  230.         }
  231. }
  232. ////////////////////////////////////
复制代码


所有资料51hei提供下载:
ds1302万年历.rar (107.16 KB, 下载次数: 486)


评分

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

查看全部评分

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

使用道具 举报

沙发
ID:345157 发表于 2018-9-19 17:55 | 只看该作者
谢谢,正在学习
回复

使用道具 举报

板凳
ID:400537 发表于 2018-9-20 17:46 | 只看该作者
感谢分享,对比着试下
回复

使用道具 举报

地板
ID:253741 发表于 2018-9-27 17:56 | 只看该作者
正在学习  加油!
回复

使用道具 举报

5#
ID:408289 发表于 2018-10-15 10:54 | 只看该作者
万年历、加油!
回复

使用道具 举报

6#
ID:684962 发表于 2020-1-11 12:33 | 只看该作者
真棒太感谢了
回复

使用道具 举报

7#
ID:617682 发表于 2020-3-22 16:40 | 只看该作者
这万年历 代码可以解析吗?
回复

使用道具 举报

8#
ID:654855 发表于 2020-4-14 16:57 | 只看该作者
很强,刚学看的有点吃力
回复

使用道具 举报

9#
ID:732301 发表于 2020-5-3 19:53 | 只看该作者
想请问一下作者在LCD那里RW为什么不用连接,直接接地?
回复

使用道具 举报

10#
ID:249808 发表于 2020-9-28 09:57 | 只看该作者
仿真了一下!还可以!可以用老版本软件仿真!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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