打印

这个问题,我想了一个春节(是我没表达清楚?)

[复制链接]
5035|53
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yuntian|  楼主 | 2008-2-13 15:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
新年第一贴,先拜个年再说.

   问题比较简单,但是我想了一个春节也没有好的算法.
一个产品,需要判断两个时间是否相差在30分钟以内,因为单片机已经空间快用完了,所以是个非常头痛的问题,是PIC系列的,程序空间只剩下110字,两个时间包括年月日时分,因为两次时间不确定哪个一个快,哪一个慢,加上程序空间限制了,所以头大,单片机是用8脚的,这个类型的单片机好像没有超过2K程序空间的.
    比较有挑战的问题,哪个有好办**

问题等于是任意给定两个时间,判断这两个时间是否相差30分钟,(注意,括年月日时分5个参数)


再把问题说清楚一下:
就是系统是一个门禁,主机MCU程序空间有2K,每个ID卡都有独立时钟,门禁需要两个人都插入ID卡才能打开,再只有一个插卡口,所以只能一个人插卡后拔出来,另一个人再插卡,两次插卡时间不能超过30分钟,超过30分钟前一次插卡无效.
   再则,时钟不是主机产生的,是由每个ID插卡时发送自己的当前时间给主机判断,这点要注意.
   搞得我好像觉得自己智商很低,连减法都搞不定,另一个前提是程序空间只有110字,大程序装不下,否则这么简单搞不定我只能改行了.

相关帖子

沙发
xwj| | 2008-2-13 15:29 | 只看该作者

很简单啊,应该不用110字

使用特权

评论回复
板凳
ayb_ice| | 2008-2-13 15:31 | 只看该作者

110字节搞不定啊

可能也差不多,直接减吧,PICC的效率还是很高的。

使用特权

评论回复
地板
HWM| | 2008-2-13 15:32 | 只看该作者

“减法”是一个有挑战的问题吗?

使用特权

评论回复
5
老狼| | 2008-2-13 16:48 | 只看该作者

很简单的。

第一个事件来的时候,启动定时计时,等第二个事件到来! 代码量应该够了。

或者第一个事件来的时候,用不断读取时钟信号的秒变位计数,如果精度允许一分钟-2分钟,就读取分钟变位计数,反正方法挺多。

使用特权

评论回复
6
3.3v| | 2008-2-13 18:28 | 只看该作者

计数

使用特权

评论回复
7
yuntian|  楼主 | 2008-2-13 18:45 | 只看该作者

没那么简单吧

因为两个时间是不确定的,比如第一个时间是2008-01-20 15:59,第二个时间是2004-02-29 16:01怎么比较他们是否相差30分钟?如果减法,我可以肯定的告你,代码绝对超过空间了.这还有润年的问题.
如果代码长度没有限制,我想很多人都很快搞定,问题是空间不够了,算法一定要想当精简,而且还会有时间换空间.

使用特权

评论回复
8
xwj| | 2008-2-13 19:00 | 只看该作者

唉.....

使用特权

评论回复
9
老狼| | 2008-2-13 20:54 | 只看该作者

我倒!

使用特权

评论回复
10
谈的元| | 2008-2-13 22:24 | 只看该作者

2008比2004大,就是差超过30分钟呀

先比较年,再比较月,。。。

楼主有什么问题呀?

使用特权

评论回复
11
程序匠人| | 2008-2-14 08:14 | 只看该作者

5楼老狼的方法似乎是正解

lz不会连RAM也用得一个不剩吧?

使用特权

评论回复
12
yuntian|  楼主 | 2008-2-14 09:17 | 只看该作者

原来写过一个,有漏洞

i=date.month;
    if(date.year>last_time.year)//年比较
        {i+=12;}
    if(i>last_time.month)//月比较
        {i=days_month[date.month&0x0f-1];
            if(date.month==1&&(date.year&0x03)==0)    //测试是否是润年
                {i++;}
            i+=date.day;
        }
    else{i=date.day;}
    if(i>last_time.day)//日比较
        {i=date.hour+24;}
    else{i=date.hour;}
    if(i>last_time.hour)//时比较
        {i=date.minute+60;}
    else{i=date.minute;}
    if(i>=last_time.minute)
        {i-=last_time.minute;
            if(i>30)//间隔超过30分?
                {return(1);}//超时返回=1
        }

