当前位置:网站首页 > 编程语言 > 正文

时钟配置代码(时钟配置代码是什么)



代码分析

RTC实验配置相关宏定义

在这个RTC实验中的bsp_rtc.h文件中添加了一些宏定义用于切换工程的配置,见 。

以上代码定义的宏介绍如下:

关于这些宏的作用,在后面的C源代码中都会有体现。

初始化RTC

在本工程中,我们编写了RTC_Configuration函数对RTC进行初始化,见 。

在这个初始化函数里,分成了使用LSE和LSI的初始化配置,这两种配置的初始化过程类似,都直接调用了前面介绍的各种RTC相关的库函数

这个初始化的流程如下:使用RCC_APB1PeriphClockCmd使能PWR和BKP区域(即备份域)的时钟系统,使用PWR_BackupAccessCmd设置允许对BKP区域的访问,使能LSE时钟或LSI时钟,选择LSE或LSI作为RTC的时钟源并使能RTC时钟,利用库函数RTC_WaitFor Synchro对备份域和APB进行同步,用RTC_ITConfig使能秒中断,使用RTC_SetPrescaler分频配置把RTC时钟频率设置为1Hz。那么RTC每个时钟周期都会产生一次中断对RTC的每一个初始化参数都是使用相应的库函数来配置的。

经过这样的配置后,RTC每秒产生一次中断事件,实验中在中断设置标志位以便更新时间。

时间管理结构体

RTC初始化完成后可以直接往它的计数器写入时间戳,但是时间戳对用户不友好,不方便配置和显示时间, 在本工程中,使用bsp_date.h文件的rtc_time结构体来管理时间, 见 。

这个类型的结构体具有时、分、秒、日、月、年及星期这7个成员。当需要给RTC的计时器重新配置或显示时间时,使用这种容易接受的时间表示方式。

在配置RTC时,使用这种类型的变量保存用户输入的时间,然后利用函数由该时间求出对应的UNIX时间戳,写入RTC的计数器;RTC正常运行后, 需要输出时间时,利用函数通过RTC的计数器获取UNIX时间戳,转化成这种友好的时间表示方式保存到变量输出。

其实在C语言标准库ANSI C中,也具有类似这样的结构体struct tm ,位于标准的time.h文件中, 而具有以上功能的转化函数则为mktime和localtime,它们分别把tm格式的时间转化成时间戳和用时间戳转化成tm格式。 而在本实验中直接使用了开源的万年历算法源码,便于修改和学习。

时间格式转换

在本实验中,tm格式转时间戳使用mktimev函数,时间戳转tm格式使用to_tm函数,这两个函数都定义在bsp_date.c文件中, 见 。

关于日期计算的细节此处不作详细分析,其原理是以1970年1月1日0时0分0秒为计时基点,对日期和以秒数表示时间戳进行互相转化,转化重点在于闰年的计算。

这两个函数都是以格林威治时间(GMT)时区来计算的,在调用这些函数时我们会对输入参数加入时区偏移的运算,进行调整。

配置时间

有了以上的准备,接下来学习一下Time_Adjust函数,见

Time_Adjust函数用于配置时间,它先调用前面的RTC_Configuration初始化RTC,接着调用库函数RTC_SetCounter向RTC计数器写入要设置时间的时间戳值, 而时间戳的值则使用mktimev函数通过输入参数tm来计算,计算后还与宏TIME_ZOOM运算,计算时区偏移值。此处的输入参数tm是北京时间, 所以“mktimev(tm)-TIME_ZOOM”计算后写入到RTC计数器的是格林威治时区的标准UNIX时间戳。

检查并配置RTC

上面的Time_Adjust函数直接把参数写入到RTC中修改配置,但在芯片每次上电时,并不希望每次都修改系统时间, 所以我们增加了RTC_CheckAndConfig函数用于检查是否需要向RTC写入新的配置,见。

在本函数中,会检测备份域寄存器RTC_BKP_DRX内的值是否等于RTC_BKP_DATA而分成两个分支。

