04:定时器

news2024/9/9 7:32:02

定时器

  • 1、定时器怎么定时
  • 2、怎样实现计数?
    • 2.1、控制寄存器TCON
    • 2.2、工作模式寄存器TCOM
    • 2.3、定时器T0
  • 3、案例:通过定时器T0控制LED间隔1s亮灭

当定时器用的时候,靠内部震荡电路数数。当配置为定时器使用时,每经过1个机器周期,计数存储器的值就加1。

1、定时器怎么定时

1、通过晶振(晶体振荡器)发出脉冲,记录脉冲的个数来进行定时的。
2、而脉冲的频率为时钟频率,此频率的倒数为震荡周期(时钟周期),也是计算机中最小的时间单位。
在这里插入图片描述

如图:晶体振荡器的频率为11.0592MHz,则他的时钟周期为1/11.0592MHz(秒),既一个脉冲的周期需要这么多秒。

3、机器周期为CPU周期,一个基本操作所需要的时间称为机器周期。一般情况下,一个机器周期由若干个时钟周期组成。一般情况下是12倍/6倍。
在这里插入图片描述

在这里插入图片描述

  • 加1经过了多少时间?
    当晶振频率是11.0592MHz的时候,等于11059.2KHz = 11059200Hz
    机器周期 = 12 x 时钟周期 =12 x (1/时钟频率) 秒 = 12 / 时钟频率 秒 = 12 / 11059200 秒 = 12 000 000/ 11059200 微秒 = 1.085 (us)
    既:当使用12倍数时,每隔1.085us,计数器就+1

2、怎样实现计数?

  通过配置相关的寄存器:如下图为定时器的相关寄存器。
在这里插入图片描述

  • 如图有2中寄存器:第一种为TCON,第二种为TCOM,他们都是各8位。
  • 如图有2种定时器:第一种位定时器T0,第二种为定时器T1,他们都是各16位。

2.1、控制寄存器TCON

在这里插入图片描述

TF0:定时器T0溢出中断标志,当定时器0开始计数时,计数到规定的时间时,定时器产生了溢出。TF0自动由0变位1(由硬件置1)。
如果不用中断,需要手动清零。

TR0:定时器T0的控制位,当为1时,定时器T0才能计数,相当于T0的开关(由软件控制)。

2.2、工作模式寄存器TCOM

在这里插入图片描述

GATE:门控制位,当GATE=0时:计数条件只有TR1一个(TR1=1就计数,TR1=0就不计数)。
			   当GATE=1时:是否计数不仅取决于TR1还取决于INT1引脚
C/T :时钟输入选择为,为1时,时钟从外部引脚P3.5口输入;为0时,时钟从内部输入
M1      M0
0        0        :13位定时器,使用高8位和低5位
0        1        :16位定时器,全用
1        0        :8位自动重装载定时器,当溢出时将TH1存放的值自动重装入TL1.
1        1        :定时器无效

2.3、定时器T0

在这里插入图片描述

   定时器T0一共有16位,分为高8位TH0,和低8位TL0。所以一共能计2^16个数(65536),而每计1个数的周期是1.085us,所以默认是从0开始数数,累计计时约71ms。

3、案例:通过定时器T0控制LED间隔1s亮灭

代码①:

#include <REGX52.H>

sbit LED1 = P3^7;
void main(void)
{
	int cnt = 0;
	LED1 = 1;//先让灯熄灭的状态
	
/*1、选择定时器T0,并配置为16位定时器*/
	TMOD =0x01;							// 0000 0001
	
/*
	2、定一个10ms的时间,数1下需要1.085us
	10ms需要数则需要数9216下,那从65536-9126=56320
	从56320这里开始数,数9216下就到了65536。当超过了
	65536时就报表了,控制寄存器TCON的TF0由0变为1	
*/
	TL0 = 0x00; //0000 0000
	TH0 = 0xDC;//1101 1100
	
/*3、打开定时器T0*/
	TR0 = 1;
	
	TF0 = 0;//先个溢出标志清零
	while(1)
	{
		if(TF0 == 1)//10ms报表了
		{	
			TF0 = 0;//软件清零,现在不使用中断
			TL0 = 0x00; //重新给初值
			TH0 = 0xDC;
			cnt++;
			if(cnt == 100)//数100次,相当于1s
			{
				cnt = 0;
				LED1 = !LED1;
			}
		}
	}
}

【注】

  • 每次报表后,都要给定时器重新一个初值
  • 每隔10毫秒cnt进行加1,当cnt加到100时,说明已经过了1秒了

代码优化②:

#include <REGX52.H>

sbit LED1 = P3^7;

void Timer0_Init_10ms(void)//定时器初始化10ms
{
	TMOD =0x01;							
	
	TL0 = 0x00; //0000 0000
	TH0 = 0xDC;//1101 1100
	
	TR0 = 1;
	TF0 = 0;
}

