目录
一、定时器简介:
51单片机定时器是一种常用的计时/计数功能模块,用于测量时间间隔、生成精确的定时信号或控制外部设备。
它是以Intel 8051单片机为代表的系列单片机中的一个重要功能模块。51单片机通常具有多个定时器,例如常见的定时器/计数器0和定时器/计数器1。每个定时器都可以根据需要配置为不同的工作模式,如定时模式、计数模式、PWM模式等。
定时器的工作原理是基于一个内部振荡源(通常是晶体振荡器)产生的时钟信号。这个时钟信号根据定时器的预设值进行计数,当计数值与预设值相等时,定时器会产生一个中断或触发一些特定的动作,从而实现计时或控制功能。
在定时模式下,定时器可以被配置为一次性定时或循环定时。一次性定时表示定时器在达到预设值后只触发一次中断或动作,而循环定时表示定时器在达到预设值后会自动重新计数,连续触发中断或动作。在计数模式下,定时器可以被配置为对外部事件进行计数。例如,可以将一个外部信号连接到定时器的输入引脚,当外部事件发生时,定时器会自动计数。除了计时和计数功能,定时器还可以用于产生PWM(脉宽调制)信号。PWM信号可以用来控制电机速度、调节LED亮度等应用。
通过合理配置和使用定时器,可以充分发挥51单片机的计时/计数能力,实现各种实时控制和测量应用。
二、定时器框架:
1、相关寄存器说明及使用
1.1 TMOD(计数器设置)
1.2 TCON(中断寄存器设置)
TCON:控制寄存器,作用是控制定时器的启、停,标志定时器溢出和中断情况。
TF1 :TF1=1表示T1有中断产生。(Timer Flag,定时器标志位)
TR1 :TR1=1表示T1开始运行。(单片机中T0引脚,需要高低电平的驱动)
TF0 :TF0=1表示T0有中断产生。
TR0 :TR0=1表示T0开始运行。(单片机中T1引脚,需要高低电平的驱动)
IE1 :IE1=1表示INT1有中断产生。
IT1 :IT1=1表示INT1为下降沿触发,IT1=0表示INT1为低电平触发。
IE0 :IE0=1表示INT0有中断产生。
IT0 :IT0=1表示INT0为下降沿(负跳变)触发,IT0=0表示INT0为低电平触发。
1.3 IE(中断允许位设置)
中断允许寄存器 IE (A8H)
EA :整体中断允许位;EA=1允许中断。(使用中断就要打开)
ET2 :T2中断允许位;ET2=1允许中断(S52才有)。
ES :串行中断允许位;ES=1允许中断。 ET1 :T1中断允许位;ET1=1允许中断。
EX1 :INT1中断允许位;EX1=1允许中断。 ET0 :T0中断允许位;ET0=1允许中断。
EX0 :INT0中断允许位;EX0=1允许中断。
1.4 TH(定时器存储配置)
TH0/TH1/TH2 为定时器存储寄存器高八位(High)
-
TL0/TL1/TL2 为定时器存储寄存器低八位(Low)
-
不同频率晶振产生的机器周期不一样:
-
公式为:机器周期=晶振频率/12。这是在该晶振频率下每秒产生多少M机器周期。
-
根据晶振的不同设置不同的计时时间
-
比如当晶振频率为11.0592M的晶振。则每秒可产生机器周期为11.0592/12=0.9216M的机器周期,也就是921600个机器周期。50ms等于0.05秒,所以需要921600*0.05=46080个机器周期;定时器在方式1工作,为16位,最大值为65536,所以需设初值为65536-46080=19456;转为16进制为(4c00),所以高位TH0=0x4c; TL0=0x00;
2、示例代码
//代码:(用定时器实现LED灯的闪烁)
#include<reg52.h>
void main()
{
unsigned char cnt=0; //定义一个计数变量,记录T0溢出次数
TMOD = 0x01; //设置T0为模式1:16位定时计数器2^16(0~65535)0代替65536了
TH0 = 0xB8; //TH0 = 64536/256 ;高8位
TL0 = 0x00; //TL0 = 64536%256 ;总体T0赋值为0xB800,计时20ms
TR0 = 1; //启动定时器T0
while(1)
{
if(TF0 ==1) //判断是否溢出
{
TF0 = 0;//T0溢出后,清零中断标志
TH0 = 0xB8; //并重新赋值
TL0 = 0x00; //计时20ms
cnt++;
if(cnt>=50)//判断T0溢出是否达到50次
{
cnt = 0;
LED = ~LED;
}
}
}
}
//代码(用定时器实现led灯闪烁)
#include<reg52.h>
sbit led = P1^0;
int i = 0;
void timer1_init()
{
TMOD = 0x10; //定时器0选择工作方式1
TH1 = 0x4C; //设置初始值,定时50ms
TL1 = 0x00;
EA = 1; //打开总中断
ET1 = 1; //打开定时器0中断
TR1 = 1; //启动定时器0
}
void main()
{
led = 1;
timer1_init();//定时器1的初始化
while(1)
{
if(i==10)
{
led = ~led;
i = 0; //注意i需要零
}
}
}
void timer1() interrupt 3
{
TH1 = 0x4C; //设置初始值,定时50ms
TL1 = 0x00;
i++;
}