教程如下:
- 按鍵修改時間:一共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)
2020-4-17 15:42 上傳
點擊文件名下載附件
|