原理
- 时钟源:定时器是内部时钟源(晶振),计数器是外部
- 计时长度:对应TH TL计数器初值寄存器(高八位,低八位)
- 对应的中断触发函数
中断源 | 中断处理函数 |
---|---|
Timer0 | Timer0_Routine(void) interrupt 1 |
Timer1 | Timer1_Routine(void) interrupt 3 |
Timer2 | Timer2_Routine(void) interrupt 5 |
相关寄存器
TCON:定时器控制寄存器
只需用到:TF0、TF1、TR0、TR1
定时器/计数器运行控制位(代码):TR0、TR1
中断触发标志位(内部):TF0、TF1
TMOD:定时器模式寄存器
两个定时器/计数器(任选一个即可):T0(TL0\TH0)
、T1(TL1\TH1)
工作模式:
- 模式0(13位定时器/计数器)
- 模式1(16位定时器/计数器)
- 模式2(8位自动重装初值)
- 模式3(两个8位定时器/计数器)
我们学的是定时器,计数器是外部计数,则0.7、0.3地址是计数器的置0,C/T:置0为定时器,模式(M1、M0)这里我们选01(16位定时器,不自动重装初值)
如果不会自动重装载寄存器(不会自动赋初值)则要触发中断处理函数时重新手动赋初值
定时器计算初值
需要定时的时间带入公式,求出x
中断允许寄存器
总中断允许控制位:EA
ET0:定时/计数器T0的溢出中断允许位,ET1:定时/计数器T1的溢出中断允许位,ET2:定时/计数器T2的溢出中断允许位
需要外部、定时器、串口那个则赋值那个为1
代码编写
每1s翻转LED灯状态
- 模式选择(定时器0;工作模式1)
- 定时器初值(10ms)
- 打开定时器T0运行控制位
- 打开定时器0中断允许位
- 打开总中断允许控制位
- 编写中断服务函数
- 当溢出时,触发中断,执行中断函数,执行完之后,回到主函数继续执行
#include <reg52.h>
sbit LED1 = P1^0; //定义LED灯
int count; //由于51单片机没办法定时1s,只能通过计数达到效果
void main()
{
TMOD = 0x01; //配置定时器工作模式:使用定时器0,使用16位定时器模式(不自动重装初值)
//定时10ms,给寄存器赋初值
TL0 = 0x00;
TH0 = 0xDC;
TR0 = 1; //打开定时器T0运行控制位
ET0 = 1; //打开定时器0中断允许位
EA = 1; //打开总中断允许控制位
while(1)
{
//大于99时则取反LED状态
if(count > 99)
{
count = 0;
LED1 = ~LED1;
}
}
}
//定时中断处理函数
Timer0_Routine(void) interrupt 1
{
//触发中断函数,需要重新给定时器赋初值
TL0 = 0x00;
TH0 = 0xDC;
count++;
}