• 已解决 73482 个问题
  • 已帮助 5993 位优秀工程师

两个数(每个数都是几个数相乘的积)比较大小出现异常

SingleYork 2016-08-11 浏览量:1386
本帖最后由 SingleYork 于 2016-8-12 18:44 编辑

如题,51单片机中,在程序中设置两个数SetTime、RunTime,比较这两个数的大小,均是unsigned long类型,其中:




SetTime = SetDay*24*60*60 + SetHour*60*60;


即:将设置的“天数”跟设置的“小时数”换算成“秒数”,再赋值给SetTime ,也就是SetTime 的单位为:秒;SetDay、SetHour均为unsigned char类型;


RunTime = Day*24*60*60+Hour*60*60+Min*60+Sec;


原理同SetTime一样,也是全部换算成秒来做比较;其中Day、Hour、Min、Sec也均为unsigned char类型;


RunTime是由定时器产生,具体方式如下(为了减少等待时间,数据做了处理,最终结果是:1小时相当于10秒钟):





换算完成之后,再将两个数做对比,若RunTime>SetTime,则输出一个信号:





那么问题来了:


当我设置SetDay=0;SetHour=1;时,也就是1个小时,RunTime大于10秒(之前有说明,为了缩短等待时间做的数据处理,1小时等于10秒)时就会给出一个信号;
当我设置SetDay=0;SetHour=2;时,也就是2个小时,RunTime大于20秒时就会给出一个信号;
当我设置SetDay=0;SetHour=3;时,也就是3个小时,RunTime还是大于20秒时就会给出一个信号;
当我设置SetDay=0;SetHour=4;时,也就是4个小时,RunTime还是大于20秒时就会给出一个信号;

后面的问题差不多,就不一一列出来了!


特在此求助大神!
PS:经过各路大神的解答,初步判定是if(Hour>1)这个条件的问题,按照如下方式改,问题暂时解决,至于问题是否真是如此以及程序中其他的问题,还得多几天验证才能知道!感谢各路大神!



延续:
按照如上更改了之后,SetHour设置在18以下,输出等待时间是对的,设置SetHour=19或以上还是有问题,具体现象如下:
设置 19时 等待10秒输出设置 20 时 等待30秒输出设置 21时 等待50秒输出设置 22时 等待50秒输出设置 23时 等待50秒输出
而且等待的时长好像不是完全固定的,有时候10秒,有时候20秒……求解!
虽然最佳答案选择了“999”这个热心小伙伴的,也确实一开始是有这个问题,所以他的回答是正确的,至于后来我发现了另外一个问题,又不想重新发帖,于是在本帖的后面追加了问题点,其实问题的根本还是如“MOP”所说,是计算过程中数据溢出的问题:详见15楼




但是无奈啊,最佳答案只能选一个呀,所以只好委屈“MOP”同学了,按照你所说的,我试了,确实也能解决问题,不过我之前也是用的强制类型转换,如下:


SetTime = (unsigned long)SetDay*24*60*60 + (unsigned long)SetHour*60*60




这样也确实解决了问题,所以最根本的问题,还是计算过程中数据溢出的问题,在此,也非常感谢MOP同学热心解答!



1 0 收起

我来回答

上传资料:
选择文件 文件大小不超过15M(格式支持:doc、ppt、xls、pdf、zip、rar、txt)
最佳答案
  • Hour++;
    if (Hour > 1)
    {
    Hour=0;
    Day++;
    }

    就是这里啦。
    第一次进这个判断时是第10s,Hour等于1。
    第二次进这个判断时是第20s,Hour等于2。于是条件成立:if(Hour>1){Day++;},根据你上边的公式把Day代入计算,等式必然成立,于是就输出了信号。
    • 发布于 2016-08-11
    • 举报
    • 评论 0
    • 0
    • 0

