novoton-RTC使用

 

RTC时钟

上电之后,初始化完成,只要不断电,它就一直自动记录当前时间。任何时候都可以从它内部的寄存器读出当前的时间和日期。

一般32K晶振都会有一定的误差。如果希望RTC非常准,32K晶振就要进行补偿。新唐的RTC一般都带频率补偿寄存器。补偿值需要软件自行填入。一般一批32K晶振误差都差不多,使用频率计数器测一下晶振,然后将补偿值填入RTC就可以了。补偿值具体应该填多少,TRM(技术参考手册)里面RTC部分介绍的很详细,这里就不再赘述。

RTC除了做时钟,还能产生Tick中断和Alarm中断,并能唤醒系统。

 

使能外部32.768KHZ晶振:

void CLK_EnableXtalRC(uint32_t u32ClkMask);

* - \ref CLK_PWRCTL_HXTEN_Msk
* - \ref CLK_PWRCTL_LXTEN_Msk
* - \ref CLK_PWRCTL_HIRCEN_Msk
* - \ref CLK_PWRCTL_LIRCEN_Msk

等待时钟稳定:

uint32_t CLK_WaitClockReady(uint32_t u32ClkMask);

* - \ref CLK_STATUS_HXTSTB_Msk
* - \ref CLK_STATUS_LXTSTB_Msk
* - \ref CLK_STATUS_HIRCSTB_Msk
* - \ref CLK_STATUS_LIRCSTB_Msk
* - \ref CLK_STATUS_PLLSTB_Msk
* @retval 0 clock is not stable
* @retval 1 clock is stable

 设置RTC时钟源:

void CLK_SetModuleClock(uint32_t u32ModuleIdx, uint32_t u32ClkSrc, uint32_t u32ClkDiv);

* |Module index      |    Clock source          |   Divider   |
* |\ref RTC_MODULE    |\ref CLK_CLKSEL3_RTCSEL_LXT     |     x    |
* |\ref RTC_MODULE    |\ ref CLK_CLKSEL3_RTCSEL_LIRC   |     x    |

使能RTC时钟源:

void CLK_EnableModuleClock(uint32_t u32ModuleIdx);

  *             - \ref RTC_MODULE

选择时钟源+使能时钟:::
/* 使能RTC的时钟 */ CLK->APBCLK |= CLK_APBCLK_RTC_EN_Msk;

开启并初始化时钟值:

void RTC_Open(S_RTC_TIME_DATA_T *sPt);

* @param[in] sPt Specify the time property and current date and time. It includes: \n
* u32Year: Year value, range between 2000 ~ 2099. \n
* u32Month: Month value, range between 1 ~ 12. \n
* u32Day: Day value, range between 1 ~ 31. \n
* u32DayOfWeek: Day of the week. [RTC_SUNDAY / RTC_MONDAY / RTC_TUESDAY /
* RTC_WEDNESDAY / RTC_THURSDAY / RTC_FRIDAY /
* RTC_SATURDAY] \n
* u32Hour: Hour value, range between 0 ~ 23. \n
* u32Minute: Minute value, range between 0 ~ 59. \n
* u32Second: Second value, range between 0 ~ 59. \n
* u32TimeScale: [RTC_CLOCK_12 / RTC_CLOCK_24] \n
* u8AmPm: [RTC_AM / RTC_PM] \n

开启TICK中断:

void RTC_SetTickPeriod(uint32_t u32TickSelection);

* @param[in] u32TickSelection It is used to set the RTC tick period time for Periodic Time Tick request. \n
* It consists of: \n
* RTC_TICK_1_SEC: Time tick is 1 second \n
* RTC_TICK_1_2_SEC: Time tick is 1/2 second \n
* RTC_TICK_1_4_SEC: Time tick is 1/4 second \n
* RTC_TICK_1_8_SEC: Time tick is 1/8 second \n
* RTC_TICK_1_16_SEC: Time tick is 1/16 second \n
* RTC_TICK_1_32_SEC: Time tick is 1/32 second \n
* RTC_TICK_1_64_SEC: Time tick is 1/64 second \n
* RTC_TICK_1_128_SEC: Time tick is 1/128 second

 void RTC_EnableInt(uint32_t u32IntFlagMask);

* @param[in] u32IntFlagMask Specify the interrupt source. It consists of: \n
* RTC_INTEN_ALMIEN_Msk: Alarm interrupt \n
* RTC_INTEN_TICKIEN_Msk: Tick interrupt \n
* RTC_INTEN_SNPDIEN_Msk: Snooper Pin Event Detection interrupt \n

开启总中断:

NVIC_EnableIRQ(RTC_IRQn);

 

贴上代码(遇到的小问题:没有解锁保护寄存器时,LXT是启动不了的。)

 

void rtc_init(void)
{
    S_RTC_TIME_DATA_T mDataTime;
    
    // 解锁保护寄存器
    SYS_UnlockReg();
    
    CLK_EnableXtalRC(CLK_PWRCTL_LXTEN_Msk);
    CLK_WaitClockReady(CLK_STATUS_LXTSTB_Msk);
    CLK_SetModuleClock(RTC_MODULE,CLK_CLKSEL3_RTCSEL_LXT,1);
    CLK_EnableModuleClock(RTC_MODULE);
    
    // 加锁保护寄存器
    SYS_LockReg();
    
    mDataTime.u32Year = 2018;
    mDataTime.u32Month = 5;
    mDataTime.u32Day = 24;
    mDataTime.u32DayOfWeek = RTC_THURSDAY;
    mDataTime.u32Hour = 23;
    mDataTime.u32Minute = 0;
    mDataTime.u32Second = 0;
    mDataTime.u32TimeScale = RTC_CLOCK_24;
    
    RTC_Open(&mDataTime);
    
    RTC_SetTickPeriod(RTC_TICK_1_SEC);
    
    RTC_EnableInt(RTC_INTEN_TICKIEN_Msk);
    
    NVIC_EnableIRQ(RTC_IRQn);

}

 

void RTC_IRQHandler(void)
{
    
    S_RTC_TIME_DATA_T mDataTime;
    
    if( RTC_GET_TICK_INT_FLAG() )
    {
        RTC_CLEAR_TICK_INT_FLAG();
        
        RTC_GetDateAndTime(&mDataTime);
        
        printf("Time:%d/%02d/%02d %02d:%02d:%02d\n",mDataTime.u32Year,mDataTime.u32Month,mDataTime.u32Day,mDataTime.u32Hour,mDataTime.u32Minute,mDataTime.u32Second);
    }

}

 

posted @ 2018-05-24 21:48  LLWDream  阅读(391)  评论(0编辑  收藏  举报