教程如下:
- 按键修改时间:一共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是一对,并且波特率一样就行了。
- 好贴代码:(需要找到对应的库文件才行,懒得的话 直接点我的博客或者链接去下载吧)
- #include <FlexiTimer2.h>
- #include <LiquidCrystal.h>
- /*
- Arduino 连接 DS1302
- 增加了串口调整时间代码
- 2019,11,17,11,22,40,5
- */
- #include <stdio.h>
- #include <string.h>
- #include "DS1302.h"
- // 初始化针脚
- const int rs = 30, en = 31 , d4 = 32, d5 = 33, d6 = 34,d7 = 35;
- LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
- /* 接口定义
- CE(DS1302 pin5) -> Arduino D5
- IO(DS1302 pin6) -> Arduino D6
- SCLK(DS1302 pin7) -> Arduino D7
- */
- uint8_t CE_PIN = 24;
- uint8_t IO_PIN = 26;
- uint8_t SCLK_PIN = 25;
- /* 日期变量缓存 */
- char buf[50];
- char buflcd1[30],buflcd2[30],buflcd3[30];
- char day[10];
- /* 串口数据缓存 */
- String comdate = "";
- int numdate[7] ={0}, j = 0, mark = 0;
- /* 创建 DS1302 对象 */
- DS1302 rtc (CE_PIN, IO_PIN, SCLK_PIN);
- void print_time()
- {
- /* 从 DS1302 获取当前时间 */
- Time t = rtc.time();
- /* 将星期从数字转换为名称 */
- memset(day, 0, sizeof(day));
- switch (t.day)
- { case 0: strcpy(day, "Saturday "); break;
- case 1: strcpy(day, "Sunday "); break;
- case 2: strcpy(day, "Monday "); break;
- case 3: strcpy(day, "Tuesday "); break;
- case 4: strcpy(day, "Wednesday"); break;
- case 5: strcpy(day, "Thursday "); break;
- case 6: strcpy(day, "Friday "); break;
- case 7: strcpy(day, "Saturday "); break;
- }
- /* 将日期代码格式化凑成buf等待输出 */
- snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d", day, t.yr, t.mon, t.date, t.hr, t.min, t.sec);
- /* 输出日期到串口 */
- Serial.println(buf);
- }
- int w=0;
- void setup()
- {
- Serial.begin(9600);
- rtc.write_protect(false);
- rtc.halt(false);
- attachInterrupt(1,minutes, FALLING);//引脚号是3 分钟加一
- attachInterrupt(5,hours, FALLING);//引脚号是18 小时加一
- attachInterrupt(4,days, FALLING);//引脚号是19 天数加一
- attachInterrupt(3,monthes, FALLING);//引脚号是20 月份加一
- attachInterrupt(2,years, FALLING);//引脚号是21 年份加一
- lcd.begin(16, 2);lcd.setCursor(1, 0);
- lcd.print("17dianziyiban ");//17电子一班
- lcd.setCursor(1, 1);
- lcd.print(" shichengshi"); //施成师
- delay(1000);
- lcd.clear() ;
- FlexiTimer2::set(500,1.0/1000,LCD);
- FlexiTimer2::start();
- }
- void LCD()
- {
- Time t = rtc.time(); //LCD的屏幕会有显示“残留”
- snprintf(buflcd1, sizeof(buflcd1), "%04d %s",t.yr, day );//为了减少清屏带来的闪烁
- lcd.setCursor(0, 0);lcd.print(buflcd1); //LCD显示字符的排版 比较奇特
- snprintf(buflcd2, sizeof(buflcd2), "%02d-%02d",t.mon ,t.date);
- lcd.setCursor(0, 1);lcd.print(buflcd2);
- snprintf(buflcd3, sizeof(buflcd3), "%02d:%02d:%02d", t.hr, t.min, t.sec);
- lcd.setCursor(6, 1);lcd.print(buflcd3);
- }
- void minutes()
- {
- Time t = rtc.time();
- t.min++;if(t.min>60)t.min=1,t.hr++;
- Time p( t.yr, t.mon, t.date, t.hr, t.min,t.sec,t.day);
- rtc.time(p);
- }
- void hours()
- {
- Time t = rtc.time();
- t.hr++;
- if(t.hr>24)
- {t.hr=1;t.day++;t.date++;
- t.day=t.day%7;
- }Time p( t.yr, t.mon, t.date, t.hr, t.min,t.sec,t.day);
- rtc.time(p);
- }
- void days()
- {
- Time t = rtc.time();
- t.date++;
- switch(t.mon)
- {case 1: if(t.date>31)t.date=1,t.mon++;break;
- case 2: if(t.date>28)t.date=1,t.mon++;break;
- case 3: if(t.date>31)t.date=1,t.mon++;break;
- case 4: if(t.date>30)t.date=1,t.mon++;break;
- case 5: if(t.date>31)t.date=1,t.mon++;break;
- case 6: if(t.date>30)t.date=1,t.mon++;break;
- case 7: if(t.date>31)t.date=1,t.mon++;break;
- case 8: if(t.date>31)t.date=1,t.mon++;break;
- case 9: if(t.date>30)t.date=1,t.mon++;break;
- case 10: if(t.date>31)t.date=1,t.mon++;break;
- case 11: if(t.date>30)t.date=1,t.mon++;break;
- case 12: if(t.date>31)t.date=1,t.mon++;break;
- }
- t.day++;t.day=t.day%7;
- Time p( t.yr, t.mon, t.date, t.hr, t.min,t.sec,t.day);
- rtc.time(p);
- }
- void monthes()
- {
- Time t = rtc.time();
- t.mon++; if(t.mon>12)t.mon=1,t.yr++;
- switch(t.mon)
- {case 1: t.day+=3;t.day=t.day%7;break;
- case 2: t.day+=3;t.day=t.day%7;break;
- case 3: if(t.yr%4==0)t.day+=1;else t.day+=0;t.day=t.day%7;break;
- case 4: t.day+=3;t.day=t.day%7;break;
- case 5: t.day+=2;t.day=t.day%7;break;
- case 6: t.day+=3;t.day=t.day%7;break;
- case 7: t.day+=2;t.day=t.day%7;break;
- case 8: t.day+=3;t.day=t.day%7; break;
- case 9: t.day+=3;t.day=t.day%7;break;
- case 10: t.day+=2;t.day=t.day%7;break;
- case 11: t.day+=3;t.day=t.day%7;break;
- case 12: t.day+=2;t.day=t.day%7;break;
- }
- Time p( t.yr, t.mon, t.date, t.hr, t.min,t.sec,t.day);
- rtc.time(p);
- }
- void years()
- {
- Time t = rtc.time();
- t.yr++;
- switch((t.yr-1)%4)
- {case 0:if(t.mon<3)t.day+=2;else t.day+=1;break;
- default: t.day+=1;
- }
- Time p( t.yr, t.mon, t.date, t.hr, t.min,t.sec,t.day);
- rtc.time(p);
- }
-
- void loop()
- {
- /* 当串口有数据的时候,将数据拼接到变量comdate */
- while (Serial.available() > 0)
- {
- comdate += char(Serial.read());
- delay(2);
- mark = 1;
- }
- /* 以逗号分隔分解comdate的字符串,分解结果变成转换成数字到numdate[]数组 */
- if(mark == 1)
- {
- //Serial.print("You inputed : ");
- //Serial.println(comdate);
- for(int i = 0; i < comdate.length() ; i++)
- {
- if(comdate[i] == ',' || comdate[i] == 0x10 || comdate[i] == 0x13)
- {
- j++;
- }
- else
- {
- numdate[j] = numdate[j] * 10 + (comdate[i] - '0');
- }
- }
- /* 将转换好的numdate凑成时间格式,写入DS1302 */
- Time t(numdate[0], numdate[1], numdate[2], numdate[3], numdate[4], numdate[5], numdate[6]);
- rtc.time(t);
- mark = 0;j=0;
- /* 清空 comdate 变量,以便等待下一次输入 */
- comdate = String("");
- /* 清空 numdate */
- for(int i = 0; i < 7 ; i++) numdate[i]=0;
- }
-
- /* 打印当前时间 */
- print_time();
- delay(1000);
- }
复制代码
全部资料51hei下载地址:
基于 Arduino MEGA2560的 DS1302 实时时钟和修改( protues仿真+程序+虚拟串口软件+.zip
(5.62 MB, 下载次数: 44)
|