其他答案 数量:20
  • 为啥感觉你的定时器做的有点问题呢
    • 发布于2016-08-11
    • 举报
    • 评论 0
    • 0
    • 0

  • 本帖最后由 LiuYang 于 2016-8-11 19:26 编辑

    确实是定时器的问题。第一次进到中断里,证明已经到达定时器的溢出值,这时计时是正确的。
    然而在计算过程中将CNT清零,也就是改变了定时器中断的时间了,那么下一次进入中断的时间也就不是设定好的值了。
    将定时器设置为自动重装清零模式,在中断的计算过程里不要加入对定时器的操作,这样时间就准了。
    • 发布于2016-08-11
    • 举报
    • 评论 0
    • 0
    • 0

  • 你中断中:
    小时>1后
    天就++了
    • 发布于2016-08-11
    • 举报
    • 评论 0
    • 0
    • 0

  • LiuYang 发表于 2016-8-11 19:14
    确实是定时器的问题。第一次进到中断里,证明已经到达定时器的溢出值,这时计时是正确的。
    然而在计算过程 ...

    感谢刘总,不过工作模式就是设置的自动重装……定时器工作在0模式……也就是16位自动重装……
    • 发布于2016-08-12
    • 举报
    • 评论 0
    • 0
    • 0

  • 999 发表于 2016-8-11 21:33
    Hour++;
    if (Hour > 1)
    {

    恩,这确实是其中一个问题,这可能是我昨天修改后没改回去造成的,之前这个地方是23还是有同样的问题,现在改了貌似问题暂时得到解决,我还得多次验证一下,才知道是不是真的是这个问题,感谢热心解答……
    • 发布于2016-08-12
    • 举报
    • 评论 0
    • 0
    • 0

  • Hour++;
    if (Hour > 1)
    {
    Hour=0;
    Day++;
    }
    你的定时器函数里面,Hour的判断条件是>1,所以Hour最大值就是为2,所以就出现了你后面无论设置多大值都没有用的结果;另外还有一个问题,if (Hour > 1)的条件成立后,Hour就被你赋值为0了。
    • 发布于2016-08-12
    • 举报
    • 评论 0
    • 0
    • 0

  • SingleYork 发表于 2016-8-12 08:15
    感谢刘总,不过工作模式就是设置的自动重装……定时器工作在0模式……也就是16位自动重装…… ...

    那么在中断函数里就不要再操作CNT寄存器了
    • 发布于2016-08-12
    • 举报
    • 评论 0
    • 0
    • 0

  • 已经推到论坛首页,希望能帮助楼主把问题尽快解决!
    • 发布于2016-08-12
    • 举报
    • 评论 0
    • 0
    • 0

  • 18*60*60=64800
    19*60*60=68400
    而两字节最大表示数为65535
    这种巧合让我想到你这编译器是不是unsigned long类型其实只要俩字节
    纯属猜测:lol
    • 发布于2016-08-12
    • 举报
    • 评论 0
    • 0
    • 0

  • 如题,51单片机中,在程序中设置两个数SetTime、RunTime,比较这两个数的大小,均是unsigned long类型,其中:



    SetTime = SetDay*24*60*60 + SetHour*60*60;


    即:将设置的“天数”跟设置的“小时数”换算成“秒数”,再赋值给SetTime ,也就是SetTime 的单位为:秒;SetDay、SetHour均为unsigned char类型; (unsigned char = int), 所以你assign時候,右邊已經Overflow了,因為右邊全部都是int
    故:
    SetTime = SetDay*24L*60L*60L + SetHour*60L*60L;


    RunTime = Day*24*60*60+Hour*60*60+Min*60+Sec;
    同理:
    RunTime = Day*24L*60L*60L+Hour*60L*60L+Min*60L+Sec;


    原理同SetTime一样,也是全部换算成秒来做比较;其中Day、Hour、Min、Sec也均为unsigned char类型;

    以上試試吧!! 祝好運:)
    • 发布于2016-08-12
    • 举报
    • 评论 0
    • 0
    • 0

  • 本帖最后由 999 于 2016-8-12 15:01 编辑

    你不是已经做了强制转换吗?又改了帖子?。。囧
    • 发布于2016-08-12
    • 举报
    • 评论 0
    • 0
    • 0

  • MOP 发表于 2016-8-12 12:33
    如题,51单片机中,在程序中设置两个数SetTime、RunTime,比较这两个数的大小,均是unsigned long类型,其 ...

    我听STC的技术说好像常数后面加L会好些,我没试过,但是我用另外一种方法,就是强制类型转换,貌似就没有问题了,至少暂时是没有问题了……非常感谢你的热心解答……
    • 发布于2016-08-12
    • 举报
    • 评论 0
    • 0
    • 0

  • 999 发表于 2016-8-12 14:47
    你不是已经做了强制转换吗?又改了帖子?。。囧

    恩,之前的强制类型转换应该是对的,错误的原因应该是如你所说,Hour>1这个条件,后面我把这个条件改成23了,然后还是出问题,后面我又用强制转换,貌似问题暂时得到了解决!哎!原来都是一时疏忽惹的祸呀……
    • 发布于2016-08-12
    • 举报
    • 评论 0
    • 0
    • 0

  • 999与MOP都被楼主采纳,根据悬赏求助奖励办法,社区分别都奖励300IC币!
    • 发布于2016-08-15
    • 举报
    • 评论 0
    • 0
    • 0

相关问题

问题达人换一批

两个数(每个数都是几个数相乘的积)比较大小出现异常