【51单片机】定时器产生指定延迟的delay函数

本文介绍了一段用于STM32的自定义延时函数,允许用户根据需要调整定时器初值以实现不同长度的延时。代码中详细展示了如何配置定时器0工作在模式1,设置初值以产生1ms的延时,并通过查询方式等待定时器溢出。此外,还提供了STC89C52的头文件片段,包含了一些基本的SFR(特殊功能寄存器)定义,方便在Keil环境中使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 可以自己输入的延迟时间,灵活性高
  2. 下面代码定时1ms,用户可以自行更改定时器初值
void delay(unsigned int n)//STC89C52,晶振:11.0592MHZ
{
   
   	
	int i;
	for(i=0;i<n;i++)
	{
   
   
		TMOD &= 0xF0;		
		TMOD |= 0x01;		//定时器0,工作模式1
		TH0 = 0xFC;			//至初值
		TL0 = 0x66;			//定时1ms
		TF0 = 0;			//清除溢出标志
		TR0 = 1;			//开启定时器0
		EA=0;				//关中断(使用查询方式)
		ET0=0;				//关T0中断
		while(TF0 == 0);	//溢出等待
		TR0 = 0;			//暂停定时器
	}
}

后附上STC89C52的头文件,如果有小伙伴Keil里没有STC的话,可以新建一个STC89C52.h头文件,然后直接复制下面的代码到,并添加该头文件到工程文件夹中,最后便可以在main.c里#include。

#ifndef __STC89C5xRC_RDP_H__
#define __STC89C5xRC_RDP_H__

/////////////////////////////////////////////////

/* The following is STC additional SFR */

/* sfr  AUXR  = 0x8e; */
/* sfr  AUXR1 = 0xa2; */
/* sfr  IPH   = 0xb7; */

sfr  P4  = 0xe8;
sbit P46 = P4^6;
sbit P45 = P4^5;       //ISPÏÂÔØÐè¹´Ñ¡"ALE½ÅÓÃ×÷P4.5¿Ú"
sbit P44 = P4^4;
sbit P43 = P4^3;
sbit P42 = P4^2;
sbit P41 = P4^1;
sbit P40 = P4^0;

sfr  XICON = 0xc0;

sfr  WDT_CONTR = 0xe1;

sfr ISP_DATA  = 0xe2
<think>嗯,用户想找关于51单片机定时器1的延时函数实现或使用方法的示例代码。我需要结合他们提供的引用资料来回答。首先,引用里提到定时器的初始化和中断服务函数,比如引用1中的timer_init函数可以同时初始化定时器0和1,用户可能需要定时器1的具体配置。引用2中的延时函数使用了定时器中断来更新计数器,这样主程序不会被阻塞。引用3和4提到了定时器的工作模式和中端服务程序的结构。用户需要的是定时器1的延时函数,所以应该用定时器1的中断来实现。首先,初始化定时器1,设置工作模式。51单片机定时器1通常有几种工作模式,比如模式1是16位定时器。需要计算定时器的初值,比如12MHz晶振下,50ms的定时可能需要TH1和TL1的值。然后在中断服务函数里累加计数,达到指定次数后完成延时。另外,用户可能需要阻塞和非阻塞两种方式的代码。阻塞方式是在主循环中等待标志位,而非阻塞方式可能更适合多任务。引用4中的例子用了静态变量来保存计数,这样中断函数可以独立运行,不影响主程序。需要确保中断服务函数的编号正确,定时器1的中断号是3吗?或者是其他?需要确认51单片机的中断向量表,定时器0是中断1,定时器1是中断3?可能还需要考虑定时器1用作波特率发生器时的情况,但用户的问题没有提到串口,所以暂时不用处理。代码示例应该包括初始化函数、中断服务函数以及如何使用延时函数。比如,主函数里调用timer1_delay_ms(1000)来实现1秒延时。同时,要处理全局变量或静态变量来记录中断次数,并注意重装定时器初值以避免误差累积。 需要检查代码的正确性,比如定时器模式设置是否正确,中断是否启用,总中断是否打开。另外,示例代码中的注释是否清晰,用户能否理解每个步骤的作用。可能还需要提醒用户根据实际晶振频率调整定时器初值的计算。</think>### 51单片机定时器1延时函数实现方法 #### 1. 定时器1初始化配置 定时器1需配置为**16位自动重装载模式**(模式1),并开启中断。以下为初始化函数示例: ```c void Timer1_Init() { TMOD &= 0x0F; // 清除定时器1原有配置 TMOD |= 0x10; // 定时器1设为模式1(16位定时器) TH1 = 0xFC; // 初始值高位(假设12MHz晶振,定时1ms) TL1 = 0x66; // 初始值低位 ET1 = 1; // 开启定时器1中断 TR1 = 1; // 启动定时器1 EA = 1; // 开启总中断 } ``` *注:初值计算基于公式 $TH1 = (65536 - t \cdot f_{osc}/12)/256$,$TL1 = (65536 - t \cdot f_{osc}/12)\%256$,其中 $t$ 为定时时间(秒)*[^2][^4]。 #### 2. 中断服务函数延时控制 在中断中维护延时计数器: ```c volatile unsigned int timer1_counter = 0; // 全局计数器 void Timer1_ISR() interrupt 3 { // 定时器1中断号为3 TH1 = 0xFC; // 重装初值 TL1 = 0x66; timer1_counter++; // 计数器递增 } ``` #### 3. 阻塞式延时函数实现 ```c void Timer1_Delay_ms(unsigned int ms) { timer1_counter = 0; // 重置计数器 while(timer1_counter < ms); // 等待达到目标时间 } ``` #### 4. 非阻塞式延时框架 ```c // 主循环中检测 if(timer1_counter >= target_delay) { // 执行延时任务 timer1_counter = 0; // 重置计数器 } ``` #### 关键点说明 1. **初值计算**:12MHz晶振下,1ms定时对应初值 $TH1=0xFC$, $TL1=0x66$ 2. **误差控制**:需在中断中**手动重装载**初值以避免模式1无自动重装导致的误差[^3] 3. **中断优先级**:若系统中有多个中断,需设置IP寄存器优先级
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

文武好呆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值