51单片机 - 关于延时函数的总结

在总结延时函数前,有必要先说明一下:

机器周期在使用12M晶振时是1us;在使用11.0592M晶振时是1.09us。

1、1us的延时函数

想要准确延时1us,直接使用一个空指令就能实现。

2、当我们想要准确延时几十微秒以上的时间时,推荐使用软件延时。

例如以下程序:

void Delay_us(unsigned char us)
{
	while(us--);
}

这个程序的工作过程:

       1、 如果不执行while(us--); (也就是当us = 0时),这个函数一共需要14us的时间;

        2、而 while(us--); 每执行一次消耗约6us的时间。

经过示波器测量后,确定这个函数任意us值的延时都是非常准确的。

2、当我们想要准确延时1ms及以上,推荐使用定时器进行延时。

使用定时器进行延时涉及定时器的知识,网上也有很文章讲的很详细,这里就不细说。

3、最后放上我使用示波器校正后的延时程序 “Delay.c” 。

#include <reg52.h> 
#include "Delay.h" 

/** 
 * 函数名称:	Timer0_Init
 *
 * 功能说明:	定时器0的初始化
 *
 * 参数说明:	无
 *
 * 函数返回:	无
 */
void Timer0_Init()
{
	TMOD &= 0xF0;	// 清除定时器0工作模式配置(保留定时器1工作模式配置)
	TMOD |= 0x01;  	// 配置定时器0工作模式1(16位定时器模式)
	TF0 = 0;      	// 清除溢出中断标志位
	TR0 = 0;      	// 停止定时器
}

/** 
 * 函数名称:	Delay_us(14us - 1ms)
 *
 * 功能说明:	1、 最低延时14us(当us=0时);
 *				2、 us加1,则延时增加6us;
 *				3、 最高延时1ms
 * 				4、 误差为0
 *
 * 参数说明:	us - 要延时的微秒数
 *
 * 函数返回:	无
 */
void Delay_us(unsigned char us)
{
	while(us--);
}

/** 
 * 函数名称:	Delay_ms(1ms - 1min)
 *
 * 功能说明:	1、 最低延时1ms(当ms=1时);
 *				2、 ms加1,则延时增加1ms;
 *				3、 最高延时1分钟
 *				4、 ms越大,误差越大. ms = 1 时误差为0,延时1分钟时误差为3%
 *
 * 参数说明:	ms - 要延时的毫秒数
 *
 * 函数返回:	无
 */
void Delay_ms(unsigned int ms)
{
	/* 循环一次则完成一次1ms的延时 */
	while(ms--)
	{
		/* 设置定时器初值 */
		/* 40是示波器修正值 */		
		TH0 = (65536-1000+40) >> 8;  			// 定时器初值高字节
		TL0 = (65536-1000+40) & 0xFF;			// 定时器初值低字节

		/* 启动定时器 */
		TR0 = 1;

		/* 等待定时器溢出 */
		while (TF0 == 0); 		// 等待定时器溢出标志位被置位

		/* 关闭定时器 */
		TR0 = 0;
		TF0 = 0; 				// 清除溢出标志
	}
}

在主程序对定时器0进行初始化 Timer0_Init() 后,就能直接使用Delay_ms()

对于几微秒的延时,推荐直接使用空指令就可以了

以上都是基于12M晶振下进行校准的,用于11.0592M晶振的延时误差也很小,11.0592M晶振1ms延时误差大约在0.1ms以内。

当然使用这样的延时会有程序死等的弊端,有更好的设计希望大家指导一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值