本帖最后由 Linkfox.cc@灵狐 于 2018-2-7 18:21 编辑
这个贴早就应该发出来的,但是好像叫我保存成草稿了一直没发出去,今天看来一下才发现
在51单片机中有2个16位定时器/计数器,定时器0位P4定时器1 P35
当工作设定在定时模式时,没经过一个机器周期内部的16位技术寄存器的值就会加一,当这个寄存器溢出时我们就可以算出单次定时的时间
当工作在计数器模式是 P34 P35每来一个脉冲,寄存器就加1
要使用定时器/计数器需要进行如下步骤
1.通过TCON控制器启动
2.通过TMOD控制器设置工作模式
3.通过读取TCON内的TF位查询定时器/计数器是否溢出
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与定时/计数器无关,是控制外部中断的。
位 符号 功能 TMOD.7 GATE 控制T1,置“1”时只有在P3.3脚为高及TR1置“1”时才可以启动T1,置“0”时TR1为“1”就允许T1启动。 TMOD.6 C/T 置“1”时T1做计数器,置“0”时T1做定时器。 TMOD.5 M1 M1= 0,M0= 0时工作模式0。M1 = 0,M0= 1,工作 TMOD.4 M0 模式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停止计数。
TMOD3~0位设置T0定时器的,和T1设置相同(除工作模式3)
下面是我写的一个0-99计时 [mw_shl_code=c,true] #include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit we = P2^7;
sbit du = P2^6;
uchar code leddata[]={
0x3F, //"0"
0x06, //"1"
0x5B, //"2"
0x4F, //"3"
0x66, //"4"
0x6D, //"5"
0x7D, //"6"
0x07, //"7"
0x7F, //"8"
0x6F, //"9"
};
void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
void display(uchar i)
{
uchar shi, ge;
shi = i / 10;//取十位
ge = i % 10;//求余取个位
P0 = 0xff; //清楚断码
we = 1;//打开位选
P0 = 0xfe;//1111 1110 开第一位
we = 0; //关闭位选
du = 1; //打开段选
P0 = leddata[shi];
du = 0; //关闭
delay(5);
P0 = 0xff;//清除残影
we = 1; //打开位选
P0 = 0xfd;//1111 1101 开第二位
we = 0; //1关闭位选
du = 1;//打开段选
P0 = leddata[ge];
du = 0; //关闭
delay(5);
}
void main()
{
uchar a; //计数变量
uchar b;//秒计数变量
TR1 = 1;//启动T1
TMOD = 0x10;//T1位定时器,工作模式1 16位计数器
TH0 = 0x4b;
TL0 = 0xfc;//0x4bfc
while(1)
{
if(TF1 == 1)//T1是否溢出 {
TH1 = 0x4b;
TL1 = 0xfc;//0x4bfc 19452
TF1 = 0;//清零
a++;
}
if(a == 20)//1s
{
a = 0;//清零
b++;//秒+1
}
if(b == 99)//读秒=99
{
b=0;
}
display(b);
}
}[/mw_shl_code]
以上所有内容仅为个人学习总结,如有错误之处请大家指点出来谢谢
|