本文主要是介绍stm32f103 rtc日历,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
要做一个基于stm32f103的 rtc日历,stm32f103 rtc只有一个32位的计数器,不像现在新出的有专门的日期寄存器可以使用,但是网上早有大牛们写过这样的程序,找了个调试,可以用。因为网上有很多,就不再详细说明,下面是代码。
/*********时间结构体*******/
typedef struct
{//公历年月日周shifenmiaou16 w_year;u8 w_month;u8 w_date;u8 week;u8 hour;u8 min;u8 sec;
}calendar_tm;
calendar_tm timer;/****************************************************************************
* 名 称:u8 Is_Leap_Year(u16 year)
* 功 能:判断是否是闰年函数
* 入口参数:u16 year
* 出口参数:u8
* 说 明:该年份是不是闰年.1,是.0,不是
* 月份 1 2 3 4 5 6 7 8 9 10 11 12* 闰年 31 29 31 30 31 30 31 31 30 31 30 31* 非闰年 31 28 31 30 31 30 31 31 30 31 30 31
* 调用方法:无
****************************************************************************/
/*u8 Is_Leap_Year(u16 year)
{ if(year%4==0) //必须能被4整除{ if(year%100==0) { if(year%400==0)return 1;//如果以00结尾,还要能被400整除 else return 0; }else return 1; }else return 0;
}
*/
u8 Is_Leap_Year(u16 year) //和上面的一样,都可以使用
{return ((year % 4 == 0&& year %100 !=0)||year%400==0);
}
/****************************************************************************
* 名 称:u32 Time_Regulate(void)
* 功 能:调整有格式的时间值
* 入口参数:来自键盘输入
* 出口参数:u32,32位寄存器的值
* 说 明:把键盘输入的时钟转换为秒钟* 以1970年1月1日为基准* 1970~2099年为合法年份
* 调用方法:无
****************************************************************************/ u8 const table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5}; //月修正数据表
const u8 mon_table[12]={31,28,31,30,31,30,31,31,30,31,30,31}; //平年的月份日期表
u32 Time_Regulate(void)
{u16 syear = 0xFF; u8 smon = 0xFF,sday = 0xFF,hour = 0xFF,min = 0xFF,sec = 0xFF;u16 t;u32 seccount=0;printf("\r\n==============Time Settings=============================");printf("\r\n Please Set Year");while(syear == 0xFF) {syear = USART_Scanf(4,2099); }printf(": %d", syear); printf("\r\n Please Set Month");while(smon == 0xFF) {smon = USART_Scanf(2,12); }printf(": %d", smon);printf("\r\n Please Set Day");while(sday == 0xFF) {sday = USART_Scanf(2,31); }printf(": %d", sday);printf("\r\n Please Set Hours");while(hour == 0xFF) {hour = USART_Scanf(2,23); }printf(": %d", hour); printf("\r\n Please Set Minutes");while(min == 0xFF){min = USART_Scanf(2,59);}printf(": %d", min); printf("\r\n Please Set Seconds");while(sec == 0xFF){sec = USART_Scanf(2,59);}printf(": %d", sec); if(syear>=2000&&syear<=2099) //syear范围1970-2099,此处设置范围为2000-2099{ for(t=1970;t<syear;t++) //把所有 年份的秒钟相加{if(Is_Leap_Year(t))seccount+=31622400;//闰年的秒钟数else seccount+=31536000; //平年的秒钟数}smon-=1;for(t=0;t<smon;t++) //把前面月份的秒钟数相加{seccount+=(u32)mon_table[t]*86400;//月份秒钟数相加if(Is_Leap_Year(syear)&&t==1)seccount+=86400;//闰年2月份增加一天的秒钟数 }seccount+=(u32)(sday-1)*86400;//把前面日期的秒钟数相加 seccount+=(u32)hour*3600;//小时秒钟数seccount+=(u32)min*60; //分钟秒钟数seccount+=sec;//最后的秒钟加上去}return seccount - 20; //校正20秒,原因不详
}/****************************************************************************
* 名 称:void Time_Display(u32 secs)
* 功 能:显示日历
* 入口参数:计数器中的值(秒钟数)
* 出口参数:无
* 说 明:
* 调用方法:无
****************************************************************************/
void Time_Display(u32 secs)
{u32 days,temp,years = 1970,months = 0; days = secs/86400;if(days > 0) //超过一天{temp = days;while(temp >= 365) {if(Is_Leap_Year(years)) //是闰年{if(temp >= 366)temp -= 366; //闰年的天数elsebreak;}else{temp -= 365;} years++;}timer.w_year = years; //得到年份while(days >= 28){if(Is_Leap_Year(years) && months ==1) //判断是否为闰年的第二月{if(temp >= 29)temp -= 29;elsebreak;}else{if(temp >= mon_table[months]) temp -= mon_table[months];elsebreak;}months++; }timer.w_month = months+1; //得到月数timer.w_date = temp+1; //得到日期}temp = secs % 86400; //得到剩余秒数timer.hour = temp/3600; //得到小时timer.min = (temp%3600)/60; timer.sec = (temp%3600)%60;timer.week = RTC_Get_Week(timer.w_year,timer.w_month,timer.w_date);timer.week=RTC_Get_Week(timer.w_year,timer.w_month,timer.w_date);//获取星期 printf("\r\n Time: %0.2d:%0.2d:%0.2d,week:%0.2d,%0.2d:%0.2d:%0.2d",timer.w_year,timer.w_month,timer.w_date,timer.week,timer.hour,timer.min,timer.sec);} /****************************************************************************
* 名 称:u8 RTC_Get_Week(u16 year,u8 month,u8 day)
* 功 能:输入公历日期得到星期(只允许1901-2099年) //周日用 “00” 表示
* 入口参数:公历年月日
* 出口参数:星期
* 说 明:
* 调用方法:无
****************************************************************************/ u8 RTC_Get_Week(u16 year,u8 month,u8 day)
{ u16 temp2;u8 yearH,yearL; yearH=year/100; yearL=year%100; // 如果为21世纪,年份数加100 if (yearH>19)yearL+=100;// 所过闰年数只算1900年之后的 temp2=yearL+yearL/4;temp2=temp2%7; temp2=temp2+day+table_week[month-1];if (yearL%4==0&&month<3)temp2--;return(temp2%7);
}
这篇关于stm32f103 rtc日历的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!