普中51单片机:定时器与计数器详解及应用(七)

在这里插入图片描述

文章目录

  • 引言
  • 定时器工作原理
  • TMOD定时器/计数器工作模式寄存器
  • 定时器工作模式
    • 模式0(13位定时器/计数器)
    • 模式1(16位定时器/计数器)
    • 模式2(8位自动重装模式)
    • 模式3(两个8位计数器)
  • 定时器配置流程
  • 代码演示——LED1间隔1秒闪烁
  • 代码演示——按键1控制LED流水灯状态
  • 代码演示——LCD1602定时器时钟显示

引言

定时器和计数器是用于测量时间间隔或计数事件的硬件模块。它们可以在许多应用中使用,例如生成精确的时间延迟、测量频率、计数外部事件等。51单片机的定时器属于单片机的内部资源,其电路的连接和运转均在单片机内部完成。本文将详细介绍51单片机中的定时器和计数器的工作原理、配置方法及其应用。

本章节将涉及中断相关的知识,具体内容可参考:中断系统讲解

注意:定时器的资源和单片机的型号是关联在一起的,不同型号的单片机可能会有不同的定时器数量和操作方式,但一般来说,T0和T1的操作方式是所有51单片机所共有的。

定时器工作原理

定时器在单片机内部就像一个小闹钟,根据时钟的输出信号,每隔“一秒”,计数单元的数值就增加一。当计数单元数值增加到“设定的闹钟提醒时间”时,计数单元就会向中断系统发出中断申请,产生“响铃提醒”,使程序跳转到中断服务函数中执行。

定时器/计数器的工作原理基于时钟脉冲。定时器模式下,它们使用内部时钟源来计数;计数器模式下,它们使用外部脉冲源来计数。每个定时器/计数器都有一个寄存器,用于存储当前的计数值。

TMOD定时器/计数器工作模式寄存器

定时和计数功能由特殊功能寄存器TMOD的控制位 C T C\sqrt{T} CT 进行选择,TMOD寄存器的各位信息如下表所列。可以看出,2个定时/计数器有四种操作模式,通过TMOD的M1和M0选择。2个定时/计数器的模式0、1和2都相同,模式3不同,各模式下的功能如下所述:
在这里插入图片描述

定时器工作模式

通过对寄存器TMOD寄存器中的M1、M0的设置,定时器/计数器0和1有四种不同的工作模式。

模式0(13位定时器/计数器)

在这里插入图片描述
工作模式图如下:
在这里插入图片描述

模式1(16位定时器/计数器)

模式1除了使用了TH0及TL0全部16位外,其他与模式0完全相同。此模式下,TL0的8位溢出向TH0进位,TH0溢出置位TCON中的溢出标志位TF0。

当GATE=0(TMOD.3)时,如TR0=1,则定时器计数。GATE=1时,允许由外部输入INTO控制定时器0,这样可实现脉宽测量。TRO为TCON寄存器内的控制位,TCON寄存器各位的具体功能描述见上节TCON寄存器的介绍。

注意:STC89C51RC/RD+系列单片机的定时器有两种计数速率:一种是12T模式,每12个时钟加1,与传统8051单片机相同;另外一种是6T模式,每6个时钟加1,速度是传统8051单片机的2倍T0的速率在烧录用户程序时在STC-ISP编程器中设置。

模式2(8位自动重装模式)

此模式下定时器/计数器可自动重装载8位计数器,TL0的溢出不仅置位TF0,而且将TH0内容重新装入TL0。(TH0可先设置好,重装时TH0内容不变)
在这里插入图片描述

模式3(两个8位计数器)

对定时器0,在此模式中,定时器1停止计数,效果与将TR1设置为0相同。


对定时器0,此模式下定时器0的TL0及TH0作为2个独立的8位计数器。下图为模式3时的定时器0逻辑图。TL0占用定时器0的控制位: C T C\sqrt{T} CT 、GATE、TRO、INTO及TFO。THO限定为定时器功能(计数器周期),占用定时器1的TR1及TF1。此时,TH0控制定时器1中断。

模式3是为了增加一个附加的8位定时器/计数器而提供的,使单片机具有三个定时器/计数器。模式3只适用于定时器/计数器0,定时器T1处于模式3时相当于TR1-0,停止计数,而T0可作为两个定时器用。
在这里插入图片描述

