精华内容
下载资源
问答
  • 本文主要简单介绍了51单片机延时函数
  • 参考了51单片机 Keil C 延时程序的简单研究,自己也亲身测试和计算了一些已有的延时函数
  • 51单片机延时函数

    千次阅读 多人点赞 2019-11-13 10:48:54
    指令周期 :几个机器周期能完成一项基本操作,但一条...机器周期:8051系列单片机的机器周期=12*时钟周期,之所以这样分是因为单个时钟周期根本干不了一件完整的事情(如取指令、写寄存器、读寄存器等),而12个时钟...

    指令周期 :几个机器周期能完成一项基本操作,但一条指令常常是需要多项基本操作结合才能完成,完成一条指令所需的时间就是指令周期,当然不同的指令,其指令周期就不一样。通常含一个机器周期的指令称为单周期指令,包含两个机器周期的指令称为双周期指令。
    机器周期:8051系列单片机的机器周期=12*时钟周期,之所以这样分是因为单个时钟周期根本干不了一件完整的事情(如取指令、写寄存器、读寄存器等),而12个时钟周期就能基本完成一项基本操作了。
    时钟周期:时钟周期=振荡周期,名称不同而已,都是等于单片机晶振频率的倒数,如常见的外接12M晶振,那它的时钟周期=1/12M。
    机器周期=12个时钟周期。
    下面是三者关系图
    在这里插入图片描述
    一、软件延时
    1.1 普通软件延时函数是这样的,在晶振频率在11.0592Mhz的时候,内层 i=114.为什么是114呢?因为程序经过在keil中运行,计算出一次自减时间约为8.7us。
    所以在1ms自减运算的次数为: 1000/8.7=114
    在这里插入图片描述
    1.2自动 适应主时钟 的延时函数。

    在这里插入图片描述
    时钟频率:1秒钟CPU震动的次数;STC89C52是11.0592MHZ 也就是 11059200HZ;在1秒内有11059200个时钟周期。
    //96T per loop :每一条自减语句需要96个时钟周期,需要96个脉冲
    在这里插入图片描述
    所以 i=MAIN_Fosc/9600;

    展开全文
  • 一个非常好的51单片机辅助工具,可以生成各T的延时函数代码,还有串口波特率等基本功能(已破解)
  • 51单片机C语言延时函数怎么定义和使用

    万次阅读 多人点赞 2019-01-06 17:38:04
    C语言定义延时函数主要通过无意义指令的执行来达到延时的目的。C程序中可使用不同类型的变量来进行延时设计。经实验测试,使用unsigned char类型具有比unsigned int更优化的代码,在使用时应该使用unsigned char作为...

    C语言定义延时函数主要通过无意义指令的执行来达到延时的目的。C程序中可使用不同类型的变量来进行延时设计。经实验测试,使用unsigned char类型具有比unsigned int更优化的代码,在使用时应该使用unsigned char作为延时变量。
      以某晶振为12MHz的单片机为例,晶振为12MHz即一个机器周期为1us。现在定义一个延时xms毫秒的延时函数。

     void delay(unsigned int xms) // xms代表需要延时的毫秒
          {
          unsigned int x,y;
          for(x=xms;x>=0;x--)
          for(y=110;y>=0;y--);
          }
    

    1.51单片机C语言延时函数的使用
    下面给出一些经典的延时函数,(1)500ms延时子程序如下:

    void delay500ms(void)
    {
      unsigned char i,j,k;
      for(i=15;i>=0;i--)
      for(j=202;j>=0;j--)
      for(k=81;k>=0;k--);
    }
    

    计算分析:程序共有三层循环,一层循环n:R52 = 812 = 162us DJNZ 2us;二层循环m:R6*(n+3) = 202165 = 33330us DJNZ 2us + R5赋值 1us = 3us;三层循环: R7(m+3) = 1533333 = 499995us DJNZ 2us + R6赋值 1us = 3us
    循环外: 5us 子程序调用 2us + 子程序返回 2us + R7赋值 1us = 5us
    延时总时间 = 三层循环 + 循环外 = 499995+5 = 500000us =500ms
    计算公式:延时时间=[(2
    R5+3)*R6+3]*R7+5
    (2)200ms延时子程序:

    void delay200ms(void)
    {
      unsigned char i,j,k;
      for(i=5;i》0;i--)
      for(j=132;j》0;j--)
      for(k=150;k》0;k--);
    }
    

    (3)10ms延时子程序:

    void delay10ms(void)
    {
      unsigned char i,j,k;
      for(i=5;i》0;i--)
      for(j=4;j》0;j--)
      for(k=248;k》0;k--);
    }
    

    (4)1s延时子程序:

    void delay1s(void)
    {
      unsigned char h,i,j,k;
      for(h=5;h》0;h--)
      for(i=4;i》0;i--)
      for(j=116;j》0;j--)
      for(k=214;k》0;k--);
    }
    

    关于单片机C语言的精确延时,网上很多都是大约给出延时值没有准确那值是多少,也就没有达到精确高的要求,而本函数克服了以上缺点,能够精确计数出要延时值且精确达到1us,本举例所用CPU为STC12C5412系列12倍速的单片机,只要修改一下参数值其它系例单片机也通用,适用范围宽。
    共有三条延时函数说明如下:
      函数调用分两级:一级是小于10US的延时,二级是大于10US的延时

    //小于10US的【用1US级延时】

    //----------微秒级延时---------

    for(i=X;i》X;i–) 延时时间=(3+5*X)/12 提示(单位us, X不能大于255)

    //======大于10US《小于21.9955Ms的可用【10US级延时函数】=

    void Delay10us(uchar Ms)
    {
      uchar data i;
      for(;Ms》0;Ms--)
      for(i=26;i》0;i--);
    }
    

    i=[(延时值-1.75)*12/Ms-15]/4
      如想延时60US则 i=[(60-1.75)*12/6-15]/4=25.375≈26; 修改i的值=26,再调用上面的【10US级延时函数】Delay10us(6); 则就精确延时60US;如果想延时64US可以用这二种函数组合来用: Delay10us(6); for(i=9;i》X;i–) 共延时64US
      关于单片机C语言的精确延时,网上很多都是大约给出延时值没有准确那值是多少,也就没有达到精确高的要求,而本函数克服了以上缺点,能够精确计数出要延时值且精确达到1us,本举例所用CPU为STC12C5412系列12倍速的单片机,只要修改一下参数值其它系例单片机也通用,适用范围宽。

    共有三条延时函数说明如下:

    函数调用分两级:一级是小于10US的延时,二级是大于10US的延时

    //小于10US的【用1US级延时】

    //----------微秒级延时---------

    for(i=X;i》X;i–) 延时时间=(3+5*X)/12 提示(单位us, X不能大于255)

    //======大于10US《小于21.9955Ms的可用【10US级延时函数】=

    void Delay10us(uchar Ms)
    {
      uchar data i;
      for(;Ms》0;Ms--)
      for(i=26;i》0;i--);
    }
    

    i=[(延时值-1.75)*12/Ms-15]/4
      如想延时60US则 i=[(60-1.75)*12/6-15]/4=25.375≈26; 修改i的值=26,再调用上面的【10US级延时函数】Delay10us(6); 则就精确延时60US;
      如果想延时64US可以用这二种函数组合来用: Delay10us(6); for(i=9;i》X;i–) 共延时64US
    2.下面给出有关在C51中延时子程序设计时要注意的问题(一些经验之谈)

    (1)、在C51中进行精确的延时子程序设计时,尽量不要或少在延时子程序中定义局部变量,所有的延时子程序中变量通过有参函数传递。
     (2)、在延时子程序设计时,采用do…while,结构做循环体要比for结构做循环体好。
     (3)、在延时子程序设计时,要进行循环体嵌套时,采用先内循环,再减减比先减减,再内循环要好。

    一. 500ms延时子程序产生的汇编:

    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
    

    二.200ms延时子程序产生的汇编

    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延时子程序产生的汇编:

    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延时子程序产生的汇编

    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
    

    3.另外一些关于延时的例子
    http://www.ceet.hbnu.edu.cn/bbs/viewthread.php?TId=3749,作者:小秋

    晶振:12MHz

    1:5~500us

    void delay(unsigned char i)
    {
      while(--i) ;
    }
    

    计算方法:ix2+5 可完成5~515us的延时

    2:10us~2ms

    void delay(unsigned char i)
    {
      for( ;i》0 ;i--) ;
    }
    

    计算方法:ix8+10 可完成10us~2.050ms的延时

    3:2ms~130ms

    void delay(unsigned char i,unsigned char j)
    {
      for( ;j》0 ;j--)
      for( ;i》0 ;i--) ;
    }
    

    计算方法:(ix2+3)xj+5 u


    转载自:http://www.elecfans.com/emb/580729_a.html

    展开全文
  • // 描述: 延时函数。 // 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟. // 返回: none. // 版本: VER1.0 // 日期: 2013-4-1 // 备注: //==========================================================...
  • 本文给大家分享了51单片机精确延时函数集锦。
  • 51单片机C语言us级延时函数

    千次阅读 2020-05-30 10:53:53
    Shawsun2014-04-26 23:34:21 C程序中可使用不同类型的变量来进行延时设计。经实验测试,使用unsigned ... 以某晶振为12MHz的单片机为例,晶振为12MHz即一个机器周期为1us。 一. 500ms延时子程序 程序: void de...

    转载自:https://blog.csdn.net/shawsun/article/details/24560255

    Shawsun 2014-04-26 23:34:21

         C程序中可使用不同类型的变量来进行延时设计。经实验测试,使用unsigned char类型具有比unsigned int更优化的代码,在使用时应该使用unsigned char作为延时变量。 以某晶振为12MHz的单片机为例,晶振为12MHz即一个机器周期为1us。

    一. 500ms延时子程序

    程序:

    void delay500ms(void)

    {

    unsigned char i,j,k;

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

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

    for(k=81;k>0;k--);

    }

    计算分析:

    程序共有三层循环

    一层循环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;

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

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

    for(k=150;k>0;k--);

    }

    三. 10ms延时子程序

    程序:

    void delay10ms(void)

    {

    unsigned char i,j,k;

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

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

    for(k=248;k>0;k--);

    }

    四. 1s延时子程序

    程序:

    void delay1s(void)

    {

    unsigned char h,i,j,k;

    for(h=5;h>0;h--)

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

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

    for(k=214;k>0;k--);

    }

    关于单片机C语言的精确延时,网上很多都是大约给出延时值没有准确那值是多少,也就没有达到精确高的要求,而本函数克服了以上缺点,能够精确计数出要延时值且精确达到1us,本举例所用CPU为STC12C5412系列12倍速的单片机,只要修改一下参数值其它系例单片机也通用,适用范围宽。

    共有三条延时函数说明如下:

    函数调用分两级:一级是小于10US的延时,二级是大于10US的延时

    //====================小于10US的【用1US级延时】====================

    //----------微秒级延时---------

    for(i=X;i>X;i--) 延时时间=(3+5*X)/12 提示(单位us, X不能大于255)

    //================大于10US<小于21.9955Ms的可用【10US级延时函数】===========

    void Delay10us(uchar Ms)

    {

    uchar data i;

    for(;Ms>0;Ms--)

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

    }

    i=[(延时值-1.75)*12/Ms-15]/4

    如想延时60US则 i=[(60-1.75)*12/6-15]/4=25.375≈26; 修改i的值=26,再调用上面的【10US级延时函数】Delay10us(6); 则就精确延时60US;

    如果想延时64US可以用这二种函数组合来用: Delay10us(6); for(i=9;i>X;i--) 共延时64US

    四. 1s延时子程序

    程序:

    void delay1s(void)

    {

    unsigned char h,i,j,k;

    for(h=5;h>0;h--)

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

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

    for(k=214;k>0;k--);

    }

    关于单片机C语言的精确延时,网上很多都是大约给出延时值没有准确那值是多少,也就没有达到精确高的要求,而本函数克服了以上缺点,能够精确计数出要延时值且精确达到1us,本举例所用CPU为STC12C5412系列12倍速的单片机,只要修改一下参数值其它系例单片机也通用,适用范围宽。

    共有三条延时函数说明如下:

    函数调用分两级:一级是小于10US的延时,二级是大于10US的延时

    //====================小于10US的【用1US级延时】====================

    //----------微秒级延时---------

    for(i=X;i>X;i--) 延时时间=(3+5*X)/12 提示(单位us, X不能大于255)

    //================大于10US<小于21.9955Ms的可用【10US级延时函数】===========

    void Delay10us(uchar Ms)

    {

    uchar data i;

    for(;Ms>0;Ms--)

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

    }

    i=[(延时值-1.75)*12/Ms-15]/4

    如想延时60US则 i=[(60-1.75)*12/6-15]/4=25.375≈26; 修改i的值=26,再调用上面的【10US级延时函数】Delay10us(6); 则就精确延时60US;

    如果想延时64US可以用这二种函数组合来用: Delay10us(6); for(i=9;i>X;i--) 共延时64US
    ————————————————
    版权声明:本文为CSDN博主「Shawsun」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/shawsun/article/details/24560255

    展开全文
  • 51单片机1ms延时程序

    2020-07-20 04:27:17
    本文为51单片机1ms延时程序,希望对你的学习有所帮助
  • 51单片机延时函数计算问题以及如何准确延时

    万次阅读 多人点赞 2016-01-15 23:52:09
    单片机提供时钟脉冲信号的振荡源的周期 T=1/f 状态 振荡周期经二分频后得到的 2T 机器 在一个机器周期内,CPU可以完成一个独立的操作 12T 指令 指CPU完成一条操作所需的全部时间 12-12nT 指令: 1、MUL、...

    几种周期介绍




    周期名称描述时间
    振荡(时钟)单片机提供时钟脉冲信号的振荡源的周期T=1/f
    状态振荡周期经二分频后得到的2T
    机器在一个机器周期内,CPU可以完成一个独立的 操作12T
    指令指CPU完成一条操作所需的全部时间12-12nT

    指令:

    1、MUL、DIV:仅有的4周期指令

    2、包含DPTR和PC的指令均为2周期指令

    3、所有的绝对跳转和条件转移指令,均为2周期指令

    4、所有包括A寄存器的指令,均为单周期指令

    5、位操作指令中,ANL和ORL是2周期指令

    6、所有包含立即地址的指令,除INC direct及DEC direct外,均为2周期指令

    7、剩下的均为单周期指令。



    STC-ISP软件查看各操作用时以及延时函数




    _nop_函数可以在keil软件的C51->HLP->C51lib.chm文档中查阅  (授人以鱼不如授人以渔)




    延时函数计算


    示例:

    void delay(uint z)
    
    {
    
    	uint i,j;
    
    	for(i=z;i>0;i--)
    
    		for(j=0;j<921;j++);
    
    }

    分析:

    1.先计算你单片机的振荡(时钟)周期 T= 1/晶振(11.0592MHZ)

    2.一次i--操作为12T

    3.忽略变量定义,上述延时函数共需时间:921*z*12T

    4.带入T:921*12*T*z 约为 z ms



    计算出现误差的原因


    1.软件仿真时,函数调用的时候入栈出栈操作的耗时。

    2.指令周期随指令的不同而不同导致的误差。

    3.中断的影响。

    4.变量的范围超过,从而与预计时间不一样。


    所以实际上我们应该只能算出估计值,根据最开始周期的信息来计算延时函数中延时的时长。

    展开全文
  • #include sbit P1_0 = P1^0; void Delay(); // 下面引用时一定要和这里的大小写一致否则会有警告或错误 void Main() ...while (1) // 开始一直循环 ...这要从单片机的周期说起,单片机有指令周期,机器
  • 51单片机延时计算

    万次阅读 多人点赞 2019-01-28 09:34:13
    51单片机延时计算前言正文首先是时钟周期的算法:时钟周期(T)=1(秒)/晶振频率。(比如:上面代码的时钟周期为1/12M(秒))。其次是机器周期:机器周期是由时钟周期组成的,机器周期是单片机完成一个基本操作...
  • 51单片机C语言延时函数

    万次阅读 多人点赞 2014-04-26 23:34:21
    关键字:51单片机 C语言 延时函数    C程序中可使用不同类型的变量来进行延时设计。经实验测试,使用unsigned char类型具有比unsigned int更优化的代码,在使用时应该使用unsigned char作为延时变量。 以某...
  • 1)一个是最多只能生成循环变量为3的延时函数,延时长达多秒时显然三个循环变量已经不足,给出的是错误的延时函数。 2)检查发现当初始化循环变量为0时,Keil C51 编译器会编译为: CLR A MOV Rx,A 而非...
  • 这篇的篇幅很短,所以小编大家希望耐心看完,相信你看完以后对定时器和延时函数有个全新的理解。 首先,我们要对定时器和延时函数有一个简单的了解。 1. 定时器 什么是定时器? 定时器就像是闹钟,清晨将你吵醒,...
  • STC系列51单片机延时程序汇总

    千次阅读 2020-07-15 09:08:03
    答应大家得福利来啦,这一期我就给大家分享一下STC系列51单片机延时程序汇总。 11.0592MHz晶振(延时1ms): (1)Y1指令集 适用于SCT89C系列,STC90C系列、STC89LE系列、STC90LE系列 void Delay1ms() //11.0592...
  • #include <reg51.h> #define uchar unsigned char void delay60s(); void main(void) { while(1) { P1=0x00; delay60s(); P1=0xff; delay60s(); } } void delay60s() { uchar i,t; TMOD=0x01; for (i=...
  • 51单片机的几种精确延时

    万次阅读 多人点赞 2016-08-29 23:43:27
    实现延时通常有两种方法:...首先介绍单片机的几个周期在电子技术中,脉冲信号是一个按一定电压幅度,一定时间间隔连续发出的脉冲信号。脉冲信号之间的时间间隔称为周期;而将在单位时间(如1秒)内所产生的脉冲个数称
  • 经测试 误差小于0.4%
  • 基于51单片机的精确延时(微秒级)对于某些对时间精度要求较高的程序,用c 写延时显得有些力不从心,故需用到汇编程序。 本人通过测试,总结了51 的精确延时函数(在c 语言中嵌入汇编)分享给大家。至于如何在c 中嵌入...
  • 不要慌,其实我们这节课要用到的就一句话—— 在51单片机中1个机器周期由6个状态周期组成,也就是12个时钟周期=12 x 1/12 us =1 us 这里我们知道了一个机器周期的时间是1us,所以如果我们要延时1ms就是1000个机器...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,913
精华内容 3,565
关键字:

51单片机延时函数