这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » C51编程 计算两个时间点之间的差值问题 感觉蛮有挑战性的

共6条 1/1 1 跳转至

C51编程 计算两个时间点之间的差值问题 感觉蛮有挑战性的

菜鸟
2009-08-29 17:57:35     打赏

问题:如何判断两个时间点之间的间隔小于5分钟(300s)。

背景:at89s52系统从串口就收到上位机发来的数据,该数据的主要部分如下(内容为时间):年 月日 时 分 秒 年 月日 时 分 秒 ,前面的是系统时间,后面的是任务时间。如:09 08 28 16 05 20 09 08 29 22 20 00 。现在程序要判断这两个时间之间的间隔(任务时间-系统时间)是不是小于5分钟(300s),如果小于五分钟系统将采取提示动作,否则不动作。简而言之:单片机怎样判断现在的时间是否接近任务时间。
   
思想:先把所有可能出现的情况列出来,然后找出这些情况所满足的条件,那么在处理时就可以判断对象是否满足这些条件来决定对象是否达到要求。但是这种逻辑可能存在的问题是:不满足条件的肯定不符合要求,但是满足条件的却不一定符合要求。所以就要求用于判断的条件非常精确。

我的思路:经过分析,应该发出提示的有三大种情况1、两个时间点在同一天内相隔五分钟;2、两个时间点在同一个月内相隔五分钟;3、两个时间点在同一年内相隔五分钟。具体为以下六小种情况。
a.<两个时间点在同一天> 09.08.28 16:20:00 / 09.08.28 17:00:00 即—>  同年(年差yearc=0)、  同月(月差monthc=0)、  同日(日差dayc=0)  最后以秒为单位计算这两个时间点之间的差值
b.<两个时间点跨天> 09.08.28 23:55:00 / 09.08.29 00:00:00 即—>  同年(年差yearc=0)、  同月月差monthc=0)、不同日(日差dayc=1) 时差(hourc=-23)    最后以秒为单位计算这两个时间点之间的差值
c.<两个时间点跨月> 09.08.31 23:55:00 / 09.09.01 00:00:00 即—>  同年(年差yearc=0)、 不同月(月差monthc=1)、不同日(日差dayc=-30)时差(hourc=-23)  最后以秒为单位计算这两个时间点之间的差值
d.<两个时间点跨月> 09.09.30 23:55:00 / 09.10.01 00:00:00 即—>  同年(年差yearc=0)、 不同月(月差monthc=1)、不同日(日差dayc=-29)时差(hourc=-23)  最后以秒为单位计算这两个时间点之间的差值
e.<两个时间点跨月> 09.02.28(29) 23:55:00 / 09.03.01 00:00:00 即—>  同年(年差yearc=0)、 不同月(月差monthc=1)、不同日(日差dayc=-28或-27)时差(hourc=-23)  最后以秒为单位计算这两个时间点之间的差值
f.<两个时间点跨年> 09.12.30 23:55:00 / 10.01.01 00:00:00 即—> 不同年(年差yearc=1)、 不同月(月差monthc=-11)、不同日(日差dayc=-29)时差(hourc=-23)  最后以秒为单位计算这两个时间点之间的差值

假设现在接收到一组时间数据如果是应该做出提示的,那么这组时间数据必定符合上述条件之一,所以我用if语句来判断,如下:
(以上情况的各个条件必须要同时满足才算符合要求,只有符合要求的才算他们之间具体的时间差)
if (yearc==0 && monthc++0 &&dayc==0)
    {采用第一种时间差计算}
else if (yearc==0 && monthc==0 && dayc==1 && hourc==-23)
    {采用第二种时间差计算}
else if (yearc==0 && monthc==1 && (dayc==-30 ||dayc==-29 || dayc==-28 dayc==-27) && hourc==-23)
    {   
        调用月份判断函数(判断系统时间中的月是大月(flag=1)、小月(flag=2)、闰年2月(flag=3)或非闰年2月(flag=4),用变量flag来标识)
        if ((dayc==-30 && flag==1) || (dayc==-29 && flag==2) || (dayc==-28 && flag==3) || (dayc==-27 && flag==4))
            {采用第二种时间差计算}
    }
else if (yearc==1 && monthc==-11 && dayc==-29 && hourc==-23)
    {采用第二种时间差计算}
else
    {不计算时间差}

第一种时间差计算:hourc*3600+minutec*60 +secondc
第二种时间差计算:(minutec+60)*3600+secondc

月份判断函数()
{
    switch (系统月)
    case 1:
    case 3:
    case 5:
    case 7:
    case 8:
    case 10:
    case 12: flag=1; break;
    case 4:   
    case 6:
    case 9: flag=2; break;
    case 2: {判断该年是否为闰年,若是flag=3,否则flag=4} break;
    default:break;
}


我觉得这个逻辑判断能把所有符合要求的找出来,就是说对于应该提示的情况会发出提示,但是会不会在不应该提示的情况下也发出提示呢?

也不知道我说清楚了没有。希望大家帮我想一想,我想了几天头都晕了。很感谢你能耐着性子看到这里,我真诚的向您表示感谢。
希望大家能给出更好的方案建议,我在论坛没有找到类似的技术文章,但是我相信这个问题以前一定有人做过,我知道这个问题可以用查表的

方式解决,如果您以前做过,请您给我一些方案和建议。我的邮箱是gdmgb520@163.com,也可以留下您的邮箱,我和您联想。




关键词: 编程     计算     两个     时间     点之     间的     差值     问题         

菜鸟
2009-08-29 21:15:59     打赏
2楼
怎么没人帮我看看啊?有没有人以前做过类似的东西的,是不是我写得太繁琐了。

高工
2009-08-31 09:38:02     打赏
3楼
你这个帖子发到MCU板块,我觉得看到的人会更多!~

高工
2009-09-02 15:22:16     打赏
4楼

我觉得你的思路是可行的,确实存在这么多种应该考虑的情况,你的方法严密,不会有误报的情况了。
但我的建议是:既然这个指令是由串口发送的,为什么不在计算机上做验证呢?
当然,如果你的上位机只是现成的串口工具,那没办法修改,IO也不友好。
如果上位机是自己写的,就应该在发送指令时做合法化检查,不合法的给出报警也不发送,这个算法在PC上做显然比在51上做方便的多。


菜鸟
2009-09-03 10:47:33     打赏
5楼

能不能全部转换成秒?毕竟单片机使用寿命有限,因此可以使用32位变量来存储就够了。
月份对应的天数使用查表。
const char days[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
考虑到年份最多差一年:
先不考虑闰年,有符号计算。
t = ((( Y1 - Y2 )*365 + (days[M1] + D1- days[M2] - D2))*24 + (H1-H2))*3600 + (Min1 - Min2)*60 + (S1-S2);
现在考虑闰年的影响,由于2个闰年不可能连续,所以:
if ( T1 == 闰年 )
{
  if (M1 > 2 && D1> 28)    t += 3600 * 24; 
}
else if ( T2 == 闰年 )
{
 if (M2 < 3)    t += 3600 * 24;
}

  


工程师
2009-09-06 12:54:31     打赏
6楼
有点繁琐,下次有空回来看看!

共6条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]