zoukankan      html  css  js  c++  java
  • 关于51精确延时及keil仿真延时时间

    转自:http://blog.sina.com.cn/s/blog_980e19e00101b5dh.html

    有时候需要精确的延时,比如18B20温度传感器对时序要求非常严格,必须精确到微秒级别

    一、用NOP函数

    在keil C51中,直接调用库函数:

    #include // 声明了void _nop_(void);

    _nop_(); // 产生一条NOP指令

    作用:对于延时很短的,要求在us级的,采用“_nop_”函数,这个函数相当汇编NOP指令,延时几微秒。NOP指令为单周期指令,可由晶振频率算出延时时间,对于12M晶振,延时1uS。(若为11.0592MHz,延时为12*(1/11.0592)=1.085uS)。对于延时比较长的,要求在大于10us,采用C51中的循环语句来实现。

    二、用for和while实现

    在选择C51中循环语句时,要注意以下几个问题

    第一、定义的C51中循环变量,尽量采用无符号字符型变量。

    第二、在FOR循环语句中,尽量采用变量减减来做循环。

    第三、在do…while,while语句中,循环体内变量也采用减减方法。

    这因为在C51编译器中,对不同的循环方法,采用不同的指令来完成的。

    下面举例说明:

    unsigned char i;

    for(i=0;i<255;i++);

    unsigned char i;

    for(i=255;i>0;i--);

    其中,第二个循环语句C51编译后,就用DJNZ指令来完成,相当于如下指令:

    MOV 09H,#0FFH

    LOOP: DJNZ 09H,LOOP

    指令相当简洁,也很好计算精确的延时时间。

    同样对do…while,while循环语句中,也是如此

    例:

    unsigned char n;

    n=255;

    do{n--}

    while(n);

    n=255;

    while(n)

    {n--};

    这两个循环语句经过C51编译之后,形成DJNZ来完成的方法,

    故其精确时间的计算也很方便。

    其三:对于要求精确延时时间更长,这时就要采用循环嵌套的方法来实现,因此,循环嵌套的方法常用于达到ms级的延时。对于循环语句同样可以采用for,do…while,while结构来完成,每个循环体内的变量仍然采用无符号字符变量。

    unsigned char i,j

    for(i=255;i>0;i--)

    for(j=255;j>0;j--);

    unsigned char i,j

    i=255;

    do{j=255;

    do{j--}

    while(j);

    i--;

    }

    while(i);

    unsigned char i,j

    i=255;

    while(i)

    {j=255;

    while(j)

    {j--};

    i--;

    }

    这三种方法都是用DJNZ指令嵌套实现循环的,由C51编译器用下面的指令组合来完成的

    MOV R7,#0FFH

    LOOP2: MOV R6,#0FFH

    LOOP1: DJNZ R6,LOOP1

    DJNZ R7,LOOP2

    这些指令的组合在汇编语言中采用DJNZ指令来做延时用,因此它的时间精确计算也是很简单,假上面变量i的初值为m,变量j的初值为n,则总延时时间为:m×(n×T+T),其中T为DJNZ指令执行时间(DJNZ指令为双周期指令)。这里的+T为MOV这条指令所使用的时间。同样对于更长时间的延时,可以采用多重循环来完成。

    只要在程序设计循环语句时注意以上几个问题。

    下面给出有关在C51中延时子程序设计时要注意的问题

    1、在C51中进行精确的延时子程序设计时,尽量不要或少在延时子程序中定义局部变量,所有的延时子程序中变量通过有参函数传递。

    2、在延时子程序设计时,采用do…while,结构做循环体要比for结构做循环体好。

    3、在延时子程序设计时,要进行循环体嵌套时,采用先内循环,再减减比先减减,再内循环要好。

    unsigned char delay(unsigned char i,unsigned char j,unsigned char k)

    {unsigned char b,c;

    b="j";

    c="k";

    do{

    do{

    do{k--};

    while(k);

    k="c";

    j--;};

    while(j);

    j=b;

    i--;};

    while(i);

    }

    这精确延时子程序就被C51编译为有下面的指令组合完成

    delay延时子程序如下:

    MOV R6,05H

    MOV R4,03H

    C0012: DJNZ R3, C0012

    MOV R3,04H

    DJNZ R5, C0012

    MOV R5,06H

    DJNZ R7, C0012

    RET

    假设参数变量i的初值为m,参数变量j的初值为n,参数变量k的初值为l,则总延时时间为:l×(n×(m×T+2T)+2T)+3T,其中T为DJNZ和MOV指令执行的时间。当m=n=l时,精确延时为9T,最短;当m=n=l=256时,精确延时到16908803T,最长。

    以上参考http://wenku.baidu.com/view/e79d80c40c22590102029da1.html

    三、下面介绍一下如何用keil仿真延时时间

    测试函数:

    void TempDelay (unsigned char idata us)

    {

    while(us--);

    }

    测试用例:

    TempDelay(80); //530uS

    TempDelay(14); //100uS

    NOP; //1.085uS

    操作:

    1、打开调试

    关于51精确延时及keil仿真延时时间

    2、起始时间为0.00059136s

    关于51精确延时及keil仿真延时时间

    3、执行了TempDelay(80)后时间为0.00112413s,用时0.00053277s=532.77uS
    关于51精确延时及keil仿真延时时间
    4、到这里起始时间为0.00112630s
    关于51精确延时及keil仿真延时时间
    5、执行了TempDelay(14)后,变为0.00122938s,用时0.00010308s=103.08uS
    关于51精确延时及keil仿真延时时间
    6、这是执行了一次NOP指令(晶振为11.0592MHz,单片机为STC89C52),时间为0.00123047s,用时0.00000109s=1.09uS
    关于51精确延时及keil仿真延时时间

  • 相关阅读:
    vscode 基本知识以及如何配置 C++ 环境
    计算机视觉
    GitHub 大事件
    tf 2.0
    AI 公司与比赛
    Faster RCNN 学习与实现
    pycahrm安装说明
    python 并发之线程
    python 并发之进程
    python socketserver ftp上传功能
  • 原文地址:https://www.cnblogs.com/shirishiqi/p/5407790.html
Copyright © 2011-2022 走看看