void main(void)
{ 
	int cnt = 0;
	LED1 = 1;//先让灯熄灭的状态
	Timer0_Init_10ms();
	
	while(1)
	{
		if(TF0 == 1)//10ms报表了
		{	
			TF0 = 0;//软件清零,现在不使用中断
			TL0 = 0x00; //重新给初值
			TH0 = 0xDC;
			cnt++;
			if(cnt == 100)//数100次,相当于1s
			{
				cnt = 0;
				LED1 = !LED1;
			}
			
		}
	}
}

将定时器T0初始化封装成一个函数,当需要的时候直接调用即可。
但是使用TMOD = 0x01;这样初始化也与缺陷:

假如定时器T1正在使用,且为16位定时器。则TMOD的高4位应该为:0x1(0001)
而我们使用定时器T0时TMOD初始为0x01,则TMOD的高4位为0x0(0000),则把定时器T1变为一个13位定时器了。所以还需要改进

代码优化③:

#include <REGX52.H>

sbit LED1 = P3^7;

void Timer0_Init_10ms(void)		//10毫秒@11.0592MHz
{
	//AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x00;		//设置定时初值
	TH0 = 0xDC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
}

void main(void)
{ 
	int cnt = 0;
	LED1 = 1;//先让灯熄灭的状态
	Timer0_Init_10ms();
	
	while(1)
	{
		if(TF0 == 1)//10ms报表了
		{	
			TF0 = 0;//软件清零,现在不使用中断
			TL0 = 0x00; //重新给初值
			TH0 = 0xDC;
			cnt++;
			if(cnt == 100)//数100次,相当于1s
			{
				cnt = 0;
				LED1 = !LED1;
			}
			
		}
	}
}

我们发现TMOD的初始化为:

TMOD &= 0xF0;		//设置定时器模式
TMOD |= 0x01;		//设置定时器模式

这样初始化有什么好处?

假如定时器T1正在使用,且为16位定时器。则TMOD的高4位应该为:0x1(0001),而要使用定时器T0,且也为16位定时器,则TMOD =  0x11;
TMOD &= 0xF0;表示TMOD = TMOD & 0xf0,则与出来的TMOD = 0x10,由此可见,这一步就是让TMOD的高4位不变,低4位清零。
TMOD |= 0x01;表示TMOD = TMOD | 0x01,则或出来的TMOD = 0x11,由此可见,这一步就是让TMOD的高4位不变,低4位初始化。
通过这样初始化,既保证了TMOD的高4位不变(不改变定时器T1的初始化),由对低4位进行了改变(对定时器T0初始化)。
当然:也可以直让TMOD = 0x11;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1918839.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JavaEE】网络编程——UDP

&#x1f921;&#x1f921;&#x1f921;个人主页&#x1f921;&#x1f921;&#x1f921; &#x1f921;&#x1f921;&#x1f921;JavaEE专栏&#x1f921;&#x1f921;&#x1f921; 文章目录 1.数据报套接字(UDP)1.1特点1.2编码1.2.1DatagramSocket1.2.2DatagramPacket…

数据结构复习计划之复杂度分析(时间、空间)

第二节&#xff1a;算法 时间复杂度和空间复杂度 算法(Algorithm)&#xff1a;是对特定问题求解方法(步骤)的一种描述&#xff0c;是指令的有限序列&#xff0c;其中每一条指令表示一个或多个操作。 算法可以有三种表示形式&#xff1a; 伪代码 自然语言 流程图 算法的五…

时间地点双限定|省公派教师喜提香港城市大学访问学者邀请函

X老师的研究方向为图像处理和机器学习&#xff0c;其根据专业特点及外语水平&#xff0c;将访学目标锁定在香港&#xff0c;并要求20天内获得邀请函以申报省公派。我们仅用了10天时间&#xff0c;就获得了香港城市大学的邀请函&#xff0c;且研究方向高度契合&#xff0c;完成了…

Hive的分区表分桶表

1.分区表&#xff1a; 是Hive中的一种表类型&#xff0c;通过将表中的数据划分为多个子集&#xff08;分区&#xff09;&#xff0c;每个分区对应表中的某个特定的列值&#xff0c;可以提高查询性能和管理数据的效率。分区表的每个分区存储在单独的目录中&#xff0c;分区的定义…

【正点原子i.MX93开发板试用连载体验】为什么模型不能运行在NPU上

本文最早发表于电子发烧友论坛&#xff1a;【新提醒】【正点原子i.MX93开发板试用连载体验】基于深度学习的语音本地控制 - 正点原子学习小组 - 电子技术论坛 - 广受欢迎的专业电子论坛! (elecfans.com) 昨天提到要使模型运行的NPU上&#xff0c;必须先将其量化。如果对没有量化…

构建未来对话:从零开始实现基于Vue 3的AI聊天页面

大家好&#xff0c;今天我们将一起探索如何从零开始&#xff0c;使用Vue 3构建一个AI对话页面。这个过程不仅会让我们了解Vue 3的新特性&#xff0c;还会让我们对构建交互式Web应用有一个全新的认识。如果你是编程新手&#xff0c;别担心&#xff0c;我会用通俗易懂的语言&…

汽车免拆诊断案例 | 2016款保时捷Macan车发动机故障灯异常点亮

