内部低速时钟LSI为40K,外部低速时钟LSE-32.768K
在头文件有如下定义用以适用LSI或者LSE:

#define RTC_LSI_EN            (0)   /*内部低速时钟-40K*/
#define RTC_LSE_EN            (1)   /*外部低速时钟-32.768K*/

起始时间设为2020年:

#define     START_YEAR      2020//default 2000, Jan.1, 00:00:00
#define     SEC_IN_DAY      86400//1 day includes 86400 seconds

RTC结构体:

typedef     struct
{       /* date and time components */int16_t     sec;    //senconds after the minute, 0 to 59int16_t     min;    //minutes after the hour, 0 to 59int16_t     hour;   //hours since midnight, 0 to 23int16_t     mday;   //day of the month, 1 to 31int16_t     month;  //months of the year, 1 to 12int16_t     year;   //years, START_YEAR to START_YEAR+135int16_t     wday;   //days since Sunday, 0 to 6int16_t     yday;   //days of the year, 1 to 366
}Calendar_TypeDef;

初始化函数:

void RTC_UserInit(void)
{uint32_t RetryCnt = 0xFFFFFF;Calendar_TypeDef initTime = {0,0,0,1,1,2020,3,1};//2020年1月1日0时0分0秒周三2020年的第一天//In BKP DR1, we stored a special character 0xA5A5. When forst power on, or//lost battery power, this charater will be lost. RTC needs reconfiguration.if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5){RTC_ReConfig();SetTime(&initTime);BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);//restore special character}else{/* Enable PWR and BKP clocks [PWR时钟(电源控制)与BKP时钟(RTC后备寄存器)使能]*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);/* Allow access to BKP Domain [使能RTC和后备寄存器访问]*/PWR_BackupAccessCmd(ENABLE);#if RTC_LSI_EN/* Enable the LSI OSC */RCC_LSICmd(ENABLE);/* Wait till LSI is ready */RetryCnt = 0xFFFFFF;while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET){ if(RetryCnt-- == 0) break; }//超时退出,防止死机/* Select the RTC Clock Source */RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
#endif
#if RTC_LSE_EN/* Enable LSE */RCC_LSEConfig(RCC_LSE_ON); /* Wait till LSE is ready */RetryCnt = 0xFFFFFF;while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET){ if(RetryCnt-- == 0) break; }//超时退出,防止死机/* Select LSE as RTC Clock Source */RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
#endif/* Enable RTC Clock [打开时钟]*/RCC_RTCCLKCmd(ENABLE); RTC_WaitForSynchro();//wait for APB1 synchronize with RTCRTC_ITConfig(RTC_IT_SEC, DISABLE);//enable second interrupt  RTC_WaitForLastTask();//wait for operation is over}RCC_ClearFlag();
}
//end function RTC_UserInit

用SetTime()设置时间,用GetTime()获取时间

