BLE協議棧裏有已經封裝好的RTC時鐘,時鐘源可以是外部晶體振盪時鐘也可以是內部RC時鐘。
The32-kHzXOSC is designed to operate at 32.768kHz and provide a stable clock signal for systems requiring time accuracy.The 32-kHz RCOS runs at32.753kHz when calibrated.
外部晶振更加精準一些!
主要的函數在OSAL_ClockBLE.c中;
- void osalTimeUpdate( void )
- {
- uint16 tmp; //爲暫存變量,用於臨時存放時間值
- uint16 ticks625us; //用於存放timer2的溢出次數,每次溢出爲625us,也就是說ticks625us代表了625us的個數
- uint16 elapsedMSec = 0;//也是用來存放時間值的,只是它存放的值是上一次操作所保留下來的值,它最終存放的是時間的ms值
- // Get the free-running count of 625us timer ticks
- tmp = ll_McuPrecisionCount();//這個函數就是用來讀取timer2溢出次數的,溢出次數存放在T2MOVF2([23:16]),T2MOVF2([15:8]), T2MOVF0([7:0]), 一共有24bit
- if ( tmp != previousLLTimerTick )//判斷時間是否有變化(正常情況下,隨着程序的運行,tmp 這個值一直增大(16-bit))
- {
- // Calculate the elapsed ticks of the free-running timer.
- ticks625us = tmp - previousLLTimerTick;//當前的時間值減去上一次的值,也就是代碼再一次運行到這裏所消耗的時間(注意單位爲625us)
- // Store the LL Timer tick count for the next time through this function.
- previousLLTimerTick = tmp;//將當前值存儲起來,爲程序下一次運行到這裏作準備
- /*
- 下面紅色部分的代碼,都只是實現了一個功能,就是將ticks625us個625us 轉換成 elapsedMSec 個ms(ms的整數部分)和remUsTicks 個us(ms的小數部分),“ *5 / 8” 等價於 “ *625 / 1000”(分子分母同時擴大40倍),同理“ *5 % 8” 等價於 “*625 % 1000” 至於MAXCALCTICKS ,程序中有一下兩段註釋,可以幫助我們理解
- // (MAXCALCTICKS * 5) + (max remainder) must be <= (uint16 max),
- // so: (13105 * 5) + 7 <= 65535
- #define MAXCALCTICKS ((uint16)(13105))
- */
- /* It is necessary to loop to convert the usecs to msecs in increments so as
- * not to overflow the 16-bit variables.
- */
- while ( ticks625us > MAXCALCTICKS )//這個while是對溢出的操作
- {
- ticks625us -= MAXCALCTICKS;
- elapsedMSec += MAXCALCTICKS * 5 / 8;
- remUsTicks += MAXCALCTICKS * 5 % 8;
- }
- // update converted number with remaining ticks from loop and the
- // accumulated remainder from loop
- tmp = (ticks625us * 5) + remUsTicks;
- // Convert the 625 us ticks into milliseconds and a remainder
- elapsedMSec += tmp / 8;
- remUsTicks = tmp % 8;
- // Update OSAL Clock and Timers
- if ( elapsedMSec )//判斷時間是否到了1ms,如果等於或者超過1ms(elapsedMSec >= 1),則需要輪詢任務列表
- {
- osalClockUpdate( elapsedMSec );//更新osal操作系統的系統時間
- osalTimerUpdate( elapsedMSec );//這個函數和任務的輪詢調度有關,即和timeout有關
- }
- }
- }
當然還有設置時間函數(UTCTime是從2000年1月1日00:00:00到至今的秒數)
- /*********************************************************************
- * @fn osal_setClock
- *
- * @brief Set the new time. This will only set the seconds portion
- * of time and doesn't change the factional second counter.
- *
- * @param newTime - number of seconds since 0 hrs, 0 minutes,
- * 0 seconds, on the 1st of January 2000 UTC
- *
- * @return none
- */
- void osal_setClock( UTCTime newTime )
- {
- OSAL_timeSeconds = newTime;
- }
獲得當前時間函數:
- /*********************************************************************
- * @fn osal_getClock
- *
- * @brief Gets the current time. This will only return the seconds
- * portion of time and doesn't include the factional second
- * counter.
- *
- * @param none
- *
- * @return number of seconds since 0 hrs, 0 minutes, 0 seconds,
- * on the 1st of January 2000 UTC
- */
- UTCTime osal_getClock( void )
- {
- return ( OSAL_timeSeconds );
- }
將秒數轉換爲年月日時分秒格式儲存在結構體UTCTimeStruct(定義在OSAL_Clock.h)中
- /*********************************************************************
- * @fn osal_ConvertUTCTime
- *
- * @brief Converts UTCTime to UTCTimeStruct
- *
- * @param tm - pointer to breakdown struct
- *
- * @param secTime - number of seconds since 0 hrs, 0 minutes,
- * 0 seconds, on the 1st of January 2000 UTC
- *
- * @return none
- */
- void osal_ConvertUTCTime( UTCTimeStruct *tm, UTCTime secTime )
- {
- // calculate the time less than a day - hours, minutes, seconds
- {
- uint32 day = secTime % DAY;
- tm->seconds = day % 60UL;
- tm->minutes = (day % 3600UL) / 60UL;
- tm->hour = day / 3600UL;
- }
- // Fill in the calendar - day, month, year
- {
- uint16 numDays = secTime / DAY;
- tm->year = BEGYEAR;
- while ( numDays >= YearLength( tm->year ) )
- {
- numDays -= YearLength( tm->year );
- tm->year++;
- }
- tm->month = 0;
- while ( numDays >= monthLength( IsLeapYear( tm->year ), tm->month ) )
- {
- numDays -= monthLength( IsLeapYear( tm->year ), tm->month );
- tm->month++;
- }
- tm->day = numDays;
- }
- }
校準時間時將年月日時分秒格式轉換爲秒的函數;
- /*********************************************************************
- * @fn osal_ConvertUTCSecs
- *
- * @brief Converts a UTCTimeStruct to UTCTime
- *
- * @param tm - pointer to provided struct
- *
- * @return number of seconds since 00:00:00 on 01/01/2000 (UTC)
- */
- UTCTime osal_ConvertUTCSecs( UTCTimeStruct *tm )
- {
- uint32 seconds;
- /* Seconds for the partial day */
- seconds = (((tm->hour * 60UL) + tm->minutes) * 60UL) + tm->seconds;
- /* Account for previous complete days */
- {
- /* Start with complete days in current month */
- uint16 days = tm->day;
- /* Next, complete months in current year */
- {
- int8 month = tm->month;
- while ( --month >= 0 )
- {
- days += monthLength( IsLeapYear( tm->year ), month );
- }
- }
- /* Next, complete years before current year */
- {
- uint16 year = tm->year;
- while ( --year >= BEGYEAR )
- {
- days += YearLength( year );
- }
- }
- /* Add total seconds before partial day */
- seconds += (days * DAY);
- }
- return ( seconds );
- }
example:
- har tempbuf[10]={0};
- UTCTimeStruct *Ti;
- osalTimeUpdate();
- osal_ConvertUTCTime(Ti,osal_getClock());
- tempbuf[0]=(Ti->hour)/10+'0';
- tempbuf[1]=(Ti->hour)%10+'0';
- tempbuf[2]=(Ti->minutes)/10+'0';
- tempbuf[3]=(Ti->minutes)%10+'0';
- tempbuf[4]=(Ti->seconds)/10+'0';
- tempbuf[5]=(Ti->seconds)%10+'0';
- Uart0Send_String(tempbuf,10);// 將時分秒在串口打印
http://blog.csdn.net/xiaoleiacmer/article/details/42458351