文章目录
- 51单片机定时器与计数器
- 一、定时器与计数器的结构与功能
- 计数功能
- 定时功能
- 二、定时器与计数器的控制
- TMOD 工作方式寄存器
- TCON 定时器控制寄存器
- 三、仿真案例
- (一).8个LED 1 秒周期闪烁。
- (二) 产品包装生产线。
51单片机定时器与计数器
一、定时器与计数器的结构与功能
8051单片机有两个16位定时器/计数器T0 (高8位TH0、低8位TL0)
及T1(高8位TH1、低8位TL1)
,T0
及T1
同时具有定时和计数功能。
8位特殊功能寄存器TMOD(timer mode)
,选择定时/或计数工作模式和工作方式。
8位特殊功能寄存器TCON(timer controller)
,控制定时器的启动与停止。
计数功能
计数器用于统计从 P3.4
端口和P3.5
端口输入的脉冲负跳变数量(前一个机器周期采样为高电平,后一个采样周期为低电平)。为保证正确采样,输入脉冲的高电平和低电平至少保持一个机器周期时间,所以输入脉冲频率最高为单片机内部脉冲频率一半。
定时功能
定时功能是单片机通过对内部机器脉冲进行计数,计数值乘以机器周期为定时时间。
如机器周期为1us,计数1000次,定时时间为1ms。
定时和计数的本质都是对脉冲信号计数,只不过是计数信号来源不同。计数脉冲信号来源P3.4
或者P3.5
外部计数脉冲。定时脉冲来源于内部机器脉冲,一次脉冲时间固定,可以用来定时。
二、定时器与计数器的控制
定时或者计数工作的过程
- 设置工作方式寄存器
TMOD
。 - 为定时器/计数器(
T0
/T1
)赋初值。 - 通过
TCON
控制寄存器中的TR0
或TR1
实现启动或者停止。
TMOD 工作方式寄存器
TMOD
,选择定时/或计数工作模式和工作方式,功能为启动方式,工作于计数还是定时,计数器模式。只能按字节整体赋值。
低4位是用于控制 定时/计数器 T0,高4位是用于控制 定时/计数器T1。
GATE
用于设置的启动方式。当GATE=0
时,以寄存器TCON
中的TRx
位控制定时器或者计数器Tx
启动或停止。当设置GATE=1
时,则Tx
的启动受TRx
和外部中断信号INTx
共同控制。
例如:D3位 GATE=1,只有当置 INT0=1和TR0=1 时T0才启动,否则T0停止。
C\T
用于设置工作于计数器或定时器模式。C\T =0
时,工作于定时器方式。C\T =1
时,工作于计数器方式。
例如 D2位 C\T=0 T0工作于定时器。
Ml
和M0
用于设置工作方式。
若所需计数长度为N,则计数初值X=2^(方式定时器位数)-N。
方式0,M1M0=00,13位定时器/计数器。
定时/计数器启动后,在TL和TH中存储的计数初值基础上进行加1
计数,直至溢出。溢出时T0寄存器被清零,TF0被置位,并申请中断。此后,定时/计数器重新启动,则从零重新开始计数。若希望T0从某一数值开始计数,则应给计数器赋初值。在为计数器赋初值时,应将初值拆成高低两部分字节,分别送入TL和TH。
方式1,M1M0=01,16位定时/计数寄存器,方式1与方式0工作原理类似。
方式2,M1M0=10,自重装的8位计数器。 计数初值分别在加载到TL和TH中,当计数溢出时,不需要软件重新赋初值,由高8位寄存器TH自动给用作计数的低8位寄存器TL赋初值。
方式3, M1M0=11,T0为两个独立的8位计数器,T1无效。
TCON 定时器控制寄存器
TCON(timer controller)
,控制定时器的启动与停止,以及标识是否溢出。
TRx
控制Tx
启动或停止。
例如D4位 TR0=1时,启动定时/计数器T0;当D4位 TR0=0时,停止定时/计数器T0。
TFx
是Tx
的溢出标志位。
当定时或计数因达到最大计数容量而产生溢出时,此位由硬件自动置1,当转向中断服务程序时由硬件自动清零,若无中断服务程序则需要由编程进行清0。
三、仿真案例
(一).8个LED 1 秒周期闪烁。
1.定时器/计数器初值计算
晶振脉冲 频率 f=11.0592MHz,每个机器周期12个脉冲频率,故机器周期为 T=12*1/(11.0592*10^6)=1.085us
工作方式0,13位定时/计数寄存器,最长定时时间 2^13*1.085us≈9ms
工作方式1,16位定时/计数寄存器,最长定时时间 2^16*1.085us≈71ms
显然一次定时达不到 1s,需要多次定时,每次定时溢出需要处理一些系列操作将带来误差,所以尽可能减少溢出次数,选择工作方式1,计时 50ms(46083个机器周期*1.085=50ms)
,计时20次
。
2.电路原理图
3.程序
#include<reg51.h> //包含单片机定义寄存器的头文件
int main(void ) //主函数
{
unsigned char a,b,led=0xfe,cnt=0;//a,b用于循环移位,led保存LED各位,cnt保存溢出次数。
TL0=(65536-46083)%256;//T0 的TL低8位初值
TH0=(65536-46083)/256;//T0 的TH高8位初值
TMOD=0x01;
TR0=1;//启动计数器
TF0=0;//溢出位置0
while(1){
while(TF0==1){
cnt++;//溢出一次cnt加一
while(cnt==20){
a=led>>7;
b=led<<1;
led=a|b;//循环移位
P1=led;
cnt=0;//溢出次数归零
}
//溢出后 T0寄存器被清零,需要重新赋值,同时将溢出位再次置0
TL0=(65536-46083)%256;
TH0=(65536-46083)/256;
TF0=0;
}
}
}
(二) 产品包装生产线。
每个产品经过按键一次。8个LED灯,计满5个D1亮,再次计满D2亮……计满8次灯全亮。生产线不停,重复上述过程。
计数5个,数量较少,可以使用模式2能够自动装载(为计数器低8位TL赋初值
)。
电路原理图
程序
/* Main.c file generated by New Project wizard
*
* Created: 周二 4月 18 2023
* Processor: 80C51
* Compiler: Keil for 8051
*/
#include <reg51.h>
#include <stdio.h>
void main(void)
{
unsigned char led[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x00};
unsigned char cnt=0;
TH1=256-5;//设置高8位 TH1初值
TL1=256-5;//设置低8位 TH0初值,每次溢出后由高8位TH1 赋值给低8位。
TMOD=0x60;//使用T1,GATE=0,计数器c/t=1,模式2 M1M0=10
TF1=0;//溢出置0
TR1=1;//启动计数器T1
while(1){
while(TF1==1){//溢出时
P1=led[cnt];
cnt=(cnt+1)%8;//取余循环
TF1=0;//溢出置0
}
}
}