背景
利用内部RTC替换外部RTC,RTC采用单独的电源供电,实现在单片机主电源VDD断电情况下,单片机的一个特殊引脚能够输出固定频率的脉冲信号。这样做保证了低功耗情况下,单片机依旧能够定时完成一些特定任务。
功能描述
- 用内部RTC实现秒级精度任务执行。 例如: 每1S进行一次LED灯的闪烁。每10S完成一次串口输出等。下图为使用内部RTC产生秒中断,串口打印一次数据。
- 用内部RTC实现定时任务执行。 例如:每隔30分钟进行一次传感器数据采集。
- 在前面所述两点的情况下,实现在STM32 VDD电源关闭情况下(即仅保留RTC电源),实现固定引脚的定时脉冲输出。下图为切断STM32电源后,用示波器观察引脚1S脉冲输出。
实现过程
要点:
- 如果需要产生秒中断或者定时中断,在RTC初始化函数中进行秒中断或定时中断的配置,注意中断初始化开启RTC闹钟中断。
- 如果需要在开机或断电状态下利用RTC完成I/O的定时脉冲输出。需要断开入侵检测引脚,设置该引脚为RTC闹钟输出或秒输出 该引脚为入侵检测引脚,STM32F103为PC13脚。
备注 : 没有出现的函数不重要,重要的函数已经进行备注。源工程代码已上传至资源工程代码,
有任何问题欢迎私信讨论。
void RTC_Init(void)
{
if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5) //从指定的后备寄存器中读出数据:读出了与写入的指定数据不相等
{
RTC_Config();
//将系统初始化的时间写入RTC
DateGetRTC_Sec(System_Date);
Adjust_RTCCounter();
TimeGetRTC_Sec(System_Time);
Adjust_RTCCounter();
// RTC_ExitConfigMode(); //退出配置模式
BKP_WriteBackupRegister(BKP_DR1, 0xA5A5); //向指定的后备寄存器中写入用户程序数据
}
else
{
RTC_WaitForSynchro(); //单步调试时 程序有时会陷入这个死循环!!!!!
// RTC_ITConfig(RTC_IT_SEC, ENABLE);
RTC_WaitForLastTask();
/* Enable PWR and BKP clocks */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);
/* Allow access to BKP Domain */
PWR_BackupAccessCmd(ENABLE);
/* 禁止 Tamper 引脚 */
/* 要输出 RTCCLK/64 到 Tamper 引脚, tamper 功能必须禁止 */
BKP_TamperPinCmd(DISABLE);
/* 使能 RTC 时钟输出到 Tamper 引脚 */
BKP_RTCOutputConfig(BKP_RTCOutputSource_Second);
/*等待寄存器同步*/
RTC_WaitForSynchro();
/*允许RTC秒中断*/
RTC_ITConfig(RTC_IT_SEC, ENABLE);
/*等待上次RTC寄存器写操作完成*/
RTC_WaitForLastTask();
}
GetRTC_Date();
GetRTC_Time();
}
//RTC配置
void RTC_Config(void)
{
/* Enable PWR and BKP clocks */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE); //使能PWR和BKP外设时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);
/* Allow access to BKP Domain */
PWR_BackupAccessCmd(ENABLE); //使能后备寄存器访问
/* Reset Backup Domain */
// 禁用入侵检测引脚
BKP_TamperPinCmd(DISABLE);
BKP_RTCOutputConfig(BKP_RTCOutputSource_Second); //使能入侵检测管脚输出RTC秒脉冲
BKP_DeInit(); //复位备份区域
//使用外部高速晶振 128分频
//RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128);
//使用外部32768晶振
RCC_LSEConfig(RCC_LSE_ON); //设置外部低速晶振(LSE),使用外设低速晶振
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET); //检查指定的RCC标志位设置与否,等待低速晶振就绪
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //设置RTC时钟(RTCCLK),选择LSE作为RTC时钟
/* Enable RTC Clock */
RCC_RTCCLKCmd(ENABLE); //使能RTC时钟
/* Wait for RTC registers synchronization */
RTC_WaitForSynchro(); //等待RTC寄存器同步
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
/* Enable the RTC Second */
RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能RTC秒中断
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
/* Set RTC prescaler: set RTC period to 1sec */
/* RTC period = RTCCLK/RTC_PR = (8000000Hz)/128/(62499+1) */
//RTC_SetPrescaler(62499);
// RTC_EnterConfigMode();///允许配置
RTC_SetPrescaler(32767); //设置RTC预分频的值
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
}