2015年(29)
分类: 嵌入式
2015-04-12 23:29:48
8052总共有3个定时器,分别为T0、T1、T2。
T0、T1的使用方法非常相似。
其实,学会看数据手册,如何操作的过程数据手册上已经写的非常详细了。
如图,为T0/T1所用到的寄存器的大概说明:
如果想使用定时器,操作这几个寄存器就够了,当然,如果要使用中断,还需要操作IE寄存器中的位,如EA、ET1、ET0等。
如下图,为对TCON的描述:
其中T0也是相同的设置。需要注意的是,当定时/计数器以中断形式使用时,而非轮询形式使用,TF是不需要人工清零的,硬件会自动清零。
另外IE是外部中断产生标志位,IT是外部中断触发方式控制位。
TMOD中,GATE等于1表示定时/计数器的开启不仅跟TR有关,还跟/INT引脚有关。如下图,为定时/计数器的结构图:
由图中看出,定时/计数器的输入有两个源,分别为系统时钟分频后的时钟和外部T0口,而系统时钟分频有两种模式,一种是12分频,与传统8051系统相一致,还有一种是6分频,对STC51芯片来说,这是在STC下载程序的时候决定的,如下图:
在硬件选项中,选中第一个复选框“使能6T(双倍数)模式”后,就是以6分频模式执行。
C/T为0,选择对系统时钟进行计数,就成为了定时器,而C/T为1,对外部脉冲进行计数,就成了计数器。
当TR0为1时,看(/GATE)|(/INT0);当GATE为0,那与TR0相与的另一个输入一定为1,所以说如果GATE=0,那么TR0等于1后,定时/计数器就开始工作了。而如果GATE等于1,那么只有在/INT0引脚为1时,才开始计数。
TH0、TL0为当前定时/计数器T0计到的值,通过对该值装入处置,可以设置定时时长。
定时/计数器每1个机器周期增加一次计数,计满,产生中断。
编程:
比如,现在要50ms进入一次中断,使用16位的定时计数器,晶振为12M。
那么一个机器周期为1/(12M)*12 = 1us,最多65536us,即65ms进入一次定时器中断,50ms<65ms,可以实现。
初值x计算:(65536-x)*1us=50000us; x=15536
TMOD设置,先要选好使用哪个定时器,装好初值,打开中断后才能开启计时器。
比如使用T0,那就设置低4位,GATE为0,C/T为0,M1M0为01,选择16位定时器,所以TMOD = 0x01,当然,这样不太好,万一T1有人使用呢,最好是用以下语句:TMOD &- 0xf0;TMOD |= 0x01;
TCON设置,因为TCON可以按位寻址,直接设置即可:
上代码:
//设置初值
TH0 = 15536 >> 8;//当然也可以用15536/255,但是位运算比除法运算快
TL0 = 15536 & 0xff;
//设置模式
TMOD = 0x01;
//打开中断
EA = 1;
ET0 = 1;
//开定时器
TR0 = 1;
这就OK了,其实按照数据手册来就可以了,是不难的。
那中断到了之后,程序跳到哪里去执行呢?
跳到中断向量表:
如下所示,为中断向量的入口地址:
地址 用途
0003H 外部中断0(/INT0)中断入口地址
000BH 定时/计数器0(TF0)中断入口地址
0013H 外部中断1(/INT1)中断入口地址
001BH 定时/计数器1(TF1)中断入口地址
0023H 串行中断(T1、R1)入口地址
002BH 定时/计数器2中断入口地址,在8052中使用。
在中断向量表的位置,放置了一条跳转指令,该指令跳转到对应中断的服务程序入口地址。通过查阅设计手册可知,定时器0的中断号为1。
所以,中断服务程序可以写成:
void time0_service(void)interrupt 1 using 0
{
TH0 = 15536 >> 8;
TL0 = 15536 & 0xff;
//代码段,要求:处理时间尽可能短,否则可能造成中断丢失
}
中断服务程序无返回值,无参数,必须有interrupt X,说明是中断源,编译器根据interrupt的值X,算出中断服务程序地址应该填在中断向量表(8*X+3)的位置。
using是说明使用哪组寄存器,这样的目的是为了加快处理中断的时间,可以不写。
只要看得懂数据手册,按照数据手册上面的内容写下来不是很难。
另外,很多数据手册是没有中文的,这对英语也有很高的要求。
同理,可以设置13位、8位定时器以及T2。