51单片机之定时器中断
模式3仅Timer0可用,Timer1 在模式 3 下停止工作,但仍可配置为其他模式。2.机器周期,传统8051单片机中,1个机器周期=12个时钟周期(如12MHz晶振对应1μs)。:置0=由 TRx 位控制定时器启停,置1=由 TRx 和 INTx 引脚共同控制。3.指令周期,执行一条指令所需的机器周期数,有单周期指令、双周期指令、四周期指令。:置0=定时器模式(内部时钟),置1=计数器模式(外
一、单片机的时序知识:
当外接晶振为12MHZ,51单片机的相关周期:
1.时钟周期(振荡周期)为
=
us
2.机器周期,传统8051单片机中,1个机器周期=12个时钟周期(如12MHz晶振对应1μs)。
3.指令周期,执行一条指令所需的机器周期数,有单周期指令、双周期指令、四周期指令。
二、定时器的工作原理:
定时器的本质就是计数器。定时器的工作原理是基于一个16位的加1计数器,由高8位和低8位两个寄存器THx和TLx组成。每当接收到一个脉冲,计数器的值就会自动加1,当计数器的值达到最大值(
=65535)时,就会产生溢出,并触发中断请求。
三、51单片机的定时器:
以AT89C51为例,包含两个定时器:Timer0 和 Timer1。每个定时器有四种工作模式,通过TMOD寄存器配置。
1.定时器的四种工作模式:
模式0:使用 THx(高 8 位) + TLx 的低 5 位,共 13 位计数器(最大计数
=8192)。
模式1:使用 THx(高 8 位) + TLx (低 8 位),共 16 位计数器(最大计数
=65536)。
适用于需要长周期定时的场合(如延时、PWM 生成)。
模式2(8 位自动重装定时器):
TLx 作为计数器,THx 存储重装初值,TLx 溢出后,自动从 THx 重装初值,无需软件干预。适用于高频定时任务(如串口通信波特率生成)。
模式3(双 8 位定时器):
Timer0 拆分为两个独立 8 位定时器,
TL0:独立 8 位定时器,使用 Timer0 的控制位(TR0、TF0)。
TH0:独立 8 位定时器,借用 Timer1 的控制位(TR1、TF1)。
注意:模式0、模式1在溢出后需软件重装初值;模式3仅Timer0可用,Timer1 在模式 3 下停止工作,但仍可配置为其他模式。
2.定时器工作模式的寄存器配置:
通过 TMOD(Timer Mode Control Register,地址 0x89) 配置 Timer0 和 Timer1 的工作模式:
-
低 4 位(Bit0~Bit3):配置 Timer0 的模式和功能(定时器/计数器)。
-
高 4 位(Bit4~Bit7):配置 Timer1 的模式和功能。
关键位:

-
M1/M0:选择模式(00=模式0,01=模式1,10=模式2,11=模式3)。
-
C/T:置0=定时器模式(内部时钟),置1=计数器模式(外部引脚 T0/T1 输入)。
-
GATE:置0=由 TRx 位控制定时器启停,置1=由 TRx 和 INTx 引脚共同控制。
如下图以定时器0的模式1为例,定时器的工作/配置原理图:

SYSclk(时钟周期):可以选择12分频和6分频。通过12分频可以得出来一个机器周期。
3.定时器初值的计算:
假设定时时间为T,
机器周期 = 12 / 晶振频率(单位秒)
计数值 = 定时时间T / 机器周期
初值 = 最大计数值 - 计数值
THx= 初值/256
TLx= 初值%256
例如在12MHz晶振下,使用定时器0模式1,如何计算1ms的定时初值:
这时候机器周期是1微秒,1ms需要1000个机器周期。初值就是65536 - 1000 = 64536
TH0=64536/256=0xFC TL0=64536%256=0x18
四、定时器的配置流程:
-
1.对寄存器TMOD赋值,确定定时器Timer0 和 Timer1 的工作模式
-
2.根据要定时的时间来计算好初值,并对THx、TLx赋值
-
3.配置寄存器TCON,开启定时器Timer0 / Timer1的中断
-
4.对TR0 / TR1置1,启动定时器
接下来以12MHz晶振,使用定时器0来产生中断,控制LED灯间隔1秒闪烁:
#include<reg51.h>
sbit LED = P1^1; //定义LED引脚
void timer0_init() //定时器0初始化函数
{
TMOD = 0x01; //选择定时器0为工作模式1
TH0 = 64536/256;
TL0 = 64536%256; //定时1ms的TH,TL值
EA = 1; //开启总中断开关
ET0 = 1; //开启定时器0中断开关
TR0 = 1; //置1开始计时,为0停止计时
}
void main()
{
timer0_init();
while(1);
}
void timer0_ISR() interrupt 1
{
static unsigned int i=0; //定义静态变量
TH0 = 64536/256;
TL0 = 64536%256; //对TH,TL初值重装
i++;
if(i==1000) //经过了1000次中断,即1s
{
i=0;
LED=!LED; //LED间隔闪烁
}
}
更多推荐



所有评论(0)