一. 500ms延时子程序

void delay500ms(void)
{
    unsigned char i,j,k;
    ;i>;i--)
    ;j>;j--)
    ;k>;k--);
}

产生的汇编:

C:0x0800      7F0F       MOV        R7,#0x0F

C:0x0802      7ECA       MOV        R6,#0xCA

C:0x0804      7D51       MOV        R5,#0x51

C:0x0806      DDFE       DJNZ       R5,C:0806

C:0x0808      DEFA       DJNZ       R6,C:0804

C:0x080A      DFF6       DJNZ       R7,C:0802

C:0x080C      22          RET

计算分析:

  程序共有三层循环

  一层循环n:R5*2 = 81*2 = 162us                    DJNZ    2us

  二层循环m:R6*(n+3) = 202*165 = 33330us            DJNZ    2us + R5赋值 1us = 3us

  三层循环: R7*(m+3) = 15*33333 = 499995us          DJNZ    2us + R6赋值 1us = 3us

  循环外:     5us            子程序调用 2us + 子程序返回 2us + R7赋值 1us    = 5us

  延时总时间 = 三层循环 + 循环外 = 499995+5 = 500000us =500ms

计算公式:延时时间=[(2*R5+3)*R6+3]*R7+5

二. 200ms延时子程序

void delay200ms(void)
{
    unsigned char i,j,k;
    ;i>;i--)
    ;j>;j--)
    ;k>;k--);
}

产生的汇编

C:0x0800      7F05       MOV        R7,#0x05

C:0x0802      7E84       MOV        R6,#0x84

C:0x0804      7D96       MOV        R5,#0x96

C:0x0806      DDFE       DJNZ       R5,C:0806

C:0x0808      DEFA       DJNZ       R6,C:0804

C:0x080A      DFF6       DJNZ       R7,C:0802

C:0x080C      22           RET

三. 10ms延时子程序

void delay10ms(void)
{
    unsigned char i,j,k;
    ;i>;i--)
    ;j>;j--)
    ;k>;k--);
}

产生的汇编

C:0x0800      7F05       MOV        R7,#0x05

C:0x0802      7E04       MOV        R6,#0x04

C:0x0804      7DF8       MOV        R5,#0xF8

C:0x0806      DDFE       DJNZ       R5,C:0806

C:0x0808      DEFA       DJNZ       R6,C:0804

C:0x080A      DFF6       DJNZ       R7,C:0802

C:0x080C      22         RET

四. 1s延时子程序

void delay1s(void)
{
    unsigned char h,i,j,k;
    ;h>;h--)
    ;i>;i--)
    ;j>;j--)
    ;k>;k--);
}

1s延时的验证:

1.      设置仿真的晶振为12MHz

2.   在延时函数设置断点

3. 单步运行程序,到达延时函数的入口

4.   先记下进入延时函数的时间

5.   step out 跳出函数,记下此时时间,两个时间相减即为延时函数运行时间

函数运行时间=1.00041400-0.00041600≈1s

产生的汇编

C:0x0800      7F05       MOV        R7,#0x05

C:0x0802      7E04       MOV        R6,#0x04

C:0x0804      7D74       MOV        R5,#0x74

C:0x0806      7CD6       MOV        R4,#0xD6

C:0x0808      DCFE       DJNZ       R4,C:0808

C:0x080A      DDFA       DJNZ       R5,C:0806

C:0x080C      DEF6       DJNZ       R6,C:0804

C:0x080E      DFF2       DJNZ       R7,C:0802

C:0x0810      22         RET

在精确延时的计算当中,最容易让人忽略的是计算循环外的那部分延时,在对时间要求不高的场合,这部分对程序不会造成影响.

void mDelay(unsigned int Delay) //Delay = 1000 时间为1S
{
    unsigned int i;
    ;Delay--)
    {
        ;i<;i )
        {;} 

    }
}

void waitms(int i)
{
    char m; 

    for( ; i ;i--)
   {
      ; m ; m--)
      {
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
      }
   }
} 

延时1ms的函数 
时钟频率12MHz

unsigned int sleepTime;
unsinged ; 

void sleepService(void)
{
    if (inSleep) sleepTime--;
    ) inSleep = ;
} 

void isr_timer(void) //假定定时器中断1ms 中断一次。
{
    ...
    sleepService();
    ...
} 

void sleep(unsigned int ms) //延时子程序
{
    sleepTime = ms;
    inSleep = ;
    while(inSleep);
} 

void main(void)
{
    ....
    sleep(); //延时 1秒
    ...
} 

如果要求是秒级的这么长的延时,单片机中一般采取不占CPU时间的延时,利用定时器来实现延时,如果非得用循环延时,在C中也通常嵌入汇编实现,这样误差比较小。