故障现象  一辆2016款保时捷Macan车&#xff0c;搭载CYP发动机&#xff0c;累计行驶里程约为11.2万km。车主进厂反映&#xff0c;发动机故障灯异常点亮。 故障诊断  接车后试车&#xff0c;发动机怠速无明显异常&#xff0c;组合仪表上的发动机故障灯异常点亮。用故障检测仪…

数字信号处理及MATLAB仿真(4)——量化的其他概念

上回书说到AD转换的两个步骤——量化与采样两个步骤。现在更加深入的去了解以下对应的概念。学无止境&#xff0c;要不断地努力才有好的收获。万丈高楼平地起&#xff0c;唯有打好基础&#xff0c;才能踏实前行。 不说了&#xff0c;今天咱们继续说说这两个步骤&#xff0c;首先…

stm32学习笔记---MPU6050(理论部分)

目录 MPU6050简介 MPU6050参数 硬件电路 MPU6050框图 PS产品说明书和RM寄存器映像手册 PS产品说明书 RM寄存器映像 采样频率分频器 配置寄存器 陀螺仪配置寄存器 加速度计配置寄存器 数据寄存器 电源管理寄存器1 电源管理寄存器2 器件ID号 声明&#xff1a;本专…

css实现左右两端,并且对齐

<div class"card-header"><span>就诊人管理</span><el-button class"button" type"primary" >添加就诊人</el-button></div>.card-header {display: flex; //实现两端justify-content: space-between; //侧…

计算机基础 进制转化

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 ☁️运维工程师的职责&#xff1a;监…

AMEYA360:类比半导体三款车规级新品介绍

类比半导体三款全新车规级智能驱动芯片——HD70504与HD70804四通道高边驱动、HD7004低导通电阻高边驱动以及DR8112直驱马达驱动芯片介绍&#xff0c;进一步扩展了其汽车智能驱动产品的深度与广度。 新品首发&#xff0c;诠释“芯”动未来 HD70504 & HD70804四通道高边驱动芯…

Windows电脑安装Python结合内网穿透轻松搭建可公网访问私有网盘

文章目录 前言1.本地文件服务器搭建1.1.Python的安装和设置1.2.cpolar的安装和注册 2.本地文件服务器的发布2.1.Cpolar云端设置2.2.Cpolar本地设置 3.公网访问测试4.结语 前言 本文主要介绍如何在Windows系统电脑上使用python这样的简单程序语言&#xff0c;在自己的电脑上搭建…

【Spring Boot】Spring原理:Bean的作用域和生命周期

目录 Spring原理一. 知识回顾1.1 回顾Spring IOC1.2 回顾Spring DI1.3 回顾如何获取对象 二. Bean的作用域三. Bean的生命周期 Spring原理 一. 知识回顾 在之前IOC/DI的学习中我们也用到了Bean对象&#xff0c;现在先来回顾一下IOC/DI的知识吧&#xff01; 首先Spring IOC&am…

【GC 垃圾回收算法和回收器】

作者&#xff1a;ofLJli 链接&#xff1a;https://juejin.cn/post/7003213289425633287?searchId20240709085629749958B21D886D4E67D4 来源&#xff1a;稀土掘金 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 概述 在JVM中主要的结构为&…

电脑桌面文件不见了怎么恢复?需要了解的5个知识和恢复方法!

电脑桌面文件不见了怎么恢复&#xff1f;电脑文件千万条&#xff0c;数据恢复第一条。 当我们发现电脑文件丢失时&#xff0c;切勿着急&#xff0c;只要没有做二次覆盖&#xff0c;丢失的文件还是有机会找回来的。本文整理了电脑误删文件的恢复方法&#xff0c;并提供了一些列…

ZGC在三色指针中的应用

ZGC基于颜色指针的并发处理算法 ZGC初始化之后&#xff0c;整个内存空间的地址视图被设置为Remapped&#xff0c;当进入标记阶段时的视图转变为Marked0&#xff08;也称为M0&#xff09;或者Marked1&#xff08;也称为M1&#xff09;&#xff0c;从标记阶段结束进入转移阶段时…

社区团购小程序源码系统 带完整的安装代码以及搭建部署教程

系统概述 在这个数字化时代&#xff0c;线上活动成为了连接用户与组织者的桥梁。为了满足不同场景的需要&#xff0c;开发一个灵活、可定制的在线活动报名表单小程序显得尤为重要。本文将深入介绍一个自定义在线活动报名表单小程序的源码系统&#xff0c;并提供详细的搭建部署…

sublime中无法找到Package Control或Install Package

在Crtl Shift P 中无法查找到Package Control或Install Package或调用产生报错。 可以尝试在 首选项 ---- > 设置中 检查配置文件"ignored_packages":紧跟的中括号中是否为空&#xff0c;如果不为空请删除其中内容。 如果不确定内容&#xff0c;可以用下面的…

VScode代码对齐快捷键

解决复制过来代码对齐格式问题。 左对齐&#xff1a;Ctrl[ 右对齐&#xff1a;Ctrl]