当前位置: 首页 > news >正文

普中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);}	
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【eNSP模拟实验】三层交换机实现VLAN通信
  • STL(一)
  • 如何将canvas画布变成一张img图片
  • 光伏电站逆变器选型方法
  • Power BI数据分析可视化实战培训
  • 【UNI-APP】阿里NLS一句话听写typescript模块
  • web后端开发--请求响应
  • QT开发积累——qt中的注释和多行注释的几种方式,函数方法注释生成
  • 阿里云ecs服务器,nginx多域名多项目部署教程,含本地部署教程
  • pytest使用报错(以及解决pytest所谓的“抑制print输出”)
  • 在AvaotaA1全志T527开发板上使用AvaotaOS 部署 Docker 服务
  • 使用Ultralytics YOLO进行模型验证
  • 测试狗:“微观结构表征+理论计算”助力《Science》论文发表
  • 双向链表 -- 详细理解和实现
  • 51单片机(STC8051U34K64)_RA8889_SPI4参考代码(v1.3)
  • [deviceone开发]-do_Webview的基本示例
  • Computed property XXX was assigned to but it has no setter
  • HTTP那些事
  • Java方法详解
  • MySQL Access denied for user 'root'@'localhost' 解决方法
  • 给新手的新浪微博 SDK 集成教程【一】
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 如何编写一个可升级的智能合约
  • 入门到放弃node系列之Hello Word篇
  • 在Mac OS X上安装 Ruby运行环境
  • gunicorn工作原理
  • 浅谈sql中的in与not in,exists与not exists的区别
  • ​​​​​​​STM32通过SPI硬件读写W25Q64
  • ​【已解决】npm install​卡主不动的情况
  • ​secrets --- 生成管理密码的安全随机数​
  • #Java第九次作业--输入输出流和文件操作
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (笔试题)合法字符串
  • (分享)自己整理的一些简单awk实用语句
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (附源码)springboot教学评价 毕业设计 641310
  • (六)什么是Vite——热更新时vite、webpack做了什么
  • (论文阅读40-45)图像描述1
  • (四十一)大数据实战——spark的yarn模式生产环境部署
  • (算法设计与分析)第一章算法概述-习题
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (一)springboot2.7.6集成activit5.23.0之集成引擎
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • **PyTorch月学习计划 - 第一周;第6-7天: 自动梯度(Autograd)**
  • .NET 2.0中新增的一些TryGet,TryParse等方法
  • .NET 发展历程
  • .NET的数据绑定
  • .NET中使用Protobuffer 实现序列化和反序列化
  • @NoArgsConstructor和@AllArgsConstructor,@Builder
  • @Transactional事务注解内含乾坤?
  • [000-002-01].数据库调优相关学习
  • [17]JAVAEE-HTTP协议