51单片机的几种精确延时

原创 2016年08月29日 23:43:27

实现延时通常有两种方法:一种是硬件延时,要用到定时器/计数器,这种方法可以提高CPU的工作效率,也能做到精确延时;另一种是软件延时,这种方法主要采用循环体进行。 今天主要介绍软件延时,关于硬件延时,之后定时器部分再做详细说明。

首先介绍单片机的几个周期

在电子技术中,脉冲信号是一个按一定电压幅度,一定时间间隔连续发出的脉冲信号。脉冲信号之间的时间间隔称为周期;而将在单位时间(如1秒)内所产生的脉冲个数称为频率。频率是描述周期性循环信号(包括脉冲信号)在单位时间内所出现的脉冲数量多少的计量名称;频率的标准计量单位是Hz(赫)。电脑中的系统时钟就是一个典型的频率相当精确和稳定的脉冲信号发生器。

指令周期:CPU执行一条指令所需要的时间称为指令周期,它是以机器周期为单位的,指令不同,所需的机器周期也不同。对于一些简单的的单字节指令,在取指令周期中,指令取出到指令寄存器后,立即译码执行,不再需要其它的机器周期。对于一些比较复杂的指令,例如转移指令、乘法指令,则需要两个或者两个以上的机器周期。通常含一个机器周期的指令称为单周期指令,包含两个机器周期的指令称为双周期指令。

时钟周期:也称为振荡周期,一个时钟周期 = 晶振的倒数。对于单片机时钟周期,时钟周期是单片机的基本时间单位,两个振荡周期(时钟周期)组成一个状态周期。

机器周期:单片机的基本操作周期,在一个操作周期内,单片机完成一项基本操作,如取指令、存储器读/写等。

机器周期=6个状态周期=12个时钟周期。

51单片机的指令有单字节、双字节和三字节的,它们的指令周期不尽相同,一个单周期指令包含一个机器周期,即12个时钟周期,所以一条单周期指令被执行所占时间为12*(1/ 晶振频率)= x μs。常用单片机的晶振为11.0592MHz,12MHz,24MHz。其中11.0592MHz的晶振更容易产生各种标准的波特率,后两种的一个机器周期分别为1 μs和2 μs,便于精确延时。

接下来列出这三种不同的晶振的延时函数

1、 11.0592MHz

//N ms延时
void delay_ms(uint n)
{
uint i,j;
for(i=n;i>0;i–)
for(y=114;y>0;y–);
}

2、12MHz晶振


//延时n毫秒
void delay_ms(unsigned int n)
{
    unsigned int i=0,j=0;
    for(i=0;i<n;i++)
        for(j=0;j<123;j++);
}

//延时n秒
void delay_m(unsigned int n)
{
    unsigned int i=0,j=0;
    for(i=0;i<n;i++)
        for(j=0;j<21738;j++);
}
//延时10*n微秒
void delay_10um(unsigned int n)
{
    while(n--);
}

3、24MHz晶振

