第十一届蓝桥杯嵌入式组别底层驱动程⑦(RTC时钟)
/*******************************************************************************
* 文件名称:RTC
* 日期版本:2019-11-26/V3.0b
* 作 者:零点工作室(RMLS)
*******************************************************************************/
#include "project.h"
#include "RTC.h"
uint8_t hour, min, sec;
uint32_t TimeDisplay = 0;
uint8_t text[20];
extern uint8_t str[];
void RTC_Init(uint8_t HH,uint8_t MM,uint8_t SS) //实时时钟的初始化配置
{
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);//使能PWR和BKP时钟
/*设置寄存器RCC_APB1ENR的PWREN和BKPEN位,使能电源和后备接口时钟。*/
PWR_BackupAccessCmd(ENABLE); //BKP备份域使能
BKP_DeInit(); //复位BKP寄存器
RCC_LSICmd(ENABLE); //使能内部低速时钟
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);//等待内部低速时钟就绪
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); //设置RTC时钟为内部低速时钟
RCC_RTCCLKCmd(ENABLE); //使能RTC时钟
RTC_WaitForSynchro(); //等待RTC时钟同步
RTC_WaitForLastTask(); //等待寄存器操作完成
RTC_ITConfig(RTC_IT_SEC, ENABLE); //RTC时钟秒中断使能
RTC_WaitForLastTask(); //等待寄存器操作完成
RTC_SetPrescaler(39999); /* RTC period = RTCCLK/RTC_PR = (40 KHz)/(39999+1) */ //40KHz时钟分频产生秒时基
RTC_WaitForLastTask(); //等待寄存器操作完成
RTC_SetCounter(HH*3600+MM*60+SS); //设置秒计数寄存器值
RTC_WaitForLastTask(); //等待寄存器操作完成
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //先占优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void RTC_Display(uint8_t RTC_Flag)
{
static uint32_t time = 0;
if(RTC_Flag)
{
RTC_Flag = 0;
time = RTC_GetCounter(); //得到计数器目前的值
RTC_WaitForLastTask();
if(time == (23 * 3600 + 59 * 60 + 60) )
{
RTC_SetCounter(0); //设置RTC计数器的值
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
}
else
{
hour = time / 3600;
min = time % 3600 / 60;
sec = time % 3600 % 60;
sprintf((char *)str, " %.2d:%.2d:%.2d ", hour, min, sec);
LCD_DisplayStringLine(Line7, str);
}
}
}
}
#ifndef __RTC_H__
#define __RTC_H__
#include "stm32f10x.h"
#include "RTC.h"
void RTC_Init(uint8_t HH,uint8_t MM,uint8_t SS);
void RTC_Display(uint8_t RTC_Flag);
extern uint8_t hour, min, sec;
#endif
```c
extern uint8_t RTC_Flag;
void RTC_IRQHandler(void) //RTC中断
{
if (RTC_GetITStatus(RTC_IT_SEC) == 1){
RTC_ClearITPendingBit(RTC_IT_SEC);
RTC_Flag = 1;
}
}