/******************************************************************************** Function Name  : GetTime* Description    : Get time to struct *pCalendar from RTC.* Input          : pointer to a calendar struct* Return         : *******************************************************************************/
void GetTime(Calendar_TypeDef *pTimeNow)
{uint32_t t_t = RTC_GetCounter();//call function in stm32f10x lib*pTimeNow = MyLocalTime(&t_t);//call function in local file
}
//end function GetTime/******************************************************************************** Function Name  : SetTime* Description    : set time to RTC as demand in menu.* Input          : pointer to a calendar struct * Return         : *******************************************************************************/
void SetTime(Calendar_TypeDef *pTimeNow)
{uint32_t t_t = MyMakeTime(pTimeNow);//call function in local fileRTC_WaitForLastTask();RTC_SetCounter((uint32_t)t_t);RTC_WaitForLastTask();return;
}
//end function SetTime/******************************************************************************** Function Name  : GetDiffTime* Description    : Form a 32 bit second counting value from calendar.* Input          : pointers to 2 calendar structs* Return         : 32 bit value in second*******************************************************************************/
uint32_t GetDiffTime(Calendar_TypeDef *pCalendar1, Calendar_TypeDef *pCalendar0)
{uint32_t t1, t0, dt;t1 = MyMakeTime(pCalendar1);//call function in local filet0 = MyMakeTime(pCalendar0);//call function in local fileif(t1 > t0) dt = t1 - t0;//get abs valueelse dt = t0 - t1;//get abs valuereturn dt;
}
//end function GetDiffTime/******************************************************************************** Function Name  : MyMakeTime* Description    : Form a 32 bit second counting value from calendar.* Input          : pointer to a calendar struct* Return         : 32 bit second counting value*******************************************************************************/
uint32_t MyMakeTime(Calendar_TypeDef *pCalendar)
{uint32_t TotalSeconds = pCalendar->sec;int16_t nYear = pCalendar->year;int16_t DaysInYear = 365;int16_t nMonth = pCalendar->month;int16_t DaysInMonth = 30;if((nYear < START_YEAR) || (nYear > (START_YEAR + 135))) return 0;//out of year rangeTotalSeconds += (uint32_t)pCalendar->min * 60;//contribution of minutesTotalSeconds += (uint32_t)pCalendar->hour * 3600;//contribution of hours//contribution of mdaysTotalSeconds += (uint32_t)(pCalendar->mday - 1) * SEC_IN_DAY;while(nMonth > 1)//contribution of months{nMonth --;if(nMonth == 1||nMonth == 3||nMonth == 5||nMonth == 7||nMonth == 8||nMonth == 10||nMonth == 12)DaysInMonth = 31;else if(nMonth == 2){if(IsLeapYear(nYear)) DaysInMonth = 29;else DaysInMonth = 28;}else DaysInMonth = 30;TotalSeconds += (uint32_t)DaysInMonth * SEC_IN_DAY;}while(nYear > START_YEAR)//contribution of years{nYear --;if(IsLeapYear(nYear)) DaysInYear = 366;else DaysInYear = 365;TotalSeconds += (uint32_t)DaysInYear * SEC_IN_DAY;}return TotalSeconds;
}
//end function MyMakeTime/******************************************************************************** Function Name  : MyLocalTime* Description    : Form a calendar from 32 bit second counting.* Input          : pointer to a 32 bit second value* Return         : Calendar structure*******************************************************************************/
Calendar_TypeDef MyLocalTime(const uint32_t *pTotalSeconds)
{Calendar_TypeDef Calendar;uint32_t TotalDays, RemainSeconds;int16_t DaysInYear=365;int16_t DaysInMonth=30;Calendar.year = START_YEAR;Calendar.month = 1;  Calendar.mday = 1;Calendar.yday = 1;  Calendar.wday = Ymd2Wday(START_YEAR, 1, 1);TotalDays = *pTotalSeconds / SEC_IN_DAY;RemainSeconds = *pTotalSeconds % SEC_IN_DAY;Calendar.hour = (int16_t)(RemainSeconds / 3600);//calculate hourCalendar.min = (int16_t)((RemainSeconds / 60) % 60);//calculate minuteCalendar.sec = (int16_t)(RemainSeconds % 60);//calculate secondCalendar.wday = (int16_t)((TotalDays + Calendar.wday) % 7);//calculate wdaywhile(1)//calculate year{if(IsLeapYear(Calendar.year)) DaysInYear = 366;else DaysInYear = 365;if(TotalDays >= DaysInYear){TotalDays -= DaysInYear;Calendar.year ++;}//continue whileelsebreak;//forced to end while}//finish year calculationCalendar.yday += TotalDays;//calculate ydaywhile(1)//calculate month{if(Calendar.month == 1||Calendar.month == 3||Calendar.month == 5||Calendar.month == 7||Calendar.month == 8||Calendar.month == 10||Calendar.month == 12)DaysInMonth = 31;else if(Calendar.month == 2){if(IsLeapYear(Calendar.year)) DaysInMonth = 29;else DaysInMonth = 28;}else DaysInMonth = 30;if(TotalDays >= DaysInMonth){TotalDays -= DaysInMonth;Calendar.month ++;}//continue whileelsebreak;//forced to end while}//finish month calculationCalendar.mday += (int16_t)TotalDays;//calculate mdayreturn Calendar;
}
//end function MyLocalTime/******************************************************************************** Function Name  : Ymd2Wday* Description    : Calculate days in week from year, month, mday.* Input          : year, month, mday* Return         : 0--6, Suanday--Saturday*******************************************************************************/
static int16_t Ymd2Wday(int16_t nYear, int16_t nMonth, int16_t nMday)
{ uint8_t i;const uint8_t DaysInMonth[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 }; for(i = 0; i < nMonth; i++) nMday += DaysInMonth[i]; if(nMonth > 2) {if(IsLeapYear(nYear)) nMday++; } nYear--;return (nYear + nYear/4 - nYear/100 + nYear/400 + nMday)%7;
}
//end function Ymd2Wday/************************************************************************ Function Name  : IsLeapYear* Description    : Check whether the past year is leap or not.* Input          : 4 digits year number* Return         : 1: leap year. 0: not leap year***********************************************************************/
static  uint8_t   IsLeapYear(int16_t nYear)
{if(nYear % 4 != 0)      return 0;if(nYear % 100 != 0)    return 1;return (uint8_t)(nYear % 400 == 0);
}
//end function IsLeapYear/*******************************END OF FILE************************************/