51单片机 Keil C 延时程序的简单(晶振12MHz,一个机器周期1us.)的更多相关文章

  1. 51单片机 Keil C 延时程序的简单研究

    应用单片机的时候,经常会遇到需要短时间延时的情况.需要的延时时间很短,一般都是几十到几百微妙(us).有时候还需要很高的精度,比如用单片机驱动DS18B20的时候,误差容许的范围在十几us以内,不然很 ...

  2. [51单片机] Keil C51中变量的使用方法详解

    引言    8051内核单片机是一种通用单片机,在国内占有较大的市场份额.在将C语言用于51内核单片机的研究方面,Keil公司做得最为成功.由于51内核单片机的存储结构的特殊性,Keil C51中变量 ...

  3. [学习笔记]15个QA让你快速入门51单片机开发

    一.C语言相关 Q1:sbit与sfr代表是什么?有什么作用? Q2:#define OSC_FREQ  22118400L这句宏命令里的“L”是什么意思? Q3:我粘贴了别人的代码,怎么发现没有un ...

  4. (1)51单片机NOP指令

    提问:什么是NOP指令?干什么用的?单片机程序里执行一条nop指令需要多长时间? (1)一个NOP就是一个机器周期 (2)空指令,延时一个机器周期 (3)这个与单片机型号.指令类型和使用的晶振频率有关 ...

  5. 基于51单片机个LCD1602的万年历程序

    小白 第一次跟新博客 基于51单片机和LCD1602的万年历程序 可实现走时和调时功能 有简单的1602菜单制作 欢迎大家交流 LCD1602和51单片机的连接方法 RS = P3^5; //数据/命 ...

  6. 【零基础】入门51单片机图文教程(Proteus+Keil)

    参考资料: https://www.jianshu.com/p/88dfc09e7403 https://blog.csdn.net/feit2417/article/details/80890218 ...

  7. 简单的51单片机多任务操作系统(C51)

    在网上看到这段代码,所以自己尝试了,可以跑起来,但是没有精确的定时功能,仅仅是任务的调度而已. 数组中是11,而不是12.这里写错了... /* 简单的多任务操作系统 其实只有个任务调度切换,把说它是 ...

  8. Keil uVision4 创建51单片机工程

    Keil uVision4 创建51单片机工程 版权声明:未经授权,严禁转载! 在学习51单片机的过程当中,我们需要使用 Keil uVision4 来创建一个项目,今天就来图示一下创建的流程. 首先 ...

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

    转自:http://blog.sina.com.cn/s/blog_980e19e00101b5dh.html 有时候需要精确的延时,比如18B20温度传感器对时序要求非常严格,必须精确到微秒级别 一 ...

随机推荐

  1. 利用powershell进行远程服务器管理(命令行模式)

    Pssession,Pssession是Windows Powershell会话的意思,一个会话,可以共享数据,提供交互式的对话,我们可以为某些命令例如Invoke-Command 制定会话来远程作业 ...

  2. 左移运算符<<

    在许多计算机编程语言(例如:C语言.C++语言.Java语言.JavaScript语言,Pascal语言等)中,“<<”代表左移运算符(就相当于'shl').该运算符为双目运算符,结合方向 ...

  3. Oracle V$SESSION

    SADDR session address SID session identifier 常用于链接其他列 SERIAL# SID有可能会重复,当两个session的SID重复时,SERIAL#用来区 ...

  4. 【Hibernate步步为营】--继承映射具体解释

    上篇文章讨论了多对多映射,在使用多对多映射时重点是使用<many-to-many>标签,并在标签的两端加入外键这样在生成关系时会创建两个关系之间的关系表,通过关系表来维护它们之间的关系,另 ...

  5. struts2,hibernate,spring整合笔记(4)--struts与spring的整合

    饭要一口一口吃,程序也要一步一步写, 很多看起来很复杂的东西最初都是很简单的 下面要整合struts和spring spring就是我们的管家,原来我们费事费神的问题统统扔给她就好了 先写一个测试方法 ...

  6. Android 快速开发系列 打造万能的ListView GridView 适配器

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38902805 ,本文出自[张鸿洋的博客] 1.概述 相信做Android开发的写 ...

  7. Java基础知识强化27:Object类之toString()方法

    1. Object类的toString()方法: public  String  toString():返回该对象的字符串表示 2. 案例演示: (1)Student类: package cn.itc ...

  8. yii criteria select column as 与 时间段查询

    需要查询某时间段的记录,但是数据库里只有一个时间记录,如果写sql的话,很快的,放到yii里一时竟然没办法... 不过,最后还是解决了,使用了一个第三方的插件 参考http://www.yiifram ...

  9. Mui实现退出登录

    document.getElementById("logout").addEventListener("tap",function(){ var btn=[&q ...

  10. ListActivity ListView 使用 介绍 用法

    ListActivity简单的说就是ListView和Activity的结合,跟ListView和Activity组合实现的没有什么很大的差别,主要是比较方便. 在实现时,要注意: 1.一般情况,Li ...