定时器配置流程

  1. 对TMOD赋值,以确定T0和T1的工作方式。
  2. 根据所要定时的时间计算初值,并将其写入TH0、TL0或TH1、TL1。
  3. 如果使用中断,则对EA赋值,开放定时器总中断。
  4. 使TR0或TR1置位,启动定时/计数器定时或计数。

注意:STC-ISP烧写工具自带计算所要定时的时间计算初值,可根据自己选择的模式,进行复制代码即可
在这里插入图片描述

代码演示——LED1间隔1秒闪烁

通过定时器0中断控制LED1指示灯间隔1秒闪烁,实物图连接:D1连接到P2_0引脚即可,使用的12.000MHz的时钟,每次间隔一毫秒触发中断,在中断触发函数进行计数,当为1000时,就是一秒。

#include <REGX52.H>

sbit LED1 = P2^0;

void External0_ISR(void) interrupt 1
{
	static unsigned int count = 0;
	TL0 = 0x18;	//需要手动复原			
	TH0 = 0xFC;	//需要手动复原
    // 中断处理代码
	if(count == 1000)
	{
		count = 0;
		LED1 = !LED1;
	}
	count++;
}


void Timer0_Init(void)		//1毫秒@12.000MHz
{
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x01;			//设置定时器模式
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	ET0 = 1;//打开T0中断
	EA = 1;//打开总中断
	TR0 = 1;				//定时器0开始计时
}


void main()
{
	Timer0_Init();
	while(1)
	{
		
	}	
}

代码演示——按键1控制LED流水灯状态

在此演示中,使用了INTRINS.H库中的_crol_左移和_cror_右移函数,当按下KEY1按键时,LED流水灯就会切换方向状态进行闪烁。实物图连接:K1连接P0_0引脚,LED八个灯插入P2引脚。

  • cror(unsigned char val, unsigned char n): 字符循环右移,将 val 循环右移 n 位。
  • crol(unsigned char val, unsigned char n): 字符循环左移,将 val 循环左移 n 位
#include <REGX52.H>
#include <INTRINS.H>

sbit KEY1 = P0^0;
sbit KEY2 = P0^1;
unsigned char LEDMode;

void DelayXms(unsigned int xms)	//@12.000MHz
{
	unsigned char data i, j;
	
	while(xms)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}
}

void Timer0_Init(void)		//1毫秒@12.000MHz
{
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x01;			//设置定时器模式
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	ET0 = 1;//打开T0中断
	EA = 1;//打开总中断
	TR0 = 1;				//定时器0开始计时
}

void External0_ISR(void) interrupt 1
{
	static unsigned int count = 0;
	TL0 = 0x18;	//需要手动复原			
	TH0 = 0xFC;	//需要手动复原
    // 中断处理代码
	if(count == 1000)
	{
		count = 0;
		if(LEDMode == 0)
			P2 = _crol_(P2,1);
		if(LEDMode == 1)
			P2 = _cror_(P2,1);

	}
	count++;
}

unsigned char Getkey()
{
	unsigned char keyNumber = 0;
	if(KEY1 == 0)
	{
		DelayXms(5);
		while(KEY1 == 0);
		DelayXms(5);
		keyNumber = 1;
	}
	if(KEY2 == 0)
	{
		DelayXms(5);
		while(KEY2 == 0);
		DelayXms(5);
		keyNumber = 2;
	}
	return keyNumber;
}


void main()
{
	unsigned char keyNum = 0;
	P2 = 0xfe;
	Timer0_Init();
	while(1)
	{
		keyNum = Getkey();
		if(keyNum)
		{
			if(keyNum == 1)
			{
				LEDMode++;
				if(LEDMode>=2)
				{
					LEDMode = 0;	
				}
			}
		}
	}
}

代码演示——LCD1602定时器时钟显示

此演示代码使用LCD1602模块作为显示,LCD1602模块不过多讲解,后续会提供专门的章节说明。需要LCD1602库可以私聊我。实物图连接:板子插上LCD1602模块即可。

#include <REGX52.H>
#include "LCD1602.h"

unsigned char Sec=55,Min=59,Hour;//秒分时

void DelayXms(unsigned int xms)	//@12.000MHz
{
	unsigned char data i, j;
	
	while(xms)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}
}

void Timer0_Init(void)		//1毫秒@12.000MHz
{
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x01;			//设置定时器模式
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	ET0 = 1;//打开T0中断
	EA = 1;//打开总中断
	TR0 = 1;				//定时器0开始计时
}

