51定时/计数器简介
51单片机有2个16位定时器/计数器:定时器0(T0为P3.4)和定时器1(T1为P3.5)。这里所说的16位是指定时/计数器内部分别有16位的计数寄存器。
当工作在定时模式时,每经过一个机器周期内部的16位计数寄存器的值就会加1,当这个寄存器装满时溢出。 我们可以算出工作在定时模式时最高单次定时时间为 65535*1.085us=时间(单位us)
当工作在计数器模式时,T0(P3.4引脚),T1(P3.5引脚) 每来一个脉冲计数寄存器加1
定时器作用:可以用于精确事件定时,PWM脉宽调制,波形发生,信号时序测量的方面。
使用51定时/计数器步骤
(1)启动定时/计数器(通过TCON控制器)
(2)设置定时/计数器工作模式(通过TMOD控制器)
(3)查询定时/计数器是否溢出(读TCON内TF位)
51定时/计数器控制寄存器
TF1(T1溢出标志位):当定时/计数器T1溢出时由硬件置“1”TF1,向CPU发出中断请求,一直保持到CPU响应时,才由硬件清“0”(TF1也可以由程序查询清“0”)
TR1(定时器T1运行控制位):该位由软件置“1”或清零。TR1= 1就允许T1开始计数TR1=0时禁止T1计数。
TF0(T0溢出标志位)
TR0(定时器T0运行控制位),配置方法与T1相同。
IE1、IT1、IE0、IT0与定时/计数器无关,是控制外部中断的。
51定时/计数器工作模式寄存器(不可位寻址)
bit7 控制T1,置“1”时只有在P3.3脚为高及TR1置“1”时才可以启动T1,置“0”时TR1为“1”就允许T1启动。
bit6 置“1”时T1做计数器,置“0”时T1做定时器。
当工作在计数器模式时,T0(P3.4引脚),T1(P3.5引脚) 每来一个脉冲计数寄存器加1
bit5~4 M1 M0
M1 = 0,M0 = 0时 工作模式0。13位定时器模式,这是为了与8048兼容而设计的。16位计数器只用了13位,即TH0的高8位和TL0的低5位,组成一个13位定时器/计数器。
M1 = 0,M0 = 1,工作模式1 此时由TH1、TL1寄存器组成16位计数器,TH1 为16位的高8位,TL1为16位的低8位,当这个16位计数 器加满时,T1溢出。TF1被硬件置“1”。
M1 = 1,M0 = 0,工作模式2,时8位自动重装定时器,当TL1溢 出时,将TH1的值自动装入到TL1中,TF1被硬件置“1”。
M1 = 1,M0 = 1,工作模式3,T1停止计数。
bit3~0 设置T0定时器的,和T1设置相同(除工作模式3)
定时器1:
/*定时器1,定时模式 工作模式1 16位计数器,
定时20秒后点亮LED1,数码管显示*/
#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit we = P2^;
sbit du = P2^;
uchar code leddata[]={
0x3F, //"0"
0x06, //"1"
0x5B, //"2"
0x4F, //"3"
0x66, //"4"
0x6D, //"5"
0x7D, //"6"
0x07, //"7"
0x7F, //"8"
0x6F, //"9"
0x77, //"A"
0x7C, //"B"
0x39, //"C"
0x5E, //"D"
0x79, //"E"
0x71, //"F"
0x76, //"H"
0x38, //"L"
0x37, //"n"
0x3E, //"u"
0x73, //"P"
0x5C, //"o"
0x40, //"-"
0x00, //熄灭
0x00 //自定义
};
void delay(uint z)
{
uint x,y;
for(x = z; x > ; x--)
for(y = ; y > ; y--);
}
void display(uchar i)
{
uchar shi, ge;
shi = i / ;//求模 i除以10取商的整数部分
ge = i % ;//求余 i除以10取余数部分
P0 = 0xff; //清除断码
we = ;//打开位选
P0 = 0xfe;//1111 1110 只选通第一位数码管
we = ; //关闭位选
du = ; //打开段选
P0 = leddata\[shi\];
du = ; //关闭段选
delay();//延时5毫秒
P0 = 0xff;//清除断码
we = ; //打开位选
P0 = 0xfd;//1111 1101 只选通第二位数码管
we = ; //关闭位选
du = ;//打开段选
P0 = leddata\[ge\];
du = ; //关闭段选
delay();//延时5毫秒
}
void main()
{
uchar a; //50次数计数
uchar b;//秒计数
TR1 = ;//启动T1
TMOD = 0x10;//T1为定时器,工作模式1 16位计数器
//在初值基础上加,溢出则定时时间到
//晶振是11.0592MHz 65535-(50 000/1.085)==0x4BFC
TH1 = 0x4b;
TL1 = 0xfc;//0x4bfc 定时50ms
while()
{
if(TF1 == )//判断T1是否溢出
{
TH1 = 0x4b;
TL1 = 0xfc;//0x4bfc 定时50ms
TF1 = ;//清零便于下次判断
a++;//50毫秒计数加1
}
if(a == )//判断是否到1秒
{
a = ;//清零便于下次记录50ms的次数
b++;//秒加1
}
if(b == )//检查是否到20秒
{
TR1 = ;//时间到关闭定时器1
P1 = 0xfe;//点亮LED1
}
display(b);//显示秒的值
}
}
定时器0:
/*定时器0,定时模式 工作模式1 16位计数器,
定时20秒后点亮LED2,数码管显示*/
#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit we = P2^;
sbit du = P2^;
uchar code leddata[]={
0x3F, //"0"
0x06, //"1"
0x5B, //"2"
0x4F, //"3"
0x66, //"4"
0x6D, //"5"
0x7D, //"6"
0x07, //"7"
0x7F, //"8"
0x6F, //"9"
0x77, //"A"
0x7C, //"B"
0x39, //"C"
0x5E, //"D"
0x79, //"E"
0x71, //"F"
0x76, //"H"
0x38, //"L"
0x37, //"n"
0x3E, //"u"
0x73, //"P"
0x5C, //"o"
0x40, //"-"
0x00, //熄灭
0x00 //自定义
};
void delay(uint z)
{
uint x,y;
for(x = z; x > ; x--)
for(y = ; y > ; y--);
}
void display(uchar i)
{
uchar shi, ge;
shi = i / ;//求模 i除以10取商的整数部分
ge = i % ;//求余 i除以10取余数部分
P0 = 0xff; //清除断码
we = ;//打开位选
P0 = 0xfb;//1111 1011 只选通第三位数码管
we = ; //关闭位选
du = ; //打开段选
P0 = leddata\[shi\];
du = ; //关闭段选
delay();//延时5毫秒
P0 = 0xff;//清除断码
we = ; //打开位选
P0 = 0xf7;//1111 0111 只选通第四位数码管
we = ; //关闭位选
du = ;//打开段选
P0 = leddata\[ge\];
du = ; //关闭段选
delay();//延时5毫秒
}
void main()
{
uchar a; //50次数计数
uchar b;//秒计数
TR0 = ;//启动T0
TMOD = 0x01;//T0为定时器,工作模式1 16位计数器
TH0 = 0x4b;
TL0 = 0xfc;//0x4bfc 定时50ms
while()
{
if(TF0 == )//判断T0是否溢出
{
TH0 = 0x4b;
TL0 = 0xfc;//0x4bfc 定时50ms
TF0 = ;//清零便于下次判断
a++;//50毫秒计数加1
}
if(a == )//判断是否到1秒
{
a = ;//清零便于下次记录50ms的次数
b++;//秒加1
}
if(b == )//检查是否到20秒
{
TR0 = ;//时间到关闭定时器1
P1 = 0xfd;//点亮LED2
}
display(b);//显示秒的值
}
}
定时器1做计数器,定时器0定时:
/*定时器1做计数器,工作模式2,使用定时器0让LED1小灯100毫秒闪烁一次,
定时器1记录LED1闪烁次数,并且用数码管实时显示计数数值。*/
#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit we = P2^;
sbit du = P2^;
sbit LED1 = P1^;
uchar code leddata[]={
0x3F, //"0"
0x06, //"1"
0x5B, //"2"
0x4F, //"3"
0x66, //"4"
0x6D, //"5"
0x7D, //"6"
0x07, //"7"
0x7F, //"8"
0x6F, //"9"
0x77, //"A"
0x7C, //"B"
0x39, //"C"
0x5E, //"D"
0x79, //"E"
0x71, //"F"
0x76, //"H"
0x38, //"L"
0x37, //"n"
0x3E, //"u"
0x73, //"P"
0x5C, //"o"
0x40, //"-"
0x00, //熄灭
0x00 //自定义
};
void delay(uint z)
{
uint x,y;
for(x = z; x > ; x--)
for(y = ; y > ; y--);
}
void display(uchar i)
{
uchar bai, shi, ge;
bai = i / ; //显示百位
shi = i % / ; //显示十位
ge = i % ;//显示个位
P0 = 0xff; //清除断码
we = ;//打开位选
P0 = 0xfe;//1111 1110
we = ; //关闭位选
du = ; //打开段选
P0 = leddata\[bai\];
du = ; //关闭段选
delay();//延时5毫秒
P0 = 0xff;//清除断码
we = ; //打开位选
P0 = 0xfd;//1111 1101
we = ; //关闭位选
du = ;//打开段选
P0 = leddata\[shi\];
du = ; //关闭段选
delay();//延时5毫秒
P0 = 0xff;//清除断码
we = ; //打开位选
P0 = 0xfb;//1111 1011
we = ; //关闭位选
du = ;//打开段选
P0 = leddata\[ge\];
du = ; //关闭段选
delay();//延时5毫秒
}
void main()
{
uchar a; //50次数计数
TR0 = ;//启动T0
TR1 = ;//启动T1
TMOD = 0x61;//T0为定时器,工作模式1 16位计数器,T1为计数器,工作模式2,8位自动重装
TH0 = 0x4b;
TL0 = 0xfc;//0x4bfc 定时50ms
//P3.5来一个脉冲,计数器T1就会自动加1,这里的脉冲应是LED管脚处的脉冲,需要进行串联这两个引脚
TH1 = 0;//8位自动重装,TL1加到255后,会把TH1的0值装载到TL1里面
TL1 = ;//当TL1溢出时自动装入TH1的值
while()
{
if(TF0 == )//判断T0是否溢出
{
TH0 = 0x4b;
TL0 = 0xfc;//0x4bfc 定时50ms
TF0 = ;//清零便于下次判断
a++;//50毫秒计数加1
}
if(a == )//判断是否到100毫秒
{
a = ;//清零便于下次记录50ms的次数
LED1 = ~LED1;//闪烁LED1
}
display(TL1);//显示T1计数值
}
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章