51单片机的定时器0结构
51单片机是一种广泛应用于嵌入式系统中的芯片,具有强大的计时和计数功能。其中的定时器0可以用来实现精确的1毫秒定时。本文将介绍如何配置和编写代码来实现这一功能。
首先,我们需要了解51单片机的定时器0相关的寄存器和工作原理。定时器0使用两个8位寄存器TH0和TL0来存储定时器的初值,采用16位定时模式。定时器0的时钟源可以是外部时钟源或者时钟源T0引脚。在1毫秒定时的情况下,我们一般使用系统时钟作为定时器0的时钟源。
定时器的模式
1.工作方式寄存器TMOD
TMOD高4位为T1工作方式配置,低4位为T0工作方式配置。
GATE:软件启动定时器计数器或者硬件启动定时器计数器。
GATE=0:以TR0/TR1来启动定时/计数器运行。即定时/计数器的运行只受TCON中运行控制位TR0/TR1的控制。TR0或TR1置1即可启动定时器0或1。
GATE=1:用TR0/TR1和外中断输入引脚(INT0和INT1)上的高电平来启动定时/计数器运行。即控制位TR0或TR1须置1,同时还须(P3.2)或(P3.3)为高电平方可启动定时器。
C/T:计数/定时方式选择位。
C/T=0为定时器,C/T=1为计数器。
M1与M0工作的方式
配置的定时器0的方式
接下来,我们需要配置定时器0的工作模式。
配置定时器0的工作方式需要设置TMOD寄存器的相应位。我们将TMOD寄存器设置为0x01,即使用方式1。
在配置完定时器0的工作方式后,我们还需要设置定时器0的初值。由于我们需要实现1毫秒定时,初值可以通过以下公式计算得出:
定时/计数器工作于方式1,构成一个16位的定时/计数器。内部计数器为16位,由TLx作低8位,THx作高8位组成。
首先,我们需要计算定时器0的初值。定时器0的初值可以通过以下公式来计算:
初值 = 65536 - (定时时间 / 机器周期)
其中,定时时间是你所期望的定时时间,单位为毫秒;机器周期是单片机的时钟周期,可以通过晶振频率来计算,公式为:
机器周期 = 1 / (晶振频率 / 12)
假设你期望的定时时间为1毫秒,晶振频率为12MHz,则计算过程如下:
机器周期 = 1 / (12MHz / 12) = 1μs
初值 = 65536 - (1ms / 1μs) = 65536 - 1000 = 64536
因此,你可以将定时器0的初值设置为64536,即可实现1毫秒的定时。
最后,我们需要编写中断服务函数来处理定时器0的中断。定时器0中断的标志位TF0会在定时溢出时置位,我们可以在中断服务函数中判断该标志位是否被置位,如果是,则进行相应的操作。
配置EA =1 开启总中断,ET0 = 1开启定时器0中断TR0 = 1 启动定时器0;
在本例中,我们可以在中断服务函数中加入一个计数器,每次定时器0溢出时,计数器加一。当计数器达到1000时,表示已经过去了1秒。
配置的程序代码内容
配置一个定时器0定时1ms的led灯一直反转的代码:
下面是51单片机定时器0定时1ms的代码:
#include<reg52.h>
sbit led = P1^0; // 定义LED连接的IO口
void Timer0_Init()
{
TMOD |= 0x01; // 设置定时器0为模式1
TH0 = (65536-1000)/256; // 高8位赋初值
TL0 = (65536-1000)%256; // 低8位赋初值
EA = 1; // 开启总中断
ET0 = 1; // 开启定时器0中断
TR0 = 1; // 启动定时器0
}
void Timer0_ISR() interrupt 1 // 定时器0中断函数
{
TH0 = (65536-1000)/256; // 高8位赋初值
TL0 = (65536-1000)%256; // 低8位赋初值
led = ~led; // 翻转LED状态
}
void main()
{
Timer0_Init(); // 初始化定时器0
while(1); // 无限循环
}
通过以上配置和代码,我们可以实现51单片机的1毫秒定时功能。让led灯在中断服务函数中每1毫秒反转,我们可以根据需要进行相应的操作。这种定时功能在嵌入式系统中非常常见,可以应用于各种实时任务的处理。