就这个编译下来都超过100字了,

使用特权

评论回复
13
gyt| | 2008-2-17 13:43 | 只看该作者

楼主要改变原来的思考方法

采用新的思路

使用特权

评论回复
14
winds| | 2008-2-17 13:59 | 只看该作者

只要跳出原来的思路

另外建立个时间,比如定时器产生1分钟定时等,这样才有可能解决。

使用特权

评论回复
15
mikesullen| | 2008-2-18 01:32 | 只看该作者

看来楼主对单片机的理解不够

可能是只会用C语言来写

使用特权

评论回复
16
li_mu| | 2008-2-18 04:32 | 只看该作者

你这个程序如果优化一下(反汇编)能到多少?

原来写过一个,有漏洞

i=date.month;
    if(date.year>last_time.year)//年比较
        {i+=12;}
    if(i>last_time.month)//月比较
        {i=days_month[date.month&0x0f-1];
            if(date.month==1&&(date.year&0x03)==0)    //测试是否是润年
                {i++;}
            i+=date.day;
        }
    else{i=date.day;}
    if(i>last_time.day)//日比较
        {i=date.hour+24;}
    else{i=date.hour;}
    if(i>last_time.hour)//时比较
        {i=date.minute+60;}
    else{i=date.minute;}
    if(i>=last_time.minute)
        {i-=last_time.minute;
            if(i>30)//间隔超过30分?
                {return(1);}//超时返回=1
        }

就这个编译下来都超过100字了,
-----------------------------------
我怎么总觉得好像算法有些复杂了呢

使用特权

评论回复
17
fsaok| | 2008-2-18 06:43 | 只看该作者

pic

pic用结构类去写,肯定占用更多的空间

使用特权

评论回复
18
yuntian|  楼主 | 2008-2-18 10:54 | 只看该作者

找到一个好方法

经过多次更改思路,问题解决了,楼上仁兄说得不对,俺以前是用汇编写了四年的程序后来才改C的,现在的方法比较巧的,
就是写了两个子程序,一个是日期比较程序,即比较两个日期是否相等,这个用循环可以做到,入口是两上日期的指针.
另一个程序是日期程序,即从分钟开终判断,看是否超过60分,超过则小时进位,同理天,月,年也累加,若是润年,则2月为29天.
再用一个循环把分钟逐分钟加,也是用指针,每加一次,进行一次日期标准化调整.调整后,再判断两个日期是否相等,连加30分钟,如果两个时间相差在30分钟内,则30分连加一定有一次相等,先对时间1相加30分,再对时间2连加60分钟,只要有相等则退出,完整解了问题.各位看还有更好的方法不?

使用特权

评论回复
19
forthlab| | 2008-2-18 12:23 | 只看该作者

5楼的正解!

LZ的思维太僵化了!作茧自缚啊!
可惜了你的春节了,不如出去好好玩玩,放松一下,开拓一下.

使用特权

评论回复
20
yuntian|  楼主 | 2008-2-18 13:34 | 只看该作者

TO:forthlab兄,看看这个你就知道僵化不?

if(CARRY)
    {if(ZERO)//当前大于过去年则月份加12个月
            {i=date.month;}
        else{i=date.month+12;}
        i=i-last_time.month;
        if(CARRY)//当前月大于等于过去月?
        {if(ZERO)
            {i=date.day;}
            else
            {i=days_month[last_time.month&0x0f]+date.day;
                if(last_time.month==2&&(last_time.year&0x03)==0)
                {i++;}
            }
            i-=last_time.day;
            if(CARRY)
            {if(ZERO)
                {i=date.hour;}
                else{i=date.hour+24;}
                i-=last_time.hour;
                if(CARRY)
                {if(ZERO)
                    {i=date.minute;}
                    else{i=date.minute+60;}
                    i-=last_time.minute;
                    if(CARRY)
                    {if(i>30)return(1);}
                }
                else
                {}
            }
        }

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

29

主题

178

帖子

1

粉丝