STM32F103 RTC LSE/LSI为时钟源的代码相关推荐

  1. STMCube学习记录(一)RCC时钟源配置

    打开STMCube的RCC配置界面如下图, 在用cube配置时钟时,有下面三个选项 Disable(禁用) BYPASS Clock Source(旁路时钟源) Crystal/Ceramic Res ...

  2. STM32F4设置系统时钟源为内部HSI

    最近项目需要在调试STM32时遇到外部晶振时钟不稳定,查看RCC_CR寄存器的第17位始终处于0,表示外部晶振始终处于不稳定状态: 当HSE开启时,如果HSERDY一直处于0时,则芯片会启动内部16M ...

  3. 纠结的STM32 RTC时钟源LSE

    一开始,所有实验都是在神舟板上去完成,根本就没有发现RTC的问题.直到我们自己画板来后调试时,才发现STM32 RTC的外部时钟源存在问题. 这也算是STM32的一个鸡肋,对于LSE外部晶振太过于苛刻 ...

  4. STM32 RTC时钟源LSE

    一开始,所有实验都是在神舟板上去完成,根本就没有发现RTC的问题.直到我们自己画板来后调试时,才发现STM32 RTC的外部时钟源存在问题. 这也算是STM32的一个鸡肋,对于LSE外部晶振太过于苛刻 ...

  5. STM32 五个时钟源HSI、HSE、LSI、LSE、PLL 如何识别

    ①HSI是高速内部时钟,RC振荡器,频率为8MHz.   ②HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz. ③LSI是低速内部时钟,RC振荡器,频率为4 ...

  6. STM32学习笔记之一:时钟源HSI、HSE、LSI、LSE、PLL及其不接外部晶体时的管脚配置

    如何识别STM32五个时钟源及其不接外部晶体时的管脚配置? A: 1.HSI是高速内部时钟,RC振荡器,频率为8MHz. 2. HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为 ...

  7. 什么是RCT实时时钟?(STM32中RTC时钟源)

    什么是RCT(Real Time Clock,实时时钟)? 一.RTC时钟简介 RTC(Real Time Clock,实时时钟)是指安装在电子设备或实现其功能的IC(集成电路)上的时钟,一般会是集成 ...

  8. 火牛单片机rtc时钟配置_亲测实验,RTC使用内部低速时钟LSI时,对RTC的配置过程...

    下面是一开始写程序时,配置过程: char RTCInit() { char count = 0; StartTime.year = 16; StartTime.month = 3; StartTim ...

  9. linux hwclock -r显示的HWC TIME(硬件时钟时间)与timedatectl结果中的RTC TIME(实时时钟时间)有什么区别?BIOS时钟源

    文章目录 RTC TIME(实时时钟时间).HWC TIME(硬件时间)(BIOS时钟).BIOS时钟源 夏日志时间 系统时间与硬件时间的同步原理 20230129 BIOS本地RTC(实时时钟)时间 ...

最新文章

  1. AutoScaling 生命周期挂钩功能
  2. idea 解决查看源码没有注释
  3. - The superclass javax.servlet.http.HttpServlet was not found on the Java
  4. Linux添加文件命令
  5. [Object-C语言随笔之三] 类的创建和实例化以及函数的添加和调用!
  6. Orange-Classification,Regression
  7. 实战03_SSM整合ActiveMQ支持多种类型消息
  8. Can‘t find a suitable configuration file in this directory or any parent. 报错解决错误
  9. 和朋友们一起探道一下CPA广告反作弊方面的技术,欢迎大家发表意见。
  10. OAuth 授权的工作原理是怎样的?
  11. 慢慢记录有关渗透1瞎记
  12. C++开发技术的应用有哪些?
  13. 番茄是水果还是蔬菜这事儿,居然闹到了最高法院?!
  14. 关于软件测试里面的Fault Error Failure 差别
  15. 一个简单的Python自动投票
  16. 塞规公差带图_工作量规公差带.ppt
  17. typescript入门练手小demo
  18. 五阶魔方公式java_5阶魔方教程(五阶魔方一步一步图解)
  19. 3d建模做一单多少钱?做外包赚钱吗?
  20. python 绘制qq图

热门文章

  1. JSP/Servlet临汾天泰学习笔记(一)
  2. mysql 1075_mysql1075错误_1075报错怎么办_mysql主键冲突怎么办 - 树懒学堂
  3. 模为60的BCD码计数器的设计与验证
  4. 将linux改为windows7,linux操作系统如何改为windows 7的呀????!!!
  5. 从零吃透 Vue.js 框架,这里全部有!
  6. 被打了打回去算不算是正当防卫
  7. 【会议分享】2022年电子,通信与控制工程国际研讨会(SECCE 2022)
  8. android ble蓝牙接收不到数据_Android BLE蓝牙开发-读写数据 获取UUID
  9. Spring Security中的密码安全
  10. leetcode hot100 之 子集