在本文中,我们对51单片机的定时器0进行测试。用定时器0来定时,并用来控制LED闪烁。定时器0的初始化代码如下所示。
void init_T0(void)
{
TMOD|= 0x01; //使用方式1,16位定时器
TH0=0x00; //给TH0和TL0赋初值,计数器由0开始计数,到65535溢出
TL0=0x00;
EA=1; //总中断打开
ET0=1; //定时器中断打开
TR0=1; //定时器开关打开
}
在这个实验中,采用定时器0的方式1进行定时。方式1为16位定时器方式。TH0和TL0的初始值都设置为0x00,则定时器0的计数为由0计数到65535之后溢出,及需要65536个机器周期溢出。采用12MHz的外部晶振,机器周期为1us。则定时器0的溢出周期为65.536ms。每两个周期LED灯闪一次,因此,LED的闪烁频率为1/(2*65.536ms)≈7.6Hz。
在程序中,TMOD|= 0x01;这个语句对TMOD寄存器进行赋值。TMOD|= 0x01;这一句是TMOD= TMOD| 0x01;的简写。“|”为按位或的运算。0x01的二进制值为00000001,它与TMOD进行按位或的运算结果为TMOD的bit0位强制置为1,其它位保持不变。
EA=1;
ET0=1;
TR0=1;
这三句分别对IE寄存器的EA位和ET0位以及TCON寄存器的TR0位进行赋值。可以看出对TMOD和IE、TCON的赋值方式是不一样的。原因在于TMOD这个寄存器不能进行位寻址,赋值时必须对整个寄存器进行赋值。而IE和TCON这两个寄存器是可以进行位寻址的,编程时可以对其中的位直接进行赋值。
在这个程序中,以中断方式处理定时器0的溢出事件,中断处理代码如下所示。在中断处理函数中将LED的状态改变。
void T0_ISR(void) interrupt 1 using 1
{
TH0=0x00; //给TH0和TL0重新赋值
TL0=0x00;
LED=~LED; //LED的值取反,改变灯的状态。
}
中断服务程序的标准格式为:
void 函数名() interrupt 中断号 using 工作组
中断函数不能返回任何值,所以最前面用void;后边紧跟着函数名,名字可以由用户自己决定,但不要违反C语言的标准;中断函数不带任何参数,所以函数名后边的括号内为空或者写void;中断号是指中断源的编号,这个编号是编译器识别不同中断的唯一标识,因此在写中断服务程序时务必要写正确;“using 工作组”是指这个中断函数使用单片机内存中4组工作寄存器中的哪一组,编译器在编译程序时会自动分配工作组,因此最后这句通常可以省略不写,比如源程序可以写成:void T0_ISR(void) interrupt 1。
将程序烧写到单片机中,并运行,可以看到LED连续闪烁。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)