zoukankan      html  css  js  c++  java
  • 51系列单片机的精确延时的解释(文章如有问题之处,请劳烦指正,谢谢!) 可以看看采纳下。

    /*----延时用的变量尽量用char或unsigned char来定义--------*/

    #include<intrins.h>
    //一. 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 (微秒)
    延时时间=[(2*第一层循环+3)*第二层循环+3]*第三层循环+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--);
    }
    //几毫秒秒时用此函数;延时时间=[(2*245+3)*2+3]*i+5(微秒),延时2毫秒最精确。
    void aa(unsigned char i)
    {
      unsigned char j,k;
      for(;i>0;i--)
        for(j=2;j>0;j--)
          for(k=245;k>0;k--);
    }
    //如果是微秒级延时的话,无需用调用函数,直接用单个for语句;
    //这时对晶振为12M单片机而定的情况;
    /*-------------------- 1us~511us延时语句 ----------------------*/
    /*
    用法:
    必须用char或unsigned char定义一个数 i;然后写出单个for语句;
    for(i=X;i>0;i--)
    注意:X必需是一个直接给的数,不用定义X;
    延时时间=( X*2+1 )微秒;
    如: ①for(i=1;i>0;i--) X=1; 延时时间=( X*2+1 )=3us;
    ②for(i=2;i>0;i--) X=2; 延时时间=( X*2+1 )=5us;
    ③for(i=10;i>0;i--) X=10; 延时时间=( X*2+1 )=21us;
    ④for(i=100;i>0;i--) X=100; 延时时间=( X*2+1 )=201us;
    因为i是字符型变量,故i不能大于255,即单个for语句的延时时间
    不能大于(255*2+1)=511微秒;也就是不大于0.511毫秒。
    */

    /*
    对一个变量int操作和char操作的指令时间不同,所以延时不一样,导致总线错误
    char是单字节变量,int是双字节变量,单字节变量自减1和双字节变量自减1耗费
    的CPU时间是不同的,换句话说,双字节变量自减1的操作时间要长于单字节变量,
    而你这个延时程序纯粹就是靠CPU循环进行固定次数的自减操作实现的,所以
    单字节变量变成双字节变量以后,自减操作的次数不变,延时时间会增长。
    */
    /*

    #include<intrins.h>里有延时指令 _nop_();
    _nop_();延时时间为一个机械周期=12个时钟周期的时间。
    时钟周期=1/晶振值。
    如12MHZ的晶振的单片机的时钟周期=1/12M=1/(12*10E5)=1/12000000= 1/12 微秒
    如1MHZ的晶振的单片机的时钟周期=1/1M=1/(1*10E5)=1/1000000= 1 微秒
    如24MHZ的晶振的单片机的时钟周期=1/24M=1/(24*10E5)=1/24000000= 1/24 微秒
    */

    /*
    2 软件延时与时间计算
    在很多情况下,定时器/计数器经常被用作其他用途,
    这时候就只能用软件方法延时。下面介绍几种软件延时的方法。

    2.1 短暂延时

    可以在C文件中通过使用带_NOP_( )语句的函数实现,定义一系列不同的延时函数,
    如Delay10us( )、Delay25us( )、Delay40us( )等存放在一个自定义的C文件中,
    需要时在主程序中直接调用。如延时10 μs的延时函数可编写如下:

    void Delay10us( )
    {
      _NOP_( );
      _NOP_( );
      _NOP_( );
      _NOP_( );
      _NOP_( );
      _NOP_( );
    }
    Delay10us( )函数中共用了6个_NOP_( )语句,每个语句执行时间为1 μs。
    主函数调用Delay10us( )时,先执行一个LCALL指令(2 μs),
    然后执行6个_NOP_( )语句(6 μs),最后执行了一个RET指令(2 μs),
    所以执行上述函数时共需要10 μs。 可以把这一函数当作基本延时函数,
    在其他函数中调用,即嵌套调用[4],以实现较长时间的延时;但需要注意,
    如在Delay40us( )中直接调用4次Delay10us( )函数,得到的延时时间将是42 μs,
    而不是40 μs。这是因为执行Delay40us( )时,先执行了一次LCALL指令(2 μs),
    然后开始执行第一个Delay10us( ),执行完最后一个Delay10us( )时,直接返回到主程序。
    依此类推,如果是两层嵌套调用,如在Delay80us( )中两次调用Delay40us( ),
    则也要先执行一次LCALL指令(2 μs),然后执行两次Delay40us( )函数(84 μs),
    所以,实际延时时间为86 μs。简言之,只有最内层的函数执行RET指令。
    该指令直接返回到上级函数或主函数。如在Delay80μs( )中直接调用8次Delay10us( ),
    此时的延时时间为82 μs。通过修改基本延时函数和适当的组合调用,
    上述方法可以实现不同时间的延时。

    */

  • 相关阅读:
    routing路由模式
    MQ的订阅模式
    RabbitMq中的消息应答与持久化
    work工作消息队列Round-robin与Fair dispatch
    040 关于hive元数据的解析
    simple简单消息队列
    用户设置与virtual host配置
    Mq的介绍
    字典
    元组Tuple
  • 原文地址:https://www.cnblogs.com/Blub-xinye1/p/5513545.html
Copyright © 2011-2022 走看看