历史上的今天
今天是:2024年12月29日(星期日)
2021年12月29日 | STM32F103单片机RTC实时时钟的使用
2021-12-29 来源:eefocus
实时时钟是一个独立的定时器。RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。
RTC模块和时钟配置系统(RCC_BDCR寄存器)处于后备区域,即在系统复位或从待机模式唤醒后,RTC的设置和时间维持不变。
系统复位后,对后备寄存器和RTC的访问被禁止,这是为了防止对后备区域(BKP)的意外写操作。执行以下操作将使能对后备寄存器和RTC的访问:
设置寄存器RCC_APB1ENR的PWREN和BKPEN位,使能电源和后备接口时钟
设置寄存器PWR_CR的DBP位,使能对后备寄存器和RTC的访问。
下面直接通过代码来演示如何操作RTC。
static void RTC_NVIC_Config( void )
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init( &NVIC_InitStructure );
}
//实时时钟配置
//初始化RTC时钟,同时检测时钟是否工作正常
//BKP->DR1用于保存是否第一次配置的设置
//返回0:正常
//其他:错误代码
u8 RTC_Init( void )
{
u8 temp = 0;
RCC_APB1PeriphClockCmd( RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE );
PWR_BackupAccessCmd( ENABLE ); //使能后备寄存器访问
if( BKP_ReadBackupRegister( BKP_DR1 ) != 0x5055 ) //检查是不是第一次配置时钟
{
BKP_DeInit(); //复位备份区域
RCC_LSEConfig( RCC_LSE_ON ); //设置外部低速晶振(LSE),使用外设低速晶振
//检查指定的RCC标志位设置与否,等待低速晶振就绪
while( RCC_GetFlagStatus( RCC_FLAG_LSERDY ) == RESET && temp < 250 )
{
temp++;
delay_ms( 10 );
}
if( temp >= 250 )
return 1; //初始化时钟失败,晶振有问题
RCC_RTCCLKConfig( RCC_RTCCLKSource_LSE ); //设置RTC时钟(RTCCLK),选择LSE作为RTC时钟
RCC_RTCCLKCmd( ENABLE ); //使能RTC时钟
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_WaitForSynchro(); //等待RTC寄存器同步
RTC_ITConfig( RTC_IT_SEC, ENABLE ); //使能RTC秒中断
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_EnterConfigMode(); // 允许配置
RTC_SetPrescaler( 32767 ); //设置RTC预分频的值
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_ExitConfigMode(); //退出配置模式
BKP_WriteBackupRegister( BKP_DR1, 0x5055 ); //向指定的后备寄存器中写入用户程序数据
}
else //系统继续计时
{
RTC_WaitForSynchro(); //等待最近一次对RTC寄存器的写操作完成
RTC_ITConfig( RTC_IT_SEC | RTC_IT_ALR, ENABLE ); //使能RTC秒中断、闹钟中断
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
}
RTC_NVIC_Config(); //RCT中断分组设置
return 0; //OK
}
//RTC时钟中断
//每秒钟触发一次
void RTC_IRQHandler( void )
{
if( RTC_GetITStatus( RTC_IT_SEC ) != RESET ) //秒钟中断
{
printf( "RTC INT!rn" );
}
//RTC_ClearITPendingBit(RTC_IT_SEC | RTC_IT_OW);
RTC_ClearITPendingBit( RTC_IT_SEC | RTC_IT_ALR );
RTC_WaitForLastTask();
}
在设置RTC时首先要判断一下RTC是否已经初始化过了,因为一般使用RTC时都会有电池供电,RTC的时候只需要设置一次就行。当系统关机后,只要电池有电,RTC就能正常工作,所以不需要每次开机都初始化一次时间,当没有初始化时初始化一次,初始化之后,以后开机就不需要再初始化了。为了标记当前设备是否已经初始化了,手动的给备份寄存器中写入特定的值。每次单片机启动后就会读取一次备份寄存器的值,当备份寄存器中的值不是写入的特定值,就说明当前设备还没有被初始化过,需要初始化一次。如果备份寄存器中的值是写入的特殊值,就说明当前设备已经被初始化过了,不需要再初始化了。
在初始化的时候,开启RTC的秒中断,这样RTC每一秒就会中断一次,在中断函数中通过串口打印数据。当程序运行后在串口工具中就可以看到每隔1秒,就会打印一个字符串。
上一篇:STM32F103高级定时器使用
史海拾趣
|
请教:WINCE里如何预设WIFI IP和WIFI的相关登录设置? 比如要预设IP、网关、DNS, 还有WIFI的加密方式、密码。 我想应该是修改注册表,但是我不知道在哪改,请指教。 全部的总数奉上!… 查看全部问答> |
|
有谁能提供USB鼠标键盘驱动,模拟鼠标键盘自动按键,以前用了wion.vxd,但是USB不可以 有谁能提供USB鼠标键盘驱动,模拟鼠标键盘自动按键,以前用了wion.vxd驱动,PS/2接口可以模拟按键盘, 但是USB接口不可以模拟按键 如果人能提供这样的驱动程序,本人不胜感激,大大给分,给分... … 查看全部问答> |
|
求一个可以 load nk.bin 的 loadcepc.exe 的可执行文件, 在线等!!! 这个文件编译太费事了, 找了个 msvc152 的编译器, 一堆编译错误。 有那位兄弟有 loadcepc.exe 的可执行文件, 最普通的就行了,我想在 cepc 上试一个东西。 mail: bamu1984 # 163.com … 查看全部问答> |
|
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity read_write is port( clk : in std_logic ; mcu_oe : in std_logic;   ...… 查看全部问答> |
|
与前面已讲述的电场屏蔽及磁场屏蔽的机理不同,电磁屏 蔽对于电磁波的衰减有三种不同的机理: x 当电磁波在到达屏蔽体表面时,由于空气与金属的交界面上 阻抗的不连续,对入射波产生的反射。这种反射不要求屏蔽 材料必须有一定厚度,只要求交界 ...… 查看全部问答> |
|
http://www.bsechr.com.cn/news.asp?anclassid=58&mnclassid=165Linux的标志是一只十分可爱的小企鹅,而FreeBSD的标志是一个拿着叉子的小恶魔。你是否经常会听到人们把 Linux及 BSD 系统混为一谈?是的,我有时会经常听到一些新手,甚至于媒体都这 ...… 查看全部问答> |




