1. sys_time.tm_wday應該不是必須的,設定它的原因是?
Ans:
tm 結構是C90/C99中的標準定義, 其中既成tm_wday的配置, 用來設定及記錄星期幾,
但是目前的RTC_RTCCTimeGet()並沒有計算wday, 誠如您所述該變數目前沒有效果,
這裡提供wday的計算程式, 採用Zeller公式計算而得,
ps. 程式末尾兩個字元為論壇貼code產生請自行刪除
// Zeller's congruence :
// w = (y + [y/4] + [c/4] - 2*c + [(26*(m+1))/10] + d - 1) % 7
// [] : Integer part of result
// y : Year(last 2 digit) , 2021 % 100 => y = 21
// c : Year(first 2 digit), 2021 / 100 => c = 20
// January and February as last year, if date is Feb, 2000 then
// y = (2000-1) % 100 = 1999 % 100 => y = 99
// c = (2000-1) / 100 = 1999 / 100 => c = 19
// m : Month(13,14,[3~12]), January,February => m=[13,14], March~December => m=[3~12]
// d : Day
// w : Weekday, [0~7] [Sunday,Monday~Saturday]
// w might a minus number, please use w = ((w % 7) + 7) % 7
char Week[7][5] = {"SUN. ", "MON. ","TUE. ","WED. ","THR. ","FRI. ","SAT. "};
int c = (sys_time.tm_year-(sys_time.tm_mon<2?1:0)+1900) / 100;
int y = (sys_time.tm_year-(sys_time.tm_mon<2?1:0)+1900) % 100;
int m = (sys_time.tm_mon<2?sys_time.tm_mon+13:sys_time.tm_mon+1);
int d = sys_time.tm_mday;
int w = (((y + (int)(y/4) + (int)(c/4) - 2*c + (int)((26*((float)m+1))/10) + d - 1) % 7 ) + 7 ) % 7;
sys_time.tm_wday = w;
printf("System time is: %02d:%02d:%02d %s \r", sys_time.tm_hour, sys_time.tm_min, sys_time.tm_sec, Week[w]);
2. sys_time.tm_year在範例說明裡寫since 1900,但RTC_RTCCTimeSet裡面是
2.1 請說明一下這個計算方式(閏年與1900參考值的關係),為什麼要設定leap year?,Spec中也沒有看到與1900有相關(見附圖spec部份紅框)
Ans:
TM_STRUCT_REFERENCE_YEAR 是 1900 作為 tm 的參考年分,
在C語言標準tm結構中是以1900為基準, 因此在填值時, 需用目前年份減1900填到tm_year中,
如果您的程式之前在其他平台也用tm結構來完成時, 就會無縫接軌
REFERENCE_YEAR 是 在Harmony中RTC Module設定的Reference Year(Leap Year)值,
可以是任何一個閏年(公元年分為4的倍數但非100的倍數, ex 2004, 2008, 2012, 2016, 2020,...)
至於為何需要閏年來計算萬年曆, 可以自行爬一下文來了解
SAME5X的RTC有閏年修正機制, 因此在Harmony中設置的REFERENCE_YEAR,
會依照你在RTC_RTCCTimeSet()中給定的tm.tm_year的值, 減去後設置到暫存器RTC_REGS->MODE2.RTC_CLOCK
2.2 RTC_RTCCTimeSet及讀取應該要隱藏這種莫名奇妙的計算,讓使用者直接輸入想要的年份,struct tm裡的每一個欄位都是int,也沒有什麼大小不夠用的問題。內部想用UNIX time沒問題,但應該讓使用者選擇自己想要的輸入方式。想要2018年,就輸入2018,還要自己手算的話弄成API幹嘛?
3. 因為我想用RTC當日曆,請問可以用它來做UTC與Local time的轉換嗎?即裡面跑UTC時間,要取出用時,可轉換為想要的local time。這種基本的功能我覺得應該要包在API裡面...
Ans:
RTC_RTCCTimeSet()是比照大部分Clock設置的用法來設計, 也就是說只要用tm結構的Library程式都是這樣在計算,
因此請依照自己的需求來開發與時間有關的API, 並調用RTC_RTCCxxxx()library interface function.4. 可以說明一下Tamper的作用嗎?我看說明覺得它好像是接受外部異常觸發,然後儲存異常時間點(或一些額外資訊?)用的,我這樣理解對嗎?
Ans:
這部分可以先行詳讀規格書後再來討論細節喔!5. 隨便抱怨一下,這個範例竟然在while(1)裡面直接print取出的時間,我一啟動之後,terminal程式就爆了,寫出這種範例的人是和開發者有仇嗎?
Ans:
在While迴圈中這行printf程式, 使用'\r'歸位字元結尾, 目的是在同一行不斷刷新顯示當前的系統時間,
除非您使用的終端機無法辨識\r歸位字元, 不然應該不會刷整個屏才是
printf("System time is: %02d:%02d:%02d %d %s\r",sys_time.tm_hour, sys_time.tm_min, sys_time.tm_sec, w, Week[w]);
Edited by Libra on 2020年07月08日 11:13:29
Edited by Libra on 2020年07月08日 11:14:41
Edited by Libra on 2020年07月08日 11:17:25
Edited by Libra on 2020年07月08日 11:18:50
Edited by Libra on 2020年07月08日 11:19:37
Edited by Libra on 2020年07月08日 11:22:38
Edited by Libra on 2020年07月08日 11:24:13
Edited by Libra on 2020年07月08日 11:25:15
Edited by Libra on 2020年07月08日 11:25:55
Edited by Libra on 2020年07月08日 11:27:04
Edited by Libra on 2020年07月08日 11:28:17
Edited by Libra on 2020年07月08日 11:46:30