简单的定时器中断
1、操作步骤(以T0定时器为例)
①设置工作方式寄存器TMOD(model)
②设置定时器(计算)初值(TH0,TL0)
③打开中断 (EA全局中断,相当于允许使用中断)
(ET0,允许T0中断)
(TR0,定时器0运行控制位)
④设置中断函数
2、具体分析
2.1工作方式寄存器TMOD
2.1.1介绍
TMOD为一个8位寄存器,低4位控制定时器0,高4位控制定时器1,不能位寻址。
2.1.2对应4位介绍
①GATE(门):置1时受外部中断引脚和TCON控制器控制。
②C/T:置1为计数器,0为定时器。
③M0/M1:工作方式位。
2.2控制寄存器TCON
2.2.1介绍
TCON为8位寄存器,控制中断源的开启,可以位寻址。高4位控制定时器0/1,低4位控制外部中断。
2.2.2对应2位介绍
①TR0:定时器0控制位。
②TF0:定时器0溢出位,置1时申请中断。
2.3定时器初值计算(以TCON方式1为例)
计满TH0和TL0约65.5ms
①以12MHz为例:若需要定时1s则可以用20*(50ms)得到,则需要装入65536-50000=15536。
②以11.0592MHz为例:若需要定时1s,一个机器周期为12*(1/11059200)≈1.09μs
若t=50ms,需要50000(μs)/1.09(次/μs)=45872(次),即填入65536-45872=19664;
tips:
振荡周期: 为单片机提供定时信号的振荡源的周期(晶振周期或外加振荡周期)
状态周期:2个振荡周期为1个状态周期,用S表示。振荡周期又称S周期或时钟周期。
机器周期:1个机器周期含6个状态周期,12个振荡周期。
指令周期:完成1条指令所占用的全部时间,它以机器周期为单位。
外接晶振为12MHz时,51单片机相关周期的具体值为:
振荡周期=1/12us;
状态周期=1/6us;
机器周期=1us;
指令周期=1~4us;
2.4中断函数
void 函数名 () interrupt n [using n]
{
//中断内容
}
中断号 中断源 中断向量
0 外部中断0 0003H
1 定时器/计数器0 000BH
2 外部中断1 0013H
3 定时器/计数器1 001BH
4 串行口 0023H
interrupt 关键字是不可缺少的,由它告诉编译器该函数是中断服务函数,并由后面的
n指明所使用的中断号。每个中断号都对应一个中断向量,中断源响应后处理器会跳转到中断向量所处的地址执行程序,编译器会在这地址上产生一个无条件跳转语句,转到中断服务函数所在的地址执行程序,即不需要主动调用中断函数。
3、示例
1、led以1s亮灭
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar num;
void main()
{
P1=0x00;
TMOD=0x01;//0000 0001
TH0=(65536-45872)/256;
TL0=(65539-45872)%256;
EA=1;//全局中断
ET0=1;//定时器0中断
TR0=1;//启动定时器0
while(1)
{
if(num==20)
{
num=0;
P1=~P1;
}
}
}
void T0_time() interrupt 1
{
TH0=(65536-45872)/256;
TL0=(65539-45872)%256;
num++;
}
2、60s循环计时
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit dula=P2^6;
sbit wela=P2^7;
uchar num=1,count=0;
uchar code table[]={
0x3f,0x06,0x5b,
0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f
};
void display(uchar num);
void Delayms(uchar x);
void main()
{
TMOD=0x01;
TH0=(65536-45872)/256;
TL0=(65539-45872)%256;
EA=1;//È«¾ÖÖжÏ
ET0=1;//¶¨Ê±Æ÷0ÖжÏ
TR0=1;//Æô¶¯¶¨Ê±Æ÷0
while(1)
{
display(num);
}
}
void Delayms(uchar x)
{
uchar j;
while(x--)
{
for(j=110;j>0;j--);
}
}
void display(uchar num)
{
wela=1;
P0=0xfe;
wela=0;
P0=0xff;
dula=1;
P0=table[num/10];
dula=0;
Delayms(5);
wela=1;
P0=0xfd;
wela=0;
P0=0xff;
dula=1;
P0=table[num%10];
dula=0;
Delayms(5);
}
void T0_time() interrupt 1
{
TH0=(65536-45872)/256;
TL0=(65539-45872)%256;
count++;
if(count==20)
{
count=0;
num++;
if(num==61)
{
num=1;
}
}
}