找回密码
 立即注册

QQ登录

只需一步,快速开始

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

Arduino MEGA2560 DS1302 实时时钟(protues+程序)使用教程 可用串口、按键修改

[复制链接]
跳转到指定楼层
楼主
教程如下:

  • 实现功能:(代码见底部)
  • 串口和1602 显示实时时间
  • 串口和按键修改时间
  • 实时时钟:

  • 按键修改时间:一共5个按键,分别修改分钟、小时、天数、月份、年份。
分钟满60归1,小时进1。小时24进制。 天数按照公历闰平年来计算某年某月是多少进制。如2020年2月是闰二月,一共29天,那这个天数就是29进制。 包括星期几也计算在内。已经验证准确无误。 (只是每次按键都是加一)

  • 串口修改时间:格式如:2019,11,17,12,25,36,5
                                     年,月,日,时,分,秒,星期
通过Arduino编译器的串口调试器发送。(确保串口发送的日期跟星期几是对应的,按键是在正确对应的情况下计算才会准确)

  • 虚拟 串口安装如下:VSPD串口软件的文件夹里找到vspd ,点击ok,I agree ,next,finish

  • 打开软件:直接点击ok
  • 然后点击Add Pair:

  • 在Arduino编译器上找到串口调试器,设置波特率(一般是9600)当然只要仿真里的虚拟串口COMPIM跟Arduino是一对,并且波特率一样就行了。
  • 好贴代码:(需要找到对应的库文件才行,懒得的话 直接点我的博客或者链接去下载吧)


  1. #include <FlexiTimer2.h>  
  2. #include <LiquidCrystal.h>
  3. /*
  4. Arduino 连接 DS1302
  5. 增加了串口调整时间代码
  6. 2019,11,17,11,22,40,5
  7. */
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include "DS1302.h"
  11. // 初始化针脚
  12. const int rs = 30, en = 31 , d4 = 32, d5 = 33, d6 = 34,d7 = 35;
  13. LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
  14. /* 接口定义
  15. CE(DS1302 pin5) -> Arduino D5
  16. IO(DS1302 pin6) -> Arduino D6
  17. SCLK(DS1302 pin7) -> Arduino D7
  18. */
  19. uint8_t CE_PIN   = 24;
  20. uint8_t IO_PIN   = 26;
  21. uint8_t SCLK_PIN = 25;
  22. /* 日期变量缓存 */
  23. char buf[50];
  24. char buflcd1[30],buflcd2[30],buflcd3[30];
  25. char day[10];
  26. /* 串口数据缓存 */
  27. String comdate = "";
  28. int numdate[7] ={0}, j = 0, mark = 0;
  29. /* 创建 DS1302 对象 */
  30. DS1302 rtc (CE_PIN, IO_PIN, SCLK_PIN);

  31. void print_time()
  32. {
  33.     /* 从 DS1302 获取当前时间 */
  34.     Time t = rtc.time();
  35.     /* 将星期从数字转换为名称 */
  36.     memset(day, 0, sizeof(day));
  37.     switch (t.day)
  38.     { case 0: strcpy(day, "Saturday "); break;
  39.       case 1: strcpy(day, "Sunday   "); break;
  40.       case 2: strcpy(day, "Monday   "); break;
  41.       case 3: strcpy(day, "Tuesday  "); break;
  42.       case 4: strcpy(day, "Wednesday"); break;
  43.       case 5: strcpy(day, "Thursday "); break;
  44.       case 6: strcpy(day, "Friday   "); break;
  45.       case 7: strcpy(day, "Saturday "); break;
  46.     }
  47.     /* 将日期代码格式化凑成buf等待输出 */
  48.     snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d", day, t.yr, t.mon, t.date, t.hr, t.min, t.sec);
  49.     /* 输出日期到串口 */
  50.     Serial.println(buf);
  51. }
  52. int w=0;
  53. void setup()
  54. {   
  55.     Serial.begin(9600);
  56.     rtc.write_protect(false);
  57.     rtc.halt(false);
  58.     attachInterrupt(1,minutes, FALLING);//引脚号是3 分钟加一
  59.     attachInterrupt(5,hours, FALLING);//引脚号是18  小时加一
  60.     attachInterrupt(4,days, FALLING);//引脚号是19  天数加一
  61.     attachInterrupt(3,monthes, FALLING);//引脚号是20 月份加一
  62.     attachInterrupt(2,years, FALLING);//引脚号是21  年份加一
  63.     lcd.begin(16, 2);lcd.setCursor(1, 0);
  64.     lcd.print("17dianziyiban ");//17电子一班
  65.     lcd.setCursor(1, 1);   
  66.     lcd.print(" shichengshi");  //施成师
  67.     delay(1000);
  68.     lcd.clear() ;  
  69.     FlexiTimer2::set(500,1.0/1000,LCD);
  70.     FlexiTimer2::start();  
  71. }
  72. void LCD()
  73. {
  74.    Time t = rtc.time();                                       //LCD的屏幕会有显示“残留”
  75.    snprintf(buflcd1, sizeof(buflcd1), "%04d  %s",t.yr, day );//为了减少清屏带来的闪烁
  76.    lcd.setCursor(0, 0);lcd.print(buflcd1);                   //LCD显示字符的排版 比较奇特
  77.    snprintf(buflcd2, sizeof(buflcd2), "%02d-%02d",t.mon ,t.date);
  78.    lcd.setCursor(0, 1);lcd.print(buflcd2);
  79.    snprintf(buflcd3, sizeof(buflcd3), "%02d:%02d:%02d",  t.hr, t.min, t.sec);
  80.    lcd.setCursor(6, 1);lcd.print(buflcd3);  
  81. }
  82. void minutes()
  83. {
  84.   Time t = rtc.time();  
  85.   t.min++;if(t.min>60)t.min=1,t.hr++;
  86.   Time p( t.yr, t.mon, t.date, t.hr, t.min,t.sec,t.day);
  87.   rtc.time(p);
  88. }
  89. void hours()
  90. {
  91.   Time t = rtc.time();  
  92.   t.hr++;
  93.   if(t.hr>24)
  94.   {t.hr=1;t.day++;t.date++;
  95.    t.day=t.day%7;
  96.   }Time p( t.yr, t.mon, t.date, t.hr, t.min,t.sec,t.day);
  97.   rtc.time(p);
  98. }
  99. void days()
  100. {
  101.   Time t = rtc.time();  
  102.   t.date++;  
  103.    switch(t.mon)
  104.      {case 1: if(t.date>31)t.date=1,t.mon++;break;
  105.      case 2: if(t.date>28)t.date=1,t.mon++;break;
  106.      case 3: if(t.date>31)t.date=1,t.mon++;break;
  107.      case 4: if(t.date>30)t.date=1,t.mon++;break;
  108.      case 5: if(t.date>31)t.date=1,t.mon++;break;
  109.      case 6: if(t.date>30)t.date=1,t.mon++;break;
  110.      case 7: if(t.date>31)t.date=1,t.mon++;break;
  111.      case 8: if(t.date>31)t.date=1,t.mon++;break;
  112.      case 9: if(t.date>30)t.date=1,t.mon++;break;
  113.      case 10: if(t.date>31)t.date=1,t.mon++;break;
  114.      case 11: if(t.date>30)t.date=1,t.mon++;break;
  115.      case 12: if(t.date>31)t.date=1,t.mon++;break;
  116.      }
  117.   t.day++;t.day=t.day%7;
  118.   Time p( t.yr, t.mon, t.date, t.hr, t.min,t.sec,t.day);
  119.   rtc.time(p);
  120. }
  121. void monthes()
  122. {
  123.   Time t = rtc.time();  
  124.   t.mon++; if(t.mon>12)t.mon=1,t.yr++;
  125.   switch(t.mon)
  126.      {case 1: t.day+=3;t.day=t.day%7;break;
  127.      case 2: t.day+=3;t.day=t.day%7;break;
  128.      case 3:   if(t.yr%4==0)t.day+=1;else t.day+=0;t.day=t.day%7;break;
  129.      case 4:   t.day+=3;t.day=t.day%7;break;
  130.      case 5:   t.day+=2;t.day=t.day%7;break;
  131.      case 6:   t.day+=3;t.day=t.day%7;break;
  132.      case 7:  t.day+=2;t.day=t.day%7;break;
  133.      case 8:  t.day+=3;t.day=t.day%7; break;
  134.      case 9:   t.day+=3;t.day=t.day%7;break;
  135.      case 10:  t.day+=2;t.day=t.day%7;break;
  136.      case 11:   t.day+=3;t.day=t.day%7;break;
  137.      case 12: t.day+=2;t.day=t.day%7;break;
  138.      }
  139.   Time p( t.yr, t.mon, t.date, t.hr, t.min,t.sec,t.day);
  140.   rtc.time(p);
  141. }
  142. void years()
  143. {
  144.   Time t = rtc.time();  
  145.   t.yr++;
  146.   switch((t.yr-1)%4)
  147.   {case 0:if(t.mon<3)t.day+=2;else t.day+=1;break;
  148.   default: t.day+=1;
  149.   }
  150.   Time p( t.yr, t.mon, t.date, t.hr, t.min,t.sec,t.day);
  151.   rtc.time(p);
  152. }

  153. void loop()
  154. {
  155.    /* 当串口有数据的时候,将数据拼接到变量comdate */
  156.     while (Serial.available() > 0)
  157.     {
  158.         comdate += char(Serial.read());
  159.         delay(2);
  160.         mark = 1;
  161.     }
  162.     /* 以逗号分隔分解comdate的字符串,分解结果变成转换成数字到numdate[]数组 */
  163.     if(mark == 1)
  164.     {
  165.         //Serial.print("You inputed : ");
  166.         //Serial.println(comdate);
  167.         for(int i = 0; i < comdate.length() ; i++)
  168.         {
  169.             if(comdate[i] == ',' || comdate[i] == 0x10 || comdate[i] == 0x13)
  170.             {
  171.                 j++;
  172.             }
  173.             else
  174.             {
  175.                 numdate[j] = numdate[j] * 10 + (comdate[i] - '0');
  176.             }
  177.         }
  178.         /* 将转换好的numdate凑成时间格式,写入DS1302 */
  179.         Time t(numdate[0], numdate[1], numdate[2], numdate[3], numdate[4], numdate[5], numdate[6]);
  180.         rtc.time(t);
  181.         mark = 0;j=0;
  182.         /* 清空 comdate 变量,以便等待下一次输入 */
  183.         comdate = String("");
  184.         /* 清空 numdate */
  185.         for(int i = 0; i < 7 ; i++) numdate[i]=0;
  186.     }
  187.    
  188.     /* 打印当前时间 */
  189.     print_time();
  190.     delay(1000);
  191. }
复制代码

全部资料51hei下载地址:
基于 Arduino MEGA2560的 DS1302 实时时钟和修改( protues仿真+程序+虚拟串口软件+.zip (5.62 MB, 下载次数: 44)

评分

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

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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