osal的時鐘實現在osal_cockble.c與osal_clock.h兩個檔案中。osal支援完整的utc(世界統一時間),以2023年1月1日00:00:00為時間起點,可以精確到年、月、日、時、分、秒的時間值。
1、定義utc格式的結構:
typedef struct
uint8 seconds; // 0-59
uint8 minutes; // 0-59
uint8 hour; // 0-23
uint8 day; // 0-30
uint8 month; // 0-11
uint16 year; // 2000+
} utctimestruct;
2、幾個巨集定義
閏年的判斷:**意義上的閏年是能被4整除且不能被100整除,或者能被400整除的年份。
#define isleapyear(yr) (!((yr) % 400) || (((yr) % 100) && !((yr) % 4)))
年份的天數:閏年有366天,非閏年則有365天。
#define yearlength(yr) (isleapyear(yr) ? 366 : 365)
utc的起始年份:這裡以2023年為起始年份。
#define begyear 2000 // utc started at 00:00:00 january 1, 2000
一天的秒數:24小時*60分鐘*60秒。
#define day 86400ul // 24 hours * 60 minutes * 60 seconds
用於計算的最大節拍:(maxcalcticks * 5) + (max remainder) 必須小於等於65535(16位)。因為直接給osal時鐘提供的硬體節拍為的單位為625us,即5/8ms,所以在計算的是為了將us單位的時間轉換成ms單位的時鐘需要才乘於5/8,即先乘於5再除以8,為了保證乘於5後的值小於65535,所以才定義了下面的最大節拍數。
#define maxcalcticks ((uint16)(13105))
3、幾個變數
儲存utc時間對應的秒數變數:utctime型別即uint32,能儲存的年數為2^32/86400/365=136年左右,如果utc以2023年為起點,則最長可以設定的時間為2023年。
utctime osal_timeseconds = 0;
用於儲存之前的硬體定時器節拍變數:
static uint16 previouslltimertick = 0;
用於儲存每次更新後剩餘的us級別的時間變數:
static uint16 remusticks = 0;
用於儲存utc時間對應的秒數變數:
static uint16 timemsec = 0;
osaltimeupdate()更新系統時間,同時給時鐘與定時器用
1、獲取上次呼叫到現在的時間間隔,即這次需要更新的時間
tmp = ll_mcuprecisioncount();
2、計算需要更新的時間
ticks625us = tmp - previouslltimertick;
previouslltimertick = tmp;
3、轉化成ms單位
當ticks625us大於maxcalcticks時,一直執行:
while ( ticks625us > maxcalcticks )
ticks625us -= maxcalcticks;//剩下ticks625us數
elapsedmsec += maxcalcticks * 5 / 8;//轉換成ms值
remusticks += maxcalcticks * 5 % 8;//剩餘的us值
當ticks625us的值小於maxcalcticks時,則:
tmp = (ticks625us * 5) + remusticks;//計算上面剩下的時間(單位:ms)
elapsedmsec += tmp / 8;//計算最後的ms值
remusticks = tmp % 8;//剩餘的us值,留給下次呼叫使用
5、更新osal時鐘值與定時器值
osalclockupdate( elapsedmsec );
osaltimerupdate( elapsedmsec );
osalclockupdate()更新時鐘值
引數:elapsedmsec-需要新增的時間(ms)
1、計算新增後的總秒數
timemsec += elapsedmsec;
2、如果總秒數大於1000,則向分鐘進製
if ( timemsec >= 1000 )
osal_timeseconds += timemsec / 1000;
timemsec = timemsec % 1000;
osal_setclock()設定時鐘值
引數:newtime-新時間,如果是utc時間,需要轉換成ms單位
osal_timeseconds = newtime;
osal_getclock()獲取當前時間
直接返回utc時間變數osal_timeseconds:
return ( osal_timeseconds );
osal_convertutctime()將ms單位時間值轉換成utc時間值
引數:tm-要儲存的utc格式結構體變數
sectime-從2023年1月1日00:00:00時間開始累計的秒數
1、計算在總天數:
uint32 day = sectime % day;
2、計算utc時間的秒數:
tm->seconds = day % 60ul;
3、計算utc時間分鐘數:
tm->minutes = (day % 3600ul) / 60ul;
4、計算utc時間的小時數:
tm->hour = day / 3600ul;
5、計算utc時間的年份:
uint16 numdays = sectime / day;
tm->year = begyear;
while ( numdays >= yearlength( tm->year ) )
numdays -= yearlength( tm->year );
tm->year++;
6、計算utc時間的月份:
tm->month = 0;
while ( numdays >= monthlength( isleapyear( tm->year ), tm->month ) )
numdays -= monthlength( isleapyear( tm->year ), tm->month );
tm->month++;
7、計算utc時間的天數:
tm->day = numdays;
monthlength()計算月份的天數
引數:lpyr-1表示閏年,0表示非閏年
1、mon=1,即二月,需要根據是否為閏年判斷二月對應的天數。如果是閏年,則二月為28天,否則為29天。
if ( mon == 1 ) // feb
days = ( 28 + lpyr );
2、mon=0,2,4,6,7,9,11即一月、三月、五月、七月、八月、十月、十二月的天數為31天。
uint8 days = 31;
if ( mon > 6 ) // aug-dec
mon--;
3、mon=3,5,8,10即四月、六月、九月、十一月的天數為30天:
if ( mon & 1 )
days = 30;
osal_convertutcsecs()將utc時間轉換成秒
引數:tm-utc時間對應的結構體變數
1、計算utc時間的時分秒所對應的秒數:
seconds = (((tm->hour * 60ul) + tm->minutes) * 60ul) + tm->seconds;
2、計算utc時間當前年份已經過去的天數:
int8 month = tm->month;
while ( --month >= 0 )
days += monthlength( isleapyear( tm->year ), month );
3、計算utc時間之前年份的總天數:
uint16 year = tm->year;
while ( --year >= begyear )
days += yearlength( year );
4、計算utc時間所對應的總秒數:
seconds += (days * day);
utc時間 單位換算 UTC轉換本地時間
title utc轉換本地時間 author norains date friday 26 march 2010 environment windows xp windows ce 一般情況下,我們很少需要用到utc轉換為本地時間 因為如果僅僅是獲取本機的本地時間,我們完全可以不用如此麻煩,直接呼叫...
utc時間 單位換算 日期時間
使用time模組顯示當前日期和時間 開發乙個以多種格式顯示當前時間和日期的程式。轉換秒數為gmt時間。你要使用time模組中的asctime,它從計算機的內部時鐘讀取當前的日期和時間。在格林尼治時間內轉換秒數。你可以看到程式輸出的示例,如下所示。將天數 小時 分鐘轉換成秒 開發乙個程式,讀取使用者的...
時間單位換算
時間單位還有 毫秒 ms 微秒s 納秒 ns 皮秒 ps 飛秒 fs 阿秒 渺 秒1 s 10 3 ms 10 6 us 10 9 ns 10 12 ps 10 15 fs 10 18 阿秒 10 21 渺秒 10 43 蒲朗克常數 毫秒毫秒是一種較為微小的時間單位,是一秒的千分之一。典型照相機的 ...