若不等,说明之前没有配置RTC所以直接调用Time_Adjust函数初始化RTC并写入时间戳进行计时,配置完成后向备份域寄存器RTC_BKP_DRX写入值RTC_BKP_DATA作为标志, 这样该标志就可以指示RTC的配置情况了,因为备份域不掉电时,RTC和该寄存器的值都会保存完好,而如果备份域掉电,那么RTC配置和该标志都会一同丢失;

若本函数的标志判断相等,进入else分支,不再调用Time_Adjust函数初始化RTC,而只是使用RTC_WaitForSynchro和RTC_ITConfig同步RTC域和APB以及使能中断, 以便获取时间。如果使用的是LSI时钟,还需要使能LSI时钟,RTC才会正常运行,这是因为当主电源掉电和备份域的情况下,LSI会关闭,而LSE则会正常运行,驱动RTC计时。

转换并输出时间

RTC正常运行后,可以使用Time_Display函数转换时间格式并输出到串口及液晶屏, 见 。

本函数的核心部分已加粗显示,主要是使用to_tm把时间戳转换成日常生活中使用的时间格式,to_tm以BJ_TimeVar作为输入参数, 而BJ_TimeVar对时间戳变量Time_Var进行了时区偏移,也就是说调用Time_Display函数时,以RTC计数器的值作为TimeVar作为输入参数即可, 最终会输出北京时间。

利用to_tm转换格式后,调用bsp_calendar.c文件中的日历计算函数,求出星期、农历、生肖等内容,然后使用串口和液晶屏显示出来。

中断服务函数

一般来说,上面的Time_Display时间显示每秒中更新一次,而根据前面的配置,RTC每秒会进入一次中断, 本实验中的RTC中断服务函数见 。

RTC的秒中断服务函数只是简单地对全局变量TimeDisplay置1,在main函数的while循环中会检测这个标志,当标志为1时, 就调用Time_Display函数显示一次时间,达到每秒钟更新当前时间的效果。

main函数

main函数的流程非常清晰,初始化了液晶、串口等外设后,调用RTC_CheckAndConfig函数初始化RTC,若RTC是第一次初始化,就使用变量systmtime中的默认时间配置, 若之前已配置好RTC,那么RTC_CheckAndConfig函数仅同步时钟系统,便于获取实时时间。在while循环里检查中断设置的TimeDisplay是否置1, 若置1了就调用Time_Display函数,它的输入参数是库函数RTC_GetCounter的返回值,也就是RTC计数器里的时间戳, Time_Display函数把该时间戳转化成北京时间显示到串口和液晶上。

使用串口配置时间

在main函数的44-54行,是一个按键检测分支,当检测到开发板上的KEY1被按下时,会调用Time_Regulate_Get函数通过串口获取配置时间, 然后把获取得的时间输入到Time_Adjust函数把该时间写入到RTC计数器中,更新配置, Time_Regulate_Get函数内容见 。

Time_Regulate_Get函数的本质是利用重定向到串口的C标准数据流输入函数scanf获取用户输入,若获取得的数据符合范围, 则赋值到tm结构体中,在main函数中再调用Time_Adjust函数把tm存储的时间写入到RTC计数器中。

使用串口配置时间的注意事项到此这篇时钟配置代码(时钟配置代码是什么)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • npp是什么材质(nps是什么材料)2025-05-08 09:54:07
  • 认证号码是什么(认证号码是什么东西)2025-05-08 09:54:07
  • 群晖admin密码(群晖 admin 密码)2025-05-08 09:54:07
  • win32怎么用(win32ole)2025-05-08 09:54:07
  • 操作系统基本操作文档(操作系统的基本操作)2025-05-08 09:54:07
  • u盘制作工具纯净版(u盘制作工具纯净版怎么用)2025-05-08 09:54:07
  • 字符转码方法(字符转码方法有几种)2025-05-08 09:54:07
  • m301h(m301H卡刷固件)2025-05-08 09:54:07
  • libglesv2.dll丢失(libpng15.dll丢失)2025-05-08 09:54:07
  • ipv6单播地址有(ipv6全球单播地址网关)2025-05-08 09:54:07
  • 全屏图片