【蓝桥杯】单片机精确延时——软件延时

在编写单片机程序经常会用到延时,做到精确延时的方法有两种:软件延时(采用循环体实现)和硬件延时(定时器/计数器实现)。

补充_nop_()函数

  1. C语言中没有_nop_()函数,该函数是在51单片机中用的延时函数,延时一个指令周期。在单片机c语言中直接调用库函数即可:#include<intrins.h> // 声明了void nop(void);
  2. 编写延时函数的时候,要注意,在调用此函数时,需要一个调用指令,即LCALL指令消耗两个周期(2us),延时函数执行完后要返回主调函数,需要一个返回指令,即RET指令(2us)。
  3. 例如用6MHz的晶振,则如下for循环大约延时1秒。
    int i;
    for(i=0; i<6000000; i++)
    nop(); // 延时一个指令周期,相当于执行一条无意义的语言
  1. 指令周期(机器周期=1指令周期):CPU执行一条指令所需要的时间称为指令周期,它是以机器周期为单位的。通常含一个机器周期的指令称为单周期指令,包含两个机器周期的指令称为双周期指令。

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

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

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

一个机器周期(即一条单周期指令)被执行所占时间为12*(1/ 晶振频率)= x μs。
12MHZ的晶振:一个机器周期=12*[1/(12*10^6)]秒=1微秒

附上常用延时函数
  1. 11.0592MHz晶振
//延时n毫秒 ms
void delay_ms(usigned int n)
{
    
    
usigned int i,j;
for(i=n;i>0;i–)
for(y=114;y>0;y–);
}
  1. 12MHz晶振
//延时n毫秒 ms
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秒 s
void delay_m(unsigned int n)
{
    
    
    unsigned int i=0,j=0;
    for(i=0;i<n;i++)
        for(j=0;j<21738;j++);
}
  1. 24MHz晶振
//延时n秒  s
void delay_s(unsigned int n)  
{
    
      
    unsigned int i=0,j=0;  
    for(i=0;i<n;i++)  
        for(j=0;j<54053;j++);   
}  

猜你喜欢

转载自blog.csdn.net/z3447643805/article/details/113403859