软件RTC在单片机上的C语言实现(二)

本文介绍了在单片机上使用C语言实现软件RTC的第二种方法,强调了如何处理带有时间属性的数据进行快速排序和比较。通过位字段的结构体定义,简化了时间值的比较,可用于实现多个闹钟的增删改查功能,并讨论了不同存储模式下的处理策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

软件RTC在单片机上的C语言实现(二)

一.前言

上一篇文章讲了软件rtc实现的第一种方法,用的是相对天数值,然后通过两个转换函数作为单片机内部系统与现实日期的接口。废话不多说,今天贴第二种实现方法,也是最传统的软件rtc处理方法。

二.实现

2.1 定义结构体类型和变量

typedef struct
{
	u32 minute  :6;  
	u32 hour    :5;
	u32 date    :5;
	u32 month   :4;
	u32 year    :8; 
	u32 weekDay :4;
}ST_RTCDATA;

//rtc值
ST_RTCDATA gs_RtcData;

//列举闰年时候每个月的天数
u8 gs_LeapYearMonDays[12]={31,29,31,30,\
							   31,30,31,31,\
							   30,31,30,31};

//列举平年的时候每个月的天数
u8 gs_OrdYearMonDays[12]={31,28,31,30,\
							  31,30,31,31,\
							  30,31,30,31};
//秒值							  
u8 gu8_CurSecond;

//rtc是否完成了初始化,当获取到了外部时间且赋值到了gs_RtcData将其更新为1
u8 gu8_RtcInitFlg;

肯定有人会想为什么我定义的这个ST_RTCDATA结构体不包含秒值,为什么要用C语音中的位字段的写法。其实这样写是为了方便rtc值大小的比较。我会在文章后面讲述关于带有时间属性的数据做排序和比较的时候详细介绍。

2.2 软件rtc的时间更迭的实现

//传入当前实际年份减去2000后的值
//闰年返回1,平年返回0
u8 Rtc_IsLeapYear(u8 curYear)
{
	if(curYear%4==0)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
//软件rtc,1s调用一次
void Rtc_Loop(ST_RTCDATA *time)
{
	u8 monthDays=0;

	//时间经过校准后再运行软件rtc
	if(!gu8_RtcInitFlg)
	{
		return;
	}
	
	gu8_CurSecond++;

	if(gu8_CurSecond>=60)
	{
		gu8_CurSecond=0;

		time->minute++;

		if(time->minute>=60)
		{
			time->minute=0;
			time->hour++;

			if(time->hour>=24)
			{
				time->hour=0;
				time->date++;

				time->weekDay++;
				
				//更新星期值
				if(time->weekDay>7)
				{
					time->weekDay=1;
				}
				
				//获取当前年份月份的天数
				if(Rtc_IsLeapYear(time->year)) //闰年
				{
					monthDays=gs_LeapYearMonDays[time->month-1];
				}	
				else //平年
				{
					monthDays=gs_OrdYearMonDays[time->month-1];
				}

				//如果当前日期大于当前月份的天数了,月份加1,天数置为1
				if(time->date>monthDays)
				{
					time->date=1;
					time->month++;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值