STM32F103单片机RTC结合time.h使用
在使用stm32f103系列单片机的时候总是会碰到RTC计时的问题,103系列单片机的RTC使用的是秒计时
在经过一段时间的研究,终于发现了一种比较简单而且易于理解的使用方法,就是结合系统文件time.h的使用
首先要添加头文件
#include <time.h>
RTC的初始化和普通方式无区别
u8 RTC_Init(void)
{
//检查是不是第一次配置时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //使能PWR和BKP外设时钟
PWR_BackupAccessCmd(ENABLE); //使能后备寄存器访问
if (BKP_ReadBackupRegister(BKP_DR1) != 0x5AA5) //从指定的后备寄存器中读出数据:读出了与写入的指定数据不相乎
{
BKP_DeInit(); //复位备份区域
RCC_LSEConfig(RCC_LSE_ON); //设置外部低速晶振(LSE),使用外设低速晶振
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) //检查指定的RCC标志位设置与否,等待低速晶振就绪
{
}
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寄存器的写操作完成
Clock_SetTime(2015,1,14,17,42,55); //设置时间
RTC_ExitConfigMode(); //退出配置模式
BKP_WriteBackupRegister(BKP_DR1, 0x5AA5); //向指定的后备寄存器中写入用户程序数据
}
else //如果已配置过则不再进行配置
{
RTC_WaitForSynchro(); //等待最近一次对RTC寄存器的写操作完成
RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能RTC秒中断
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
}
RTC_NVIC_Config(); //RCT中断分组设置
Clock_Get(); //更新时间
return 0;
}
设置时间和读取时间采用结构体的方式
首先需要定义一个时间结构体
typedef struct
{
vu8 hour;
vu8 min;
vu8 sec;
vu16 w_year;
vu8 w_month;
vu8 w_date;
}_calendar_obj;
_calendar_obj calendar;//时钟结构体
在设置时间时
oid Clock_SetTime(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec)
{
time_t time_t_Set_Time; //定义time_t类型的设置时间结构体
struct tm tm_Set_Time; //定义tm结构的设置时间结构体
tm_Set_Time.tm_year = (u32)(syear-1900); //从2000年开始算起
tm_Set_Time.tm_mon = (u32)(smon-1); //月
tm_Set_Time.tm_mday = (u32)sday; //日
tm_Set_Time.tm_hour = (u32)hour; //时
tm_Set_Time.tm_min = (u32)min; //分
tm_Set_Time.tm_sec = (u32) sec; //秒
time_t_Set_Time=mktime(&tm_Set_Time); //得到计数初值
if(time_t_Set_Time!=0xFFFFFFFF)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //使能PWR和BKP外设时钟
PWR_BackupAccessCmd(ENABLE); //使能RTC和后备寄存器访问
RTC_SetCounter(time_t_Set_Time); //设置RTC计数器的值
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
}
}
读取时间
void Clock_Get(void)
{
struct tm *local;
time_t RTCTime;
RTCTime = RTC_GetCounter(); //获取当前RTC高字节
local=localtime(&RTCTime); //把从1970-1-1零点零分到当前时间系统所偏移的秒数时间转换为本地日历时间
calendar.w_year = (u16)(local->tm_year+1900); //从1900年起
calendar.w_month = (u16)(local->tm_mon+1); //月
calendar.w_date = (u16)local->tm_mday; //日
calendar.hour = (u16)local->tm_hour; //时
calendar.min = (u16)local->tm_min; //分
calendar.sec = (u16)local->tm_sec; //秒
}
打开秒中断
void RTC_IRQHandler(void)
{
if (RTC_GetITStatus(RTC_IT_SEC) != RESET) //秒钟中断
{
Clock_Get();//更新时间
}
RTC_ClearITPendingBit(RTC_IT_SEC|RTC_IT_OW);//清闹钟中断
RTC_WaitForLastTask();
}