APT32 单片机RTC功能强大, 在所有低功耗模式下均可独立运行,并支持系统唤醒。实时时钟计数器(RTC)为一个独立的 BCD 编码计数器,提供实时的日历和时间信息,包括星期,年、月、日和小时、分钟、秒。支持可编程的闹钟中断。RTC 具有产生周期性的中断事件的能力。RTC 一旦初始化成功并开始工作,任何复位信号均不能影响其工作,除非重新上电。

RTC 的基本特性:

1) 支持万年历功能,自动闰年判定。计时器包括小时、分钟、秒和微秒,BCD 格式计数。


(资料图片)

2) 二十四小时或者十二小时制可选,支持星期判断。

3) 支持多个时钟源,包括外部晶振、内部低速振荡器和内部主振荡器。

4) 支持低功耗唤醒功能

5) 两个可编程闹钟。

6) 支持周期事件触发。

RTC 的系统框图:

由于 RTC 工作时钟与 APB 总线时钟(PCLK)为异步时钟,对 RTC 的读写操作均需要通过两个异步时钟同步

后进行。任何对 RTC 控制器的操作不会立即产生作用,可以通过对 CR[UPD_BSY]控制位进行查询,以获得更新状

态。UPD_BSY 控制位在写请求发生时,会立即置位,直到更新结束后才会自动清除。在 RTC 未初始化前,对寄存

器的更新值都保存在缓冲中,所以只需要在初始化时,查询 UPD_BSY 即可。当 RTC 已经初始化完成后(RTC 已经

开始工作),任何对寄存器的修改,例如 CR 和 ALRAR,都需要查询 UPD_BSY,以保证更新成功。

对 RTC 的初始化,包括如下操作。

1) 设置保护寄存器关闭

2) 设置 TIMR、DATR、ALRAR、ALRBR

3) 设置 CCR,包括时钟选择和分频选择

4) 使能 RTC 时钟(设置 CCR[CLKEN]),等待 RTC 工作时钟稳定(通过 CCR[RTCCK_ST]控制位查询)。

5) 设置 CR 寄存器,以设置时间格式或闹钟使能等配置。同时清除 INIT 位,启动初始化。

6) 回读 INIT 状态位,确认 RTC 工作

void rtc_set_time_demo(void)

{

csi_rtc_config_t tRtcConfig;

csi_rtc_time_t tRtcTime,tRtcTimeRdbk;

uint32_t wSec = 0;

csi_pin_set_mux(PA03, PA03_OSC_XI);//设置PA0.3为SXIN,如果使用外部主晶振作为RTC时钟源,必须先对管脚进行配置

csi_pin_set_mux(PA04, PA04_OSC_XO);         //设置PA0.4为SXOUT,如果使用外部主晶振作为RTC时钟源,必须先对管脚进行配置

csi_pin_set_mux(PA01,PA01_OSC_SXI);         //设置PA0.1为XIN,如果使用外部副晶振作为RTC时钟源,必须先对管脚进行配置

csi_pin_set_mux(PA02,PA02_OSC_SXO);         //设置PA0.2为XOUT,如果使用外部副晶振作为RTC时钟源,必须先对管脚进行配置

tRtcConfig.byClkSrc = RTC_CLKSRC_ESOSC;//外部副晶振作为RTC时钟源

tRtcConfig.byFmt = RTC_24FMT;//选择时间模式

csi_rtc_init(RTC, &tRtcConfig);//初始化设置

tRtcTime.iYear = 22;

tRtcTime.iMon  = 2;

tRtcTime.iMday = 14;

//tRtcTime.iWday = 1;                       //星期1-7

tRtcTime.iPm   = RTC_AM;// AM or PM

tRtcTime.iHour = 9;//如果是12小时制,回读到的hour范围为1->12;如果是24小时制,回读到的hour范围是0->23

tRtcTime.iHour = 9;//如果是12小时制,回读到的hour范围为1->12;如果是24小时制,回读到的hour范围是0->23

tRtcTime.iMin  = 50;

tRtcTime.iSec  = 59;

csi_rtc_set_time(RTC, &tRtcTime);//设置时间

csi_rtc_start(RTC);//RTC开始计时

csi_rtc_change_fmt(RTC, RTC_12FMT);//修改时间模式为12小时制

tRtcTime.iYear = 22;

tRtcTime.iMon  = 2;

tRtcTime.iMday = 14;

//tRtcTime.iWday = 1;                       //星期1-7

tRtcTime.iPm   = RTC_AM;// AM or PM

tRtcTime.iHour = 11;

tRtcTime.iHour = 9;

tRtcTime.iMin  = 59;

tRtcTime.iSec  = 56;

csi_rtc_set_time(RTC, &tRtcTime);//修改时间以后需要重新start rtc

csi_rtc_start(RTC);

csi_rtc_get_time(RTC,  &tRtcTimeRdbk);//回读当前时间

my_printf("12FMT: %d:%d:%d\n", tRtcTimeRdbk.iHour, tRtcTimeRdbk.iMin, tRtcTimeRdbk.iSec);

csi_rtc_change_fmt(RTC, RTC_24FMT);//修改时间模式为24小时制

csi_rtc_get_time(RTC,  &tRtcTimeRdbk);//回读当前时间

my_printf("24FMT: %d:%d:%d\n", tRtcTimeRdbk.iHour, tRtcTimeRdbk.iMin, tRtcTimeRdbk.iSec);

csi_rtc_change_fmt(RTC, RTC_12FMT);//修改时间模式为12小时制

while(1)

{

csi_rtc_get_time(RTC,  &tRtcTimeRdbk);

if(wSec != tRtcTimeRdbk.iSec ) 

{

wSec = tRtcTimeRdbk.iSec;

my_printf("%d:%d:%d pm= %d\n", tRtcTimeRdbk.iHour, tRtcTimeRdbk.iMin, tRtcTimeRdbk.iSec, tRtcTimeRdbk.iPm);

}

}

}

经过2小时测试,RTC精度稳定可好

推荐内容