用Keil C51开发守时器/计数器
根本的51单片机内部有两个16位可编程的守时器/计数器T0和T1。它们各自具有4种作业状况,其操控字和状况均在相应的特别功用寄存器中,能够经过软件对操控寄存器编程设置,使其作业在不同的守时状况或计数状况。
现在,许多厂家出产的8051兼容单片机上,还加入了守时器/计数器2,使单片机的运用更为灵敏,适应性更强。
许多8051单片机的书本都对守时器/计数器有具体的介绍,咱们在此不再具体地评论。但由于编写或或阅读程序时常常要查阅守时器/计数器的设置状况,因而咱们仅对一些编程时常常要用到的较重要的寄存器和设置办法进行扼要简介。
1 守时器/计数器简介
8051单片机的守时器/计数器根本结构如图1-1所示,守时器T0由两个8位计数器TH0和TL0构成,守时器T1也由两个8位计数器TH1和TL1构成,TMOD寄存器操控守时器的作业办法,TCON寄存器操控守时器的发动和中止以及守时器的状况。
图1-1 守时器/计数器结构
在作守时器运用时,输入的时钟脉冲是由晶体振动器的输出经12分频后得到的。实践上,守时器便是单片机机器周期的计数器。由于每个机器周期包含晶体振动器的12个振动周期,而每一个机器周期守时器加1,故其频率为晶振频率的1/12。假如晶振频率为12MHz,则守时器每接纳一个输入脉冲的时刻为1μs。
挑选计数器作业办法时,计数脉冲来自相应的外部输入引脚T0(P3.4)或T1(P3.5)。在这种状况下,当检测到输入引脚上的电平由高跳变到低时,计数器就加1。
2 操控和状况寄存器
(1)守时器操控寄存器(TCON)
TCON为守时器/计数器的操控寄存器,一起也锁存外部中止恳求标志,各位界说如下。
? TF1:守时器/计数器1中止恳求标志位。当守时器计数满溢出回零时,由硬件置位,并可恳求中止。当CPU呼应中止并进入中止服务程序后,TF1主动清零。
? TR1:守时器/计数器1运转操控位,靠软件置位或铲除。置位时,守时器/计数器1接通作业,铲除时中止作业。
? TF0:守时器/计数器0中止恳求标志位,其功用和操作状况类同于TF1。
? TR0:守时器/计数器0运转操控位,其功用和操作状况类同于TR1。
? IEl:外部中止1的中止恳求标志,检测到在INT引脚上呈现的外部中止信号的下降沿时,由硬件置位,恳求中止。进入中止服务程序后被硬件主动铲除。
? IT1:外部中止1的类型操控位。IT1=1,由下跳沿触发;IT1=0,由低电平触发。能够由软件来设置或铲除。
? IE0:外部中止0的中止恳求标志。其功用和操作状况类同于IE1。
? IT0:外部中止0的类型操控位。其功用和操作状况类同于IT1。
(2)作业办法寄存器(TMOD)。TMOD确认守时器的作业办法及功用挑选,不能位寻址。其间,高4位用于操控守时器1,低4位用于操控守时器0。TMOD各位的界说如下。
? GATE:门控位,当GATE=1时,只要?I?N?T?0或?I?N?T?1引脚为高电平,且TR0或TR1置1时,守时器/计数器才作业。当GATE=0时,守时器/计数器仅受TR0或TR1的操控,而不论?I?N?T?0或?I?N?T?1引脚的电平是高仍是低。
? C/?T:守时器/计数器功用挑选位,C/?T=0时,设置为守时功用;C/?T=1时,设置为计数功用。
? M1 M0 :作业办法挑选位。由M1M0共2位构成4种编码,对应以下4种作业办法。
n M1M0=00:作业办法0(13位办法)。
n M1M0=01:作业办法1(16位办法)。
n M1M0=10:作业办法2(8位主动装入时刻常数办法)。
n MlM0=11:作业办法3(2个8位办法——仅对T0)。
3 守时器/计数器设置实例
以守时器/计数器T0为例,在办法0下,TL0的低5位和TH0的8位构成13位计数器,因而计数作业办法时,计数值的规模是:1~8192(213)。
当设定为守时作业办法时,守时时刻的核算公式为:
(213-计数初值)×晶振周期×12 或(213-计数初值)×机器周期
这样,咱们能够算出,若单片机体系的外接晶振频率为6MHz,则该体系的最小守时时刻为:
[213-(213-1)]×[1/(6×106)]×12=2×10-6=2(?s)
最大守时时刻为:
(213-0)×[1/(6×106)]×12=16384×10-6=16384(?s)=16.384(ms)
或:最小守时单位×1013=16384(?s)=16.384(ms)
【例】某单片机体系的外接晶振频率为6MHz,运用守时器1,以办法0守时,从P1.0输出2ms方波的核算和设置办法如下:
① 核算计数初值。欲发生2ms的等宽正方波脉冲,只需在P1.0端以1ms为周期替换输出凹凸电平即可完成,为此守时时刻应为1ms。运用6MHz晶振,则机器周期为:
机器周期=12/晶振频率=12/(6×106)=2(?s)
办法0为13位计数结构。设待求的计数初值为X,则:
(213-X)×2×10-6=1×10-3
求解得:
X=7692
化为二进制数一共为1111000001100。
用十六进制一共,高8位为F0H,放入TH1;低5位为0CH,放入TL1。
② TMOD寄存器初始化。为把守时器/计数器1设定为办法0,设置M1M0=00;为完成守时功用,应使C/?T =0;为完成守时器/计数器1的运转操控,设置GATE=0。守时器/计数器0不必,有关位设定为0。因而TMOD寄存器应初始化为00H。
③ 由守时器操控寄存器TCON中的TR1位操控守时的发动和中止,TR1=1发动,TR1=0中止。
若使其作业在办法1,守时器/计数器为16 位守时器/计数器,即加法计数器由 TH0 悉数8位和TL0悉数8位构成16位,其他与办法0完全相同,因而核算TH0和TL0初值的办法也和作业办法0相似,仅仅需注意本来13位的当地现在要换成16位。
4 守时器/计数器2
8051单片机中,有一部分类型有三个守时器/计数器,如Intel的8032、Atmel的89C52、89C55、Philips的89C51RC、89C58,等等。这些单片机的第三个守时器/计数器叫T2,其操控寄存器是T2CON,它的各位界说如下:
? TF2:守时器2溢出标志。守时器溢出时置位,并恳求中止,只能靠软件铲除。当RCLK或TCLK =1 时TF2 将不会置位。
? EXF2:守时器2外部标志。当EXEN2为1,且T2EX 引脚上呈现负跳变发生捕获或重装时EXF2置位,恳求中止。若已答应守时器2 中止,EXF2=1 将使CPU 从中止向量处碑文守时器2中止子程序。EXF2 位必须用软件清零。当守时器/计数器2作业在向上递加或向下递减计数器形式(办法操控寄存器T2MOD的DCEN位=1)时,EXF2 不能激活中止。
? RCLK:接纳时钟标志。靠软件置位或铲除。RCLK=1时,用守时器2溢出脉冲作为串行口(作业于办法1或3时)的接纳时钟。RCLK=0时,用守时器1的溢出脉冲作为接纳时钟。
? TCLK:发送时钟标志。靠软件置位或铲除。TCLK=1时,用守时器2溢出脉冲作为串行口(作业于办法1或3时)的发送时钟。TCLK=0时,用守时器1的溢出脉冲作为发送时钟。
? EXEN2:守时器2外部答应标志。靠软件置位或铲除。当EXEN2=1时,假如守时器2未用作串行口的波特率发生器,在T2EX端呈现负跳变脉冲时,激活守时器2捕获或重装,并置EXF2标志为1,恳求中止。EXEN2=0时,T2EX端的外部信号无效。
? TR2:守时器2发动/中止操控位。靠软件置位或铲除。TR2=1时,发动守时器2,不然中止。
? C/?T?2:守时器2守时办法或计数办法操控位。C/?T?2=0,挑选守时办法;C/?T?2=1时,挑选对外部计数办法(下降沿触发)。
? CP/?R?L?2:捕获/重装载挑选。CP/?R?L?2=1时,假如EXEN2=1,且T2EX端呈现负跳变脉冲时发生捕获操作,即把TH2和TL2的内容传递给RCAP2H和RCAP2L。CP/?R?L?2=0时,若守时器2溢出或EXEN2=1,T2EX端呈现负跳变脉冲,会呈现重装载操作,即把RCAP2H和RCAP2L的内容传递给TH2和TL2。当RCLK=1或TCLK=1时,该位无效,在守时器2溢出时强制其主动重装载。
经过软件设置T2CON,可使守时/计数器以三种根本作业办法之一作业。第一种为捕捉办法。设置为捕捉办法时,和守时器0 或守时器1 相同以16 位办法作业。这种办法经过复位EXEN2来挑选。当置位EXEN2时,假如T2EX有负跳变电平,将把当时的数锁存在(RCAP2H和RCAP2L)中。这个事情可用来发生中止。
第二种作业办法为主动重装办法,其间包含了两个子功用,由EXEN2来挑选,当EXEN2复位时,16 位守时器溢出将触发一个中止并将RCAP2H 和RCAP2L 中的数装入守时器中。当EXEN2 置位时,除上述功用外,T2EX 引脚的负跳变将发生一次重装操作。
最终一种办法用来发生串行口通讯所需的数据传输率,这经过一起或别离置位RCLK 和TCLK来完成。在这种办法中,每个机器周期都将使守时器加1,而不像守时器0 和1 那样,需求12个机器周期。这使得串行通讯的数据传输率更高。
守时器2还有一个不行寻址的办法操控寄存器T2MOD,其内容如下:
? —:保存位。
? T2OE:守时器2输出答应位。
? DCNE:置位时,答应守时器2作为向上/向下计数器。
5 编程实例
【例1】这是一个简略的守时器程序,由一个循环组成,在点亮接在P1.0 口的LED之后,延时一段时刻,再灭掉LED,又延时一段时刻,之后循环到前面。按全速运转,能够看到P1.0口上接的LED 灯不断地业绩。
#include //包含一个52规范内核的头文件
sbit P10 = P1^0; //要操控的LED灯
sbit K1= P3^2; //按键K1
//用守时器中止业绩LED
void main(void) //主程序
{
TMOD=0x01; //守时器0,16位作业办法
TR0=1; //发动守时器
ET0=1; //翻开守时器0中止
EA=1; //翻开总中止
while(1) //程序循环
{
; //主程序在这里就不断自循环,实践运用中,这里是做首要作业
}
}
//守时器0中止
timer0() interrupt 1 // 守时器0中止是1号
{
TH0=0x00; //写入守时器0初始值0x0005
TL0=0x06;
P10=~P10; //回转LED灯的亮和灭
}
程序中,运用了守时器0,作业在办法1,即16位作业办法。
【例2】这是一个跑马灯程序,运用了守时器2。
#include //包含一个52规范内核的头文件
sbit P10 = P1^0; //头文件中没有界说的IO就要自己来界说了
sbit P11 = P1^1;
sbit P12 = P1^2;
sbit P13 = P1^3;
bit ldelay=0; //长守时溢出符号,预置是0
//守时器中止办法的跑马灯
void main(void) //主程序
{
unsigned char code ledp[4]={0xfe,0xfd,0xfb,0xf7};//预订的写入P1的值
unsigned char ledi; //用来指示显现次序
RCAP2H =0x10; //赋T2的预置值0x1000,溢出30次便是1秒钟
RCAP2L =0x00;
TR2=1; //发动守时器
ET2=1; //翻开守时器2中止
EA=1; //翻开总中止
while(1) //主程序循环
{
if(ldelay) //发现有时刻溢出符号,进入处理
{
ldelay=0; //铲除符号
P1=ledp[ledi]; //读出一个值送到P1口
ledi++; //指向下一个
if(ledi==4)ledi=0; //到了最终一个灯就换到第一个
}
}
}
//守时器2中止
timer2() interrupt 5 // 中止向量是5
{
static unsigned char t;
TF2=0;
t++;
if(t==30) //T2的预置值0x1000,溢出30次便是1秒钟,晶振22.118400 MHZ
{
t=0;
ldelay=1; //每次长时刻的溢出,就置一个符号,以便主程序处理
}
}