51单片机延时的方法,看这一篇就够了

方法一:
这种方法常用于单片机。定义一个延时函数,一般函数名定义为delay  C语言定义延时函数主要通过无意义指令(空指令)的执行来达到延时的目的。

查看代码
 方案1:
void delay(unsigned int i)
{
  while(  i--);
}
方案2:
void delay(unsigned int i)
{
  unsigned int w;
  for(w=0;w<i;w++);
}

我们使用方法一,调试看看实际时间(书上说执行1w次空语句相当于1s),我们来看看:
测试代码:

查看代码
 #include"reg51.h"
sbit P13=P1^3;

void Delay(float s)		//@11.030MHz
{
	long k=s*10000;
	while(k--);
}

void main()
{
	while(1)
{	 
	P13=0;
	Delay(1);
	P13=1;
	Delay(1);
	}
}

效果:

结论,1w次空语句,相当于0.4s。

显而易见,推荐方法1,更简便。


方法二:
使用intrins.h头文件里的_nop_()函数;网上都是说一共_nop_();表1us。经实操发现,该函数更适用与us秒ms级的延时,大于0.5s的延时,用本函数写,延时越大误差(也许是程序执行以外的语句所需消耗的时间,所以设置的延时时间越大,误差就越大)。例:

查看代码
void Delay()		//@11.030MHz
{
	unsigned long i,j;
	i = 10;
	while(i--){
	j=1000;
	while (j--)
	_nop_();
	}
}

调试发现:1.0786s

又例:

void Delay()		//@11.030MHz
{
	unsigned long i,j;
	i = 1000;
	while(i--){
	j=1000;
	while (j--)
	_nop_();
	}
}


调试:

如果不用定时器 有没有更准的方法?
根据板子晶振在stc-lsp自动生成代码(8051指令集Y1的1000ms含nop函数):

代码示例:

查看代码
void Delay100us()		//@11.030MHz
{
	unsigned char i, j, k,h;
	h=100;    //延时100s
	while(h--){
	_nop_();
	i = 7;
	j = 253;
	k = 55;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
	}
}

调试效果:


附:非定时器nop函数较准确的模板:

查看代码
void Delay(float s)		//@11.030MHz
{
	unsigned char i, j;
    int k=s*10;
	while(k--){		//里边是100ms
	i = 179;
	j = 208;
	do
	{
		while (--j);
	} while (--i);
	}
}

可以看到这样嵌套执行空语句179*208=37232次,就是100ms,那么我们根据方法1,不嵌套试试?
代码示例:

void Delay(long s)		//@11.030MHz
{
	long k=s*37232;		//10ms*s
	while(k--);
}
void main()
{
	while(1)
{	 
	P13=0;
	Delay(100);	 //延时100s
	P13=1;
	Delay(100);
	}
}

效果:

误差太离谱。

 

经多次测试,即使是stc-lsp生成的软件延时(方法二的方案1,2),有时候也还是存在误差,我们实操的时候没这么多时间检查修改的,示例:

查看代码
 #include"reg51.h"
#include<intrins.h> 
sbit P13=P1^3;
#define uint unsigned int 

void Delay(float s)		//@11.030MHz
{
	unsigned char i, j;
    long k=s*1000;
	while(k--){		//里边是1ms
	_nop_();
	i = 2;
	j = 198;
	do
	{
		while (--j);
	} while (--i);
}
}

void main()
{
	while(1)
{	 
	P13=0;
	Delay(100);	 //延时100s
	P13=1;
	Delay(10);  //延时10s
	}
}

效果:


某些时刻还是存在问题的,定时器才是最准确的。

虽然 非定时器nop函数较准确的模板 秒小的时候几乎无误差,但是定时器还是最规范准确的用法。所以,精准延时一律用定时器,其他延时都用方法1的方案1。

posted @ 2022-01-30 01:06  iZJ"Qq4577105  阅读(4073)  评论(0编辑  收藏  举报