微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 帮忙看看这个软件定时的问题

帮忙看看这个软件定时的问题

时间:10-02 整理:3721RD 点击:

今天用UVersion4写了个软件定时程序,用的循环变量是unsigned int型,但发现一个奇怪的问题,当循环数设为32767和32768,它们的执行时间相差很离谱。这个刚好又是signed int的上界,但我试过改成unsigned char型,循环数设为127和128,执行时间基本一致。我试过在程序中加过long型变量记数器,确定它们执行的次数是正确的,32767就执行32767次,32768就执行32768次,就是时间不一致。
我试过调整优化级别,从0级常量折叠到8级重用代码入口都试过了,现象都一样,并且在UV4环境下仿真和真机(SST、STC芯片)执行都出现这种情况。
这现象仅从C代码来看是不可理喻的,小弟我对汇编又不太了解,看着UV4的编译代码也不知问题所在,还望各位前辈高手帮忙看看,编译器到底对这两种循环做了什么不同的处理。谢谢~~
以下是我用的UV版本信息:
IDE-Version:
μVision V4.53.0.6
Copyright (C) 2012 ARM Ltd and ARM Germany GmbH. All rights reserved.
License Information:
省略
Tool Version Numbers:
Toolchain:        PK51 Prof. Developers Kit  Version: 9.50a
Toolchain Path:    C:\Keil\C51\BIN
C Compiler:         C51.Exe       V9.50a
Assembler:          A51.Exe       V8.02b
Linker/Locator:     BL51.Exe       V6.22
Librarian:             LIB51.Exe       V4.29
Hex Converter:      OH51.Exe       V2.6
CPU DLL:               S8051.DLL       V3.84.0.1
Dialog DLL:         DP51.DLL       V2.62.0.1
Target DLL:             MON51.DLL       V2.45
Dialog DLL:         TP51.DLL       V2.58

下面是代码和UV中仿真的时序图

代码和UV4仿真的时序图


看图不方便,还是贴出代码了。运行结果可以直接看图。

#include

void main()
{
  bit which;
  unsigned int uint;
  unsigned long lng, p1, p2;
  bit in, ln;

  while(1)
  {
    if(which = ~which)
      for(lng = 0; lng < 5; lng++) //32767和32768相差很大,这正在signed int的上限处。为何已声明为unsigned int,却出现这现象
      {
        in = 1;
        for(uint = 0; uint < 32768; uint++) {_nop_(); p1++;}

        in = 0;
        for(uint = 0; uint < 32767; uint++) {_nop_(); p2++;}
      }
    else
      for(uint = 0; uint < 5; uint++) //用unsigned long来做比较,32767和32768相差根本不大
      {
        ln = 1;
        for(lng = 0; lng < 32768; lng++) _nop_();

        ln = 0;
        for(lng = 0; lng < 32767; lng++) _nop_();
      }
  }
}

从p1, p2的结果可知两个循环的次数是符合预期的。但就是时间相差太离谱。
我试过用unsigned char并把循环数改成127和128,结果就正确了。难道char是单字节就正确,而int是多字节就出错?这样的话,估计用unsigned long并把循环数设成signed long的上限与上限+1,应该都会出这问题。

“时间相差太离谱” 怎么测的这个时间呢?

我测试了一下,应该是32768这个地方的问题。你在32768后面加上一个u,即32768u,那么时间就是正确的。
应该是32768这个立即数是按int型常量来处理的。
建议以后在用无符号立即数的时候使用16进制。

哈哈,谢过塔吊兄了。刚试过,果真如此。

刚收到ARM公司工程师的回复,不是当成int,而是当成了long来处理了。看下时序图,32768那里真的是同long一致的。另外还可以通过C51选项设置禁止int扩容来达到。不过好似无这个必要。
顺便分享一下


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top