方式3:
当选择方式3时,定时器T0就会被分成两个独立的计数器或者定时器。此时,TL0为8位计数器,计数溢出好置位TF0,并向CPU申请中断,之后需要软件重装初值; TH0也被固定为8位计数器,不过TL0已经占用了TF0和TR0,因此TH0将占T1的中断请求标志TF1和定时器启动控制为TR1。
为了防止中断冲突,定时器T0在方式3时,T1不能产生中断,但可以正常工作在方式0、1、2下。通常这种情况下T1将用作串行口的波特率发生器。
下面的例子是利用定时器方式3,TL0计数器对应的8位定时器实现第一个发光管以1s亮灭闪烁,用TH0计数器对应的8位定时器实现第二个发光管以0.5s亮灭闪烁。
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit led1=P1^0;
sbit led2=P1^1;
uint num1,num2;
void TIMEinit(void)
{
TMOD=0x03; //设置定时器0为工作方式3
TH0=6; //装初值
TL0=6;
EA=1; //开总中断
ET0=1; //开定时器0中断
ET1=1; //开定时器1中断
TR0=1; //启动定时器0
TR1=1; //启动定时器0的高8位计数器
}
void TL0_time() interrupt 1
{
TL0=6; //重装初值
num1++;
}
void TH0_time() interrupt 3 //占用T1定时器的中断号
{
TH0=6; //重装初值
num2++;
}
void main()
{
TIMEinit();
while(1)
{
if(num1>=4000) //12*(1/12MHz)*(256-6)*4000=1s
{
num1=0;
led1=~led1;
}
if(num2>=2000) //12*(1/12MHz)*(256-6)*2000=0.5s
{
num2=0;
led2=~led2 ;
}
}
}
这里的num1>=4000而不是num1==4000,是为了稳妥起见,万一定时器计数超过了4000,而主循环还没来得及判断,则会错过4000.那led1就不能实现取反了。