//延时n毫秒
void delay_ms(unsigned int n)
{
unsigned int i=0,j=0;
for(i=0;i

//延时n秒  
void delay_s(unsigned int n)  
{  
    unsigned int i=0,j=0;  
    for(i=0;i<n;i++)  
        for(j=0;j<54053;j++);   
}  
//延时10*n微秒  
void delay_10us(unsigned int n)  
{  
    unsigned int i=0;  
    char j=0;  
    for(i=0;i<n;i++)  
        for(j=0;j<2;j++);  
}  

建议大家封装为头文件,可以方便的调用。

接下来介绍几个自动适应主时钟的延时函数

//参数:ms,要延时的ms数,自动适应主时钟  
#define MAIN_Fosc        11059200UL    //定义主时钟HZ  
typedef unsigned int INT16U;  

void delay_ms(INT16U ms)    //INT16U 等价于 unsigned int  
{  
    INT16U i;  
    do{  
        i=MAIN_Fosc/9600;  
        while(--i);     //96T per loop  
    }while(--ms);       //--ms  ms=ms-1  
}  
//5us 延时函数,自动适应主时钟  
#define MAIN_Fosc        11059200UL    //定义主时钟HZ  

void delay5us()  
{  
    #if MAIN_Fosc == 11059200  
        _nop_();  
    #elif MAIN_Fosc == 12000000  
        _nop_();  
    #elif MAIN_Fosc == 22118400  
        _nop_(); _nop_(); _nop_();  
    #elif  
}  

单片机中还可自动生成

//11.0592MHZ延时100微秒

void Delay100us()       //@11.0592MHz
{
    unsigned char i, j;

    _nop_();
    _nop_();
    i = 2;
    j = 15;
    do
    {
        while (--j);
    } while (--i);
}

//100US

void Delay100us()       //@12.000MHz
{
    unsigned char i, j;

    i = 2;
    j = 39;
    do
    {
        while (--j);
    } while (--i);
}

//100US

void Delay100us()       //@24.000MHz
{
    unsigned char i, j;

    i = 3;
    j = 82;
    do
    {
        while (--j);
    } while (--i);
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

【51单片机】延时函数计算问题以及如何准确延时

几种周期介绍 周期名称 描述 时间 振荡(时钟) 单片机提供时钟脉冲信号的振荡源的周期 T=1/f 状态 振荡周期经二分频后得到的 2T 机器 在一个机器周期内,CPU可以完成一...
  • wait_for_taht_day5
  • wait_for_taht_day5
  • 2016年01月15日 23:52
  • 9182

51单片机C语言延时函数

关键字:51单片机 C语言 延时函数      C程序中可使用不同类型的变量来进行延时设计。经实验测试,使用unsigned char类型具有比unsigned int更优化的代码,在使用时应该使...
  • shawsun
  • shawsun
  • 2014年04月26日 23:34
  • 9274

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

 
  • nataka
  • nataka
  • 2007年04月20日 11:23
  • 783

51单片机延时函数

  • 2017年12月01日 18:11
  • 15KB
  • 下载

【转】51单片机精确延迟程序

51单片机精确延时程序(晶振12MHz,一个机器周期1us.) 几个精确延时程序:在精确延时的计算当中,最容易让人忽略的是计算循环外的那部分延时,在对时间要求不高的场合,这部分对程序不会造成影响. ...
  • hunterlew
  • hunterlew
  • 2015年04月28日 20:11
  • 1632

STM32中通过普通延时函数来精确延时

在STM32中处处会用到延时函数,一般而言,对于普通的控制延时,并不会要求特别精确,所以可以使用普通的延时函数,例如 void delay(u32 time) { while(time--); }...
  • yunzhifeiti
  • yunzhifeiti
  • 2017年03月05日 15:13
  • 4220

STM32精确延时函数

  • 2014年03月06日 12:26
  • 830B
  • 下载

怎样编写精确的延时函数

实现延时通常有两种方法:一种是硬件延时,要用到定时器/计数器,这种方法可以提高CPU的工作效率,也能做到精确延时;另一种是软件延时,这种方法主要采用循环体进行。 1 使用定时器/计数器实现精确延时 ...
  • oathevil
  • oathevil
  • 2011年07月30日 23:19
  • 4311

C51延时函数delay的编写

例如,要写一个延迟10ms的delay函数:(12M晶振) void delay_10ms() { unsigned char i,j,k; for(i=5;i>0;i--) ...
  • u014453898
  • u014453898
  • 2017年02月26日 13:43
  • 935

STM32延时函数的三种方法——最好掌握第三种

单片机编程过程中经常用到延时函数,最常用的莫过于微秒级延时delay_us( )和毫秒级delay_ms( )。 1.普通延时法 这个比较简单,让单片机做一些无关紧要的工作来打发时间,经常用循环来...
  • luodonghuan1
  • luodonghuan1
  • 2015年06月20日 14:25
  • 15899
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:51单片机的几种精确延时
举报原因:
原因补充:

(最多只允许输入30个字)