nrf51822 --- 软件模拟 万年历

1.目的

    nrf51822用定时器模拟一个万年历

2.分析

   

3.平台:

协议栈版本:SDK10.0.0

编译软件:keil 5.14

硬件平台:nrf51822最小系统

例子:SDK 10.0.0\examples\ble_peripheral\ble_app_uart\pca10028\s110\arm4

4.步骤上传图片

/********************************************************************************
	* @file     calender.c
	* @author   Depth
    * @version  V1.0.0
	* @brief    calender module based on app timer
******************************************************************************/
#include "calender.h"


/*********************************************************************
 * MACROS
 */

#define	YearLength(yr)	(IsLeapYear(yr) ? 366 : 365)
//日历变量

UTCTimeStruct Time_iOS = {8,59,15,9,6,2015};
UTCTimeStruct Time_Current;

/*********************************************************************
 * CONSTANTS
 */

// (MAXCALCTICKS * 5) + (max remainder) must be <= (uint16_t max),
// so: (13105 * 5) + 7 <= 65535
#define MAXCALCTICKS  ((uint16_t)(13105))

#define	BEGYEAR	        1970     // UTC started at 00:00:00 January 1, 2000

#define	DAY             86400UL  // 24 hours * 60 minutes * 60 seconds


/*********************************************************************
 * EXTERNAL FUNCTIONS
 */
extern uint16_t ll_McuPrecisionCount(void);

/*********************************************************************
 * LOCAL VARIABLES
 */
//static uint16_t previousLLTimerTick = 0;
//static uint16_t remUsTicks = 0;
//static uint16_t timeMSec = 0;

// number of seconds since   2010.1.1.  00:00:00
UTCTime TimeSeconds = 0;

/*********************************************************************
 * LOCAL FUNCTION PROTOTYPES
 */
static uint8_t monthLength( uint8_t lpyr, uint8_t mon );

/*********************************************************************
 * FUNCTIONS
 */

/*********************************************************************
 * @fn      Set_Clock
 *
 * @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 Set_Clock( UTCTime newTime )
{
  TimeSeconds = newTime;
}

/*********************************************************************
 * @fn      Get_Clock
 *
 * @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 Get_Clock( void )
{
  return ( TimeSeconds );
}

/*********************************************************************
 * @fn      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
 */
uint16_t numDays =0;
void ConvertUTCTime( UTCTimeStruct *tm, UTCTime secTime )
{
  // calculate the time less than a day - hours, minutes, seconds
  {
    uint32_t day = secTime % DAY;  // 求出最后一天的剩余秒数,(除去整数的天数之后的剩余秒数)
    tm->seconds = day % 60UL;      // 求出最后一分钟的剩余秒数 (最后一天的剩余秒数对60求余)
    tm->minutes = (day % 3600UL) / 60UL;  //求出 最后一小时剩余的整分钟数
    tm->hour = day / 3600UL;       //求最后一天的整小时数
  }

  // Fill in the calendar - day, month, year
  {
     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->month++;
    tm->day = numDays;
		tm->day++;
  }
}

/*********************************************************************
 * @fn      monthLength
 *
 * @param   lpyr - 1 for leap year, 0 if not
 *
 * @param   mon - 0 - 11 (jan - dec)
 *
 * @return  number of days in specified month
 */
static uint8_t monthLength( uint8_t lpyr, uint8_t mon )
{
  uint8_t days = 31;

  if ( mon == 1 ) // feb
  {
    days = ( 28 + lpyr );
  }
  else
  {
    if ( mon > 6 ) // aug-dec
    {
      mon--;
    }

    if ( mon & 1 )
    {
      days = 30;
    }
  }

  return ( days );
}

/*********************************************************************
 * @fn      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 ConvertUTCSecs( UTCTimeStruct *tm )
{
  uint32_t 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_t days = tm->day;

    /* Next, complete months in current year */
    {
      int8_t month = tm->month - 1;//
      while ( --month >= 0 )
      {
        days += monthLength( IsLeapYear( tm->year ), month );
      }
    }

    /* Next, complete years before current year */
    {
      uint16_t year = tm->year;
      while ( --year >= BEGYEAR )
      {
        days += YearLength( year );
      }
    }

    /* Add total seconds before partial day */
    seconds += (days * DAY);
  }

  return ( seconds );
}
/*********************************************************************
 * @fn      CaculateWeekday
 *
 * @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)
 */
uint8_t CaculateWeekday(UTCTimeStruct *ptime)
{ 
	  // ¸ù¾ÝÈÕÆÚÊý¼ÆËãÐÇÆÚÊý
		uint16_t year   = ptime->year ;
	
		uint8_t  mounth = ptime->month;
	
		uint8_t  day    = ptime->day + 1;
	
		uint8_t  week;
	
		if(mounth==1 || mounth==2) { mounth += 12;  year--; }  
		week = (day + 2*mounth + 3*(mounth+1)/5 + year + year/4 - year/100 + year/400)%7; 
		if(week == 0)  week = 7;
		return (uint8_t)week;
}

#include "nrf51.h"
#include "nrf_gpio.h"
#include "rtc.h"
#include "app_scheduler.h"
#include "ble_gatts.h"
#include "app_error.h"
#include "nrf_gpio.h"
//#include "power_manger.h"
#include 
#include "calender.h"
#include "app_timer.h"
#include 
#include 
#include "nordic_common.h"
#include "nrf.h"
#include "nrf_gpio.h"
#include "nrf51_bitfields.h"
#include "app_error.h"
#include "calender.h"


/**********************************************************
注册一个1s的时间用于RTC
********************************************************/
#define APP_TIMER_PRESCALER 0
//wall clock id
app_timer_id_t                              SecondID;        //广播的时候闪烁蓝灯
#define ONESECOND_INTERVAL                   APP_TIMER_TICKS(1000, APP_TIMER_PRESCALER) // 广播时间设置
static void SECONED_ADD_clock(void * p_context)  //采集皮肤数据灯闪烁指示
{
    (void)p_context;
	  UTCTimeStruct utc;
     TimeSeconds++ ;
     //一天有86400s   一个小时 3600s
	  ConvertUTCTime( &utc, Get_Clock() );  // ??????
    if(utc.minutes == 0 && utc.seconds == 0 && utc.year !=0)
    { 
			 //每个小时
		   if(utc.hour == 0)
			 { 
				  //每一天
				  if(utc.day == 0)
					{
						//每一个月
					}
			 }
		}			
		
}
/**************************************************************************
* system clock init
***************************************************************************/
void SECOND_clock_init(void)
{
	  uint32_t err_code;
	  UTCTimeStruct utc;  
		utc.seconds = 0x00;
		utc.minutes = 0x00;
		utc.hour    = 0x00;
		utc.day     = 0x00; //CC2540 ???? 0 -30
		utc.month   = 0x00; //CC2540 ???? 0 -11  
		utc.year    = 2000;
		Set_Clock( ConvertUTCSecs( &utc ) );
                
    err_code = app_timer_create(&SecondID, APP_TIMER_MODE_REPEATED, SECONED_ADD_clock); //广播事件
    APP_ERROR_CHECK(err_code);
 
	
    err_code = app_timer_start(SecondID, ONESECOND_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
	
}

SECOND_clock_init();//初始化后,系统每1s,TimeSeconds加一

ConvertUTCTime( &utc, Get_Clock() );  // 获取当前时间

CaculateWeekday(); //可以获得当前的星期几


 
 

你可能感兴趣的:(nordic,nrf51822,蓝牙4.0)