算命网站建设开发网站后台栏目根据什么做的

当前位置: 首页 > news >正文

算命网站建设开发,网站后台栏目根据什么做的,苏州园区一站式服务中心,网站服务器响应时间过长1 简介 RTC实时时钟顾名思义作用和墙上挂的时钟差不多#xff0c;都是用于记录时间和日历#xff0c;同时也有闹钟的功能。从硬件实现上来说#xff0c;其实它就是一个特殊的计时器#xff0c;它内部有一个32位的寄存器用于计时。RTC在低功耗应用中可以说相当重要#xf…1 简介 RTC实时时钟顾名思义作用和墙上挂的时钟差不多都是用于记录时间和日历同时也有闹钟的功能。从硬件实现上来说其实它就是一个特殊的计时器它内部有一个32位的寄存器用于计时。RTC在低功耗应用中可以说相当重要因为在使用外部低速晶振的条件下它在所有的低功耗模式下都可以工作这使得RTC很适合实现芯片的低功耗唤醒。下面是RTC的框图。 咋一看RTC的内部还挺复杂的。 2 硬件时钟 先看时钟RTC的时钟可以选择内部32kHz晶振、外部高速晶振分频或外部低速时钟一般都是使用外部32.768kHz低速晶振来驱动。时钟会先经过数字平滑校准器用户可以配置进行进行校准接着进入7位异步预分频器这个分频器一般设置最大分频即128分频因为这个分频器的值越大RTC的功耗会越低然后时钟进入一个粗校准器需要注意的是粗校准和前面的数字平滑校准同时只能开启其中一个之后时钟进入一个15位的同步预分频器这里一般设置为256分频这样就刚好能分出1Hz的频率也就是每秒更新一次RTC。 当然上面介绍的是最常用的RTC时钟配置根据不同的功能实现还可以有其他的配置。 3 功能 3.1 日历 RTC的日历功能依赖3个寄存器——RTC_DATE日期寄存器、RTC_TIME时间寄存器和RTC_SS亚秒寄存器。日期寄存器和时间寄存器保存我们熟知的年月日时分秒数据是以BCD码的方式保存的。亚秒寄存器用于保存毫秒级的时钟数据。 上面的3个寄存器RTC内部会有对应的影子寄存器在实际应用中我们一般读取它们对应的影子寄存器。每2个RTC周期影子寄存器才会更新一次虽说影子寄存器的值与实际值会有延迟但它能保证读出来的值是一致的。如果我们读的是寄存器的实际值那么有可能在读的过程中RTC对寄存器进行了更新导致我们读到的值前后不一致。 在读取影子寄存器的值时我们要等待状态寄存器的RSYNF位置1才能读取此时寄存器的值才是稳定的。另外需注意的是在深度睡眠和待机模式下影子寄存器的值是不更新的因此退出该模式时需要清除RSYNF位。 3.2 自动唤醒 在低功耗应用中RTC的自动唤醒功能可以说是必用到的RTC内部使用一个16位的向下计数的计数器实现自动唤醒。计数器的驱动时钟可以选择RTC时钟的2/4/8/16分频或内部时钟一般会选择内部时钟即ck_spre。如果ck_spre为1Hz的话唤醒的时间可以设置在1秒到36小时之间。 当计数器到0时WTF标志位置1唤醒计数器自动重载RTC_WUT的值。当WTF置1后必须软件清除该标志。如果使能了中断功能并且芯片处于低功耗模式唤醒中断会使芯片退出低功耗模式。 3.3 闹钟 RTC内部有2个可配置的闹钟它与我们日常熟知的闹钟原理是差不多的通过设置闹钟日期寄存器和闹钟亚秒寄存器来配置唤醒时刻当到达指定时刻时闹钟会产生中断该中断也能将芯片从低功耗模式中唤醒。 3.4 时间戳功能 时间戳功能由RTC_TS管脚输入通过配置TSEN位来使能。当RTC_TS管脚检测到时间戳事件发生时会将日历的值保存在时间戳寄存器中RTC_DTS / RTC_TTS / RTC_SSTS同时时间戳标志TSF也将由硬件置1。如果时间戳中断使能被启用TSIE时间戳事件会产生一个中断该中断也能将芯片从低功耗模式中唤醒。 4 例程 4.1 日历 这个例程主要是配置RTC让它正常工作然后定时读取日历值。 先看main函数。 #include gd32f4xx.h #include systick.h #include debug.h #include rtc.hstruct tm time_struct {.tm_year 2024,.tm_mon 1,.tm_mday 1,.tm_hour 0,.tm_min 0,.tm_sec 0,.tm_wday RTC_MONDAY };int main(void) {systick_config();debug_init();rtc_config(time_struct);printf(rtc demo\r\n);while(1){struct tm ts {0};rtc_get_time(ts);printf(%02d-%02d-%02d %02d:%02d:%02d\r\n, ts.tm_year, ts.tm_mon, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec);delay_1ms(1000);} }main函数调用rtc_config函数初始化RTC传入struct tm结构体这个结构体是time.h里面定义的是系统库自带的它的定义如下。 struct tm {int tm_sec; /* seconds after the minute, 0 to 60(0 - 60 allows for the occasional leap second) /int tm_min; / minutes after the hour, 0 to 59 /int tm_hour; / hours since midnight, 0 to 23 /int tm_mday; / day of the month, 1 to 31 /int tm_mon; / months since January, 0 to 11 /int tm_year; / years since 1900 /int tm_wday; / days since Sunday, 0 to 6 /int tm_yday; / days since January 1, 0 to 365 /int tm_isdst; / Daylight Savings Time flag /union { / ABI-required extra fields, in a variety of types */struct {int __extra_1, __extra_2;};struct {long __extra_1_long, extra_2_long;};struct {char *extra_1_cptr, *extra_2_cptr;};struct {void *extra_1_vptr, *__extra_2_vptr;};}; };初始化函数的内部如下。 void rtc_config(struct tm t) {/ 使能PMU时钟 /rcu_periph_clock_enable(RCU_PMU);/ 使能RTC寄存器访问 /pmu_backup_write_enable();/ 使用外部低速晶振 /rcu_osci_on(RCU_LXTAL);rcu_osci_stab_wait(RCU_LXTAL);rcu_rtc_clock_config(RCU_RTCSRC_LXTAL);rcu_periph_clock_enable(RCU_RTC);rtc_register_sync_wait();/ 初始化时钟 */rtc_set_time(t); }因为RTC使用的是VBAT供电域默认配置下该供电域的寄存器是写禁止的因此需要调用pmu_backup_write_enable函数使能写操作。下面就是配置外部低速时钟然后调用rtc_register_sync_wait等待影子寄存器同步数据。初始化完毕就可以配置日历了。 void rtc_set_time(const struct tm time_struct) {rtc_parameter_struct rtc_initpara {0};/ RTC时钟频率 32.768kHz / (255 1) / (127 1) 1Hz */rtc_initpara.factor_asyn 127;rtc_initpara.factor_syn 255;rtc_initpara.display_format RTC_24HOUR;rtc_initpara.year BIN_TO_BCD(time_struct-tm_year - 1970);rtc_initpara.month BIN_TO_BCD(time_struct-tm_mon);rtc_initpara.date BIN_TO_BCD(time_struct-tm_mday);rtc_initpara.hour BIN_TO_BCD(time_struct-tm_hour);rtc_initpara.minute BIN_TO_BCD(time_struct-tm_min);rtc_initpara.second BIN_TO_BCD(time_struct-tm_sec);rtc_initpara.day_of_week time_struct-tm_wday;rtc_init(rtc_initpara); }配置日历使用rtc_init函数按需要填充结构体即可factor_asyn成员是异步分频器的值factor_syn是同步分频器的值。另外需要注意日历寄存器内的值是以BCD码形式保存因此需要写一个简单的转换宏像下面。 #define BIN_TO_BCD(x) ((((x) / 10) 4) ((x) % 10)) 还有就是RTC的寄存器年份内容只能保存2个数字即只能计算99年所以根据需要填合适的起始值进去像我这里就是起始年份定为1970年把当前年份减去1970转换为BCD码后填进寄存器。 RTC运行时可以随时调用rtc_current_time_get获取当前时间。 void rtc_get_time(struct tm *time_struct) {rtc_parameter_struct rtc_initpara {0};rtc_current_time_get(rtc_initpara);time_struct-tm_year BCD_TO_BIN(rtc_initpara.year) 1970;time_struct-tm_mon BCD_TO_BIN(rtc_initpara.month);time_struct-tm_mday BCD_TO_BIN(rtc_initpara.date);time_struct-tm_hour BCD_TO_BIN(rtc_initpara.hour);time_struct-tm_min BCD_TO_BIN(rtc_initpara.minute);time_struct-tm_sec BCD_TO_BIN(rtc_initpara.second);time_struct-tm_wday rtc_initpara.day_of_week; }取值的时候也是要将BCD码转成对应的数字用下面的宏。 #define BCD_TO_BIN(x) (10 * ((x) 4) ((x) 0x0F)) 下面是demo的输出。