概要
学习单片机内部定时器中断原理以及使用方法
定时器中断的工作原理与应用
定时器内部结构包括两个特殊的功能寄存器,一个用于设置工作模式(TMOD),一个用于设置初始值(TCON)。一个12M晶振计数一次(一次的机器周期)时间为1us,最大的计数次数是65536次,因此,根据晶振频率的不同,定时器一次计时的总时间也不同。
例如:12M晶振的定时器最大计时值是65536us。计算方式t = 12 * 1/12000000 *65536。其他频率计算方式同理。
技术名词解释
- TMOD:设置定时器工作模式
解释:
定时器0的工作模式有四种,定时器1的工作模式有三种。它们的区别在于,定时器0的方式3的高八位的中断标志位占用了定时器1的中断标志位。所以定时器1工作模式少一种。定时器的几种工作方式如下:
在该图中C/~T这里C代表计数器,高电平有效(1),~T代表定时器,低电平有效(0),所以在使用定时器,给TMOD赋初值的时候,需要设置C/~T这个位置为0。代表使用定时器。
- TCON:设置定时器初始值
解释:
可以简单理解为就是设置定时器和定时器的启动标志位(TR0/TR1),溢出中断标志位(TF0/TF1)的设置。高电平1表示启动或触发,低电平0表示停止。
定时器溢出原理
代码练习
要求:利用定时器0实现一个LED等每隔1s亮灭闪烁一次。
实现代码:
实现思路:因为需要一个1s的时间间隔,所以使用定时器0的工作方式1,也就是TMOD = 0x01;由于定时器最大的计时时间是65536us(对于12M晶振来说,超不过1s),所以想办法如何凑1s,那么可以凑1000个1ms,定义一个全局变量用来储存溢出次数。接下来就是计算定时器0初值,高八位计算方式TH0 = (65536-1us数)/256,低八位计算方式TL0 =(65536-1us数)%256;有了初值初始化定时器0,开启中断,在中断函数中实现led的翻转。
#include "reg52.h"
typedef unsigned char u8;
typedef unsigned int u16;
u16 count = 0; //用来计时,计算每过1s的时间led翻转一次
sbit led = P3^0;
/*定时器初始化*/
void time0_init()
{
TMOD |= 0x01; //设置定时器0模式,工作方式1
TH0 = (65536-1000)/256; //设置初值,定时1ms
TL0 = (65536-1000)%256;
EA = 1; //打开总中断
ET0 = 1; //打开定时器0中断
TR0 = 1; //开始计时
}
void main()
{
led = 1;
time0_init();
while(1)
{
}
}
void time0() interrupt 1
{
TF0 = 0; //溢出后TF置1,要手动置0
count++; //每溢出一次+1,代表时间1ms
TH0 = (65536-1000)/256; //重新赋初值
TL0 = (65536-1000)%256; //重新赋初值
if(count == 1000) //每过1000次1ms,也就是1s,led翻转一次
{
led = ~led;
count = 0; //重新开始计时
}
}
定时器开发思路
- 定时器初始化
- 定时器工作方式设置TMOD=xxx;
- 定时器的初始值设置TH0/1 =xxx;TL0/1 = xxx;
- 高八位TH0/1 = (65536-xxx)/256
- 高八位TL0/1 = (65536-xxx)%256
- 开启定时器中断:
- 总中断EA = 1;
- 定时器中断ET0/1 = 1;
- 开始计时TR0/1 = 1;
- 设置中断函数
- 实现要求
- 根据要求实现代码的逻辑。