STM32F103 RTC LSE/LSI为时钟源的代码
内部低速时钟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为时钟源的代码相关推荐
- STMCube学习记录(一)RCC时钟源配置
打开STMCube的RCC配置界面如下图, 在用cube配置时钟时,有下面三个选项 Disable(禁用) BYPASS Clock Source(旁路时钟源) Crystal/Ceramic Res ...
- STM32F4设置系统时钟源为内部HSI
最近项目需要在调试STM32时遇到外部晶振时钟不稳定,查看RCC_CR寄存器的第17位始终处于0,表示外部晶振始终处于不稳定状态: 当HSE开启时,如果HSERDY一直处于0时,则芯片会启动内部16M ...
- 纠结的STM32 RTC时钟源LSE
一开始,所有实验都是在神舟板上去完成,根本就没有发现RTC的问题.直到我们自己画板来后调试时,才发现STM32 RTC的外部时钟源存在问题. 这也算是STM32的一个鸡肋,对于LSE外部晶振太过于苛刻 ...
- STM32 RTC时钟源LSE
一开始,所有实验都是在神舟板上去完成,根本就没有发现RTC的问题.直到我们自己画板来后调试时,才发现STM32 RTC的外部时钟源存在问题. 这也算是STM32的一个鸡肋,对于LSE外部晶振太过于苛刻 ...
- STM32 五个时钟源HSI、HSE、LSI、LSE、PLL 如何识别
①HSI是高速内部时钟,RC振荡器,频率为8MHz. ②HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz. ③LSI是低速内部时钟,RC振荡器,频率为4 ...
- STM32学习笔记之一:时钟源HSI、HSE、LSI、LSE、PLL及其不接外部晶体时的管脚配置
如何识别STM32五个时钟源及其不接外部晶体时的管脚配置? A: 1.HSI是高速内部时钟,RC振荡器,频率为8MHz. 2. HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为 ...
- 什么是RCT实时时钟?(STM32中RTC时钟源)
什么是RCT(Real Time Clock,实时时钟)? 一.RTC时钟简介 RTC(Real Time Clock,实时时钟)是指安装在电子设备或实现其功能的IC(集成电路)上的时钟,一般会是集成 ...
- 火牛单片机rtc时钟配置_亲测实验,RTC使用内部低速时钟LSI时,对RTC的配置过程...
下面是一开始写程序时,配置过程: char RTCInit() { char count = 0; StartTime.year = 16; StartTime.month = 3; StartTim ...
- linux hwclock -r显示的HWC TIME(硬件时钟时间)与timedatectl结果中的RTC TIME(实时时钟时间)有什么区别?BIOS时钟源
文章目录 RTC TIME(实时时钟时间).HWC TIME(硬件时间)(BIOS时钟).BIOS时钟源 夏日志时间 系统时间与硬件时间的同步原理 20230129 BIOS本地RTC(实时时钟)时间 ...
最新文章
- AutoScaling 生命周期挂钩功能
- idea 解决查看源码没有注释
- - The superclass javax.servlet.http.HttpServlet was not found on the Java
- Linux添加文件命令
- [Object-C语言随笔之三] 类的创建和实例化以及函数的添加和调用!
- Orange-Classification,Regression
- 实战03_SSM整合ActiveMQ支持多种类型消息
- Can‘t find a suitable configuration file in this directory or any parent. 报错解决错误
- 和朋友们一起探道一下CPA广告反作弊方面的技术,欢迎大家发表意见。
- OAuth 授权的工作原理是怎样的?
- 慢慢记录有关渗透1瞎记
- C++开发技术的应用有哪些?
- 番茄是水果还是蔬菜这事儿,居然闹到了最高法院?!
- 关于软件测试里面的Fault Error Failure 差别
- 一个简单的Python自动投票
- 塞规公差带图_工作量规公差带.ppt
- typescript入门练手小demo
- 五阶魔方公式java_5阶魔方教程(五阶魔方一步一步图解)
- 3d建模做一单多少钱?做外包赚钱吗?
- python 绘制qq图
热门文章
- JSP/Servlet临汾天泰学习笔记(一)
- mysql 1075_mysql1075错误_1075报错怎么办_mysql主键冲突怎么办 - 树懒学堂
- 模为60的BCD码计数器的设计与验证
- 将linux改为windows7,linux操作系统如何改为windows 7的呀????!!!
- 从零吃透 Vue.js 框架,这里全部有!
- 被打了打回去算不算是正当防卫
- 【会议分享】2022年电子,通信与控制工程国际研讨会(SECCE 2022)
- android ble蓝牙接收不到数据_Android BLE蓝牙开发-读写数据 获取UUID
- Spring Security中的密码安全
- leetcode hot100 之 子集