51单片机定时器与计数器

51单片机定时器与计数器

一、定时器与计数器的结构与功能

8051单片机有两个16位定时器/计数器T0 (高8位TH0、低8位TL0)T1(高8位TH1、低8位TL1)T0T1同时具有定时计数功能。
8位特殊功能寄存器TMOD(timer mode),选择定时/或计数工作模式和工作方式
8位特殊功能寄存器TCON(timer controller),控制定时器的启动与停止

在这里插入图片描述

计数功能

计数器用于统计从 P3.4端口和P3.5端口输入的脉冲负跳变数量(前一个机器周期采样为高电平,后一个采样周期为低电平)。为保证正确采样,输入脉冲的高电平和低电平至少保持一个机器周期时间,所以输入脉冲频率最高为单片机内部脉冲频率一半

定时功能

定时功能是单片机通过对内部机器脉冲进行计数计数值乘以机器周期为定时时间。
如机器周期为1us,计数1000次,定时时间为1ms。

定时和计数的本质都是对脉冲信号计数,只不过是计数信号来源不同。计数脉冲信号来源P3.4或者P3.5 外部计数脉冲。定时脉冲来源于内部机器脉冲,一次脉冲时间固定,可以用来定时。

二、定时器与计数器的控制

定时或者计数工作的过程

  1. 设置工作方式寄存器TMOD
  2. 为定时器/计数器(T0 / T1)赋初值。
  3. 通过TCON控制寄存器中的TR0TR1实现启动或者停止。

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工作于定时器。
  • MlM0用于设置工作方式。
    若所需计数长度为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。
  • TFxTx的溢出标志位。
    当定时或计数因达到最大计数容量而产生溢出时,此位由硬件自动置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;//循环检测溢出,需要编程清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
		}
	}
}


  • 9
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值