void External0_ISR(void) interrupt 1
{
	static unsigned int count = 0;
	TL0 = 0x18;	//需要手动复原			
	TH0 = 0xFC;	//需要手动复原
    // 中断处理代码
	if(count == 1000)
	{
		count = 0;
		Sec++;
		if(Sec == 60)
		{
			Sec = 0;
			Min++;
			if(Min == 60)
			{
				Min = 0;
				Hour++;
				if(Hour == 24)
				{
					Hour = 0;
				}
			}

		}
	}
	count++;
}

void main()
{
	Timer0_Init();
	LCD_Init();
	LCD_ShowString(1,1,"Time:");
	LCD_ShowString(2,1,"00:00:00");
	while(1)
	{
		LCD_ShowNum(2,1,Hour,2);
		LCD_ShowNum(2,4,Min,2);
		LCD_ShowNum(2,7,Sec,2);
	}	
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

企业数据治理做完了,如何让业务部门用起来

引言&#xff1a;企业数据治理完成后&#xff0c;确保业务部门能够充分利用这些数据并融入日常运营中&#xff0c;是实现数据价值最大化的关键步骤。以下是一些策略和建议&#xff0c;帮助推动业务部门使用数据治理成果&#xff1a; 一、管理层面推广 高层应用示范&#xff1…

【漏洞复现】方正全媒体采编系统——binary.do——SQL注入

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 方正全媒体采编系统&#xff08;FZMediaEditor&#xff09;是一…

网络安全第一次作业

需求 前置工作 给设备配好ip地址&#xff0c;并且在总公司处配置vlan 1&#xff0c; 先建立多个安全区域 接着新建两个策略 :办公区访问dmz区域策略&#xff0c;生产区访问dmz区域策略 2 &#xff0c; 不做配置即可&#xff0c;生产区本不允许访问互联网 3&#xff0c; 新…

学习大数据DAY14 PLSQL基础语法3

目录 二重循环 三种循环随便嵌套 exit continue return 作业 数据提取 游标 隐式游标 显示游标 动态游标 游标使用流程 游标属性 游标配合循环使用示例 作业2 参数游标 current of 语句 作业3 PLSQL基础语法&#xff08;三&#xff09; 二重循环 三种循环随便嵌…

LangChain框架详解

LangChain框架详解 LangChain是一个基于语言模型开发应用程序的强大框架&#xff0c;旨在帮助开发人员简化与大模型交互、数据检索以及将不同功能模块串联起来以完成复杂任务的过程。它提供了一套丰富的工具、组件和接口&#xff0c;使开发人员能够轻松构建上下文感知和具备逻…

Qt:19.浮动窗口/子窗口(子窗口介绍、代码方式创建子窗口、设置子窗口标题、为子窗口添加控件、设置子窗口停靠位置)

目录 1.子窗口介绍&#xff1a; 2.代码方式创建子窗口&#xff1a; 3.设置子窗口标题&#xff1a; 4.为子窗口添加控件&#xff1a; 5.设置子窗口停靠位置。 1.子窗口介绍&#xff1a; 在 Qt 中&#xff0c;可以创建和管理子窗口&#xff08;子窗口体&#xff09;以实现多窗…

线程安全(二)synchronized 的底层实现原理、锁升级

目录 一、基础使用1.1 不加锁的代码实现1.2 加锁的代码实现二、实现原理2.1 synchronized 简介2.2 对象监控器(Monitor)2.3 加锁过程第一步:判断 Owner 指向第二步:进入 EntryList 阻塞第三步:主动进入 WaitSet 等待三、锁升级3.1 对象的内存结构3.2 Mark Word 对象头3.3 …

python的简单爬取

需要的第三方模块 requests winr打开命令行输入cmd 简单爬取的基本格式&#xff08;爬取百度logo为例&#xff09; import requests url"http://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" resprequests.get(url)#回应 #保存到本地 with open(&…

地址翻译过程(TLB-->页表-->Cache-->主存-->外存)

目录 1.地址结构 2.查找快表或页表&#xff1a;从虚拟地址--->物理地址 3.通过物理地址访问数据 设某系统满足以下条件&#xff1a; •有一个TLB与一个data Cache •存储器以字节为编址单位 •虚拟地址 14位 •物理地址 12位 •页面大小为 64B •TLB 为四路组相联&#x…

嵌入式工程师从0开始,到底该学什么,怎么学?

作为嵌入式工程师&#xff0c;从零开始学习需要掌握以下几个关键方面。我收集归类了一份嵌入式学习包&#xff0c;对于新手而言简直不要太棒&#xff0c;里面包括了新手各个时期的学习方向编程教学、问题视频讲解、毕设800套和语言类教学&#xff0c;敲个22就可以免费获得。 基…

【高中数学/指数函数、对数函数、正弦函数】求 y=2^x+x,y=log2_x+x,y=2*sinX+x 的零点位置大小关系

【问题】 已知函数f(x)2^xx,g(x)log2_xx,h(x)2*sinXx 的零点分别是a,b,c,则a、b、c的大小顺序是&#xff1f; 【解答】 粗览三个函数&#xff0c;h(x)2*sinXx的零点是最好解决的&#xff0c;明显x0时h(x)0&#xff0c;因此c在原点的位置&#xff1b; 对于f(x)2^xx&#xff…

【C++BFS】690. 员工的重要性

本文涉及知识点 CBFS算法 LeetCode690. 员工的重要性 你有一个保存员工信息的数据结构&#xff0c;它包含了员工唯一的 id &#xff0c;重要度和直系下属的 id 。 给定一个员工数组 employees&#xff0c;其中&#xff1a; employees[i].id 是第 i 个员工的 ID。 employees[…

怎样在 C 语言中实现堆排序?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01; &#x1f4d9;C 语言百万年薪修炼课程 【https://dwz.mosong.cc/cyyjc】通俗易懂&#xff0c;深入浅出&#xff0c;匠心打磨&#xff0c;死磕细节&#xff0c;6年迭代&…

人类大脑的计算与机器的类脑计算

人类大脑的计算基本原理涉及到神经元的基本工作方式、神经网络的结构和连接模式、信息传递的方式、学习和记忆的机制等多个层面的复杂互动&#xff0c;这些原理的深入理解不仅有助于神经科学的发展&#xff0c;还为人工智能领域的发展提供了重要的启示和指导。人类大脑计算基本…

按下快门前的算法——对焦

对焦算法可以分为测距式&#xff0c;相位式&#xff0c;反差式。 其中测距式是通过激光&#xff0c;&#xff08;TOF&#xff0c;Time of Flight&#xff09;等主动式地得知物距&#xff0c;然后对焦。更常用的是后两者。 反差式CDAF&#xff08;Contrast Detection Auto Foc…

Lingo学习(二)——线性规划基础、矩阵工厂

一、线性规划基础 &#xff08;一&#xff09;方法 ① 一个线性规划中只含一个目标函数。(两个以上是多目标线性规划,Lingo无法直接解) ② 求目标函数的最大值或最小值分别用max …或min …来表示。 ③ 以!开头,以;结束的语句是注释语句; ④ 线性规划和非线性规划的本质…

Node.js如何在Windows安装?

文章目录 主要特点&#xff1a;使用场景&#xff1a;安装方法验证是否安装成功 Node.js 是一个开源、跨平台的JavaScript运行环境&#xff0c;由Ryan Dahl于2009年创建。它允许开发者在服务器端运行JavaScript代码。Node.js 基于Chrome V8 JavaScript引擎构建&#xff0c;其设计…

mobx学习笔记

mobx介绍 mobx是一个功能强大&#xff0c;上手容易的状态管理工具。MobX背后的哲学很简单:任何源自应用状态的东西都应该自动地获得。利用getter和setter来收集组件的数据依赖关系&#xff0c;从而在数据发生变化的时候精确知道哪些组件需要重绘。 mobx和redux的区别 mobx更…

【安全设备】APT攻击预警平台

一、什么是APT 高级持续性威胁&#xff08;APT&#xff09;是一种高度复杂和长期的网络攻击&#xff0c;旨在通过持续监视和访问特定目标来窃取敏感信息或进行其他恶意活动。这种攻击结合了多种先进的技术手段和社会工程学方法&#xff0c;以极高的隐蔽性实现长期潜伏和信息窃…

【排序算法】计数排序

目录 一.基本思想 二.缺陷及优化 三.代码实现 四.特性总结 1.可以排序负数 2.适合范围集中的整数 3.时间复杂度&#xff1a;O(Nrange) 4.空间复杂度&#xff1a;O(range) 5.稳定性&#xff1a;稳定 一.基本思想 根据待排序数组a创建一个新的数组count&#xff0c;该数组…