51单片机--定时器与按键控制流水灯模式

文章目录

  • 定时器
    • 定时器的介绍
    • 定时器的作用
    • 定时器框图
    • 定时器的工作模式
    • 计数器原理图:
  • 中断系统
    • 中断程序流程
    • STC89C52的中断资源
    • 定时器和中断系统
  • 定时器的相关寄存器
    • TCON
    • TMOD
    • TH与TL
    • 有关中断的寄存器
  • 按键控制流水灯模式

定时器

定时器的介绍

51单片机上的定时器是一种硬件模块,用于计时和生成特定的时间延迟。它的电路和运转都在单片机内完成,它是嵌入在单片机内部的一个功能模块,具有多种工作模式和功能。
定时器在该芯片里头

在51单片机中,通常有两个定时器/计数器:定时器0(Timer 0)和定时器1(Timer 1)。每个定时器都有一个相应的控制寄存器,用于设置相关参数和配置工作模式。在我们这款STC89C52上还多一个T2的定时器;

定时器的作用

1.用于计时系统,可以实现软件计时,或者使程序每隔一定的时间就完成一项任务;
2.替代长时间的Delay,提高CPU运行效率和处理速度;

我们在前面学习了用Delay函数进行延迟,但对于Delay函数来说,我们在完成一件任务时,当它开始延迟时,我们需要停下我们CPU的手上所有的运行,等他延迟之后我们才可以继续操作,因为对于所有子函数来说,我们都需要在主函数(main)中完成,当发生Delay时,就没有办法完成其他操作,所以Delay无法实现多任务线程的工作,例如下面的一边流水灯,一边用按键控制;而对于定时器来说,恰好解决了这一难题。

定时器框图

定时器在单片机内部就像一个小闹钟一样,根据时钟的输出信号(脉冲),每隔一段时间,那么计数单元的数值就会加一,当计数单元达到最大值后,那么计数单元就会向中断系统发出申请,让他开始执行中断服务函数。
在这里插入图片描述

定时器的工作模式

对于定时器来说,是有多种模式可以选择的,不只是会让计数单元一直加一加一,也可以是加十加十,这就相当于我们选择了另外一种模式;
对于STC89C52的T0和T1来说,都有四种工作模式:

模式0:13位定时器/计数器
模式1:16位定时器/计数器(常用)
模式2:8位自动重装模式
模式3:两个8位计数器

在这里,对于我们来说,模式1是我们这篇文章要讲的,其他的像模式0和模式3,一般情况我们是用不到的,而模式2:8位自动重装模式,主要用于串口通信产生波特率进行调节;

在这里插入图片描述
在这里,我们按照上面的框图分为时钟系统,计数系统,中断:
在这里插入图片描述

计数器原理图:

时钟系统:
在这里插入图片描述

SYSclk:system clock系统时钟,它具有晶振周期,在本开发板上晶振为11.0592MHz,是一个非常大的数字,换算成时间的话就约为9ns左右(T=1/f),可以产生脉冲,将脉冲传入计数系统,然后系统时钟可以有两种模式选择分频,也就是将频率降低;在这里,我们选择的是12T;T0 Pin是外接口引脚,可以由外接口连上一个计时器,每个一个周期脉冲就会加1,那么计时器也就可以变为计数器,通过计算脉冲来达到计数效果;也就是将C/T=0;

计数系统:
在这里插入图片描述

TR0,是计时器T0的运行控制位,相当于一个启动器(按钮),只有TR0启动之后,那么技术系统才会开始计数;TL0和TH0分别表示低位和高位,用来计算脉冲传过来的次数,每一次的脉冲过来就加一,这两个加起来总共有16bit位,那么就表示计数系统可以计算0~65535(2^16-1)次,当计数达到最大值时,就会向中断系统发出中断请求

中断:
在这里插入图片描述

TF0也就是中断溢出的标志位,简单的来说就是消息提醒,向CPU告知需要中断了,中断就需要进入中断系统;

中断系统

介绍:

单片机的中断系统是指单片机处理外部事件或者内部事件时的一种机制。在单片机执行程序的过程中,可能会遇到一些特殊情况,比如定时时间到、有外部设备的输入信号等。这时,CPU需要临时停止当前的程序,转去执行相应的中断处理程序,待处理完该事件后再返回原先的程序继续执行。这个定义很好理解,就像睡觉一半被闹钟叫醒去读书一样,闹钟在你睡觉途中打断你的睡觉,让你该去读书了,这个过程就是中断;

组成部分:

中断源:指引起中断的事件或信号源,可以是外部设备产生的输入信号,也可以是定时器的时间到达等。
中断控制器:负责对各个中断源的优先级进行管理和调度,确定哪个中断请求能够被CPU响应。
中断向量表:用于存储每个中断类型对应的中断处理程序的入口地址。
中断处理程序:是指处理具体中断事件的程序代码,根据中断类型执行相应的操作,处理完后返回到原先的程序继续执行.

作用:

实时性:中断系统可以及时响应外部事件,提高系统的实时性能。
节约CPU资源:通过使用中断系统,CPU不再需要不断地轮询外部设备状 态,而是在需要处理事件时才会被中断,节约了CPU的资源。
提高系统效率:使用中断系统可以使单片机在处理外部事件时不需要等待,减少了等待时间,提高了系统的效率。
灵活性:通过中断系统,可以方便地处理不同类型的事件,增加了系统的灵活性和扩展性。

中断程序流程

在这里插入图片描述

在我们的认知里,一般都会在主函数中执行程序,但如果有中断函数存在的话,当主程序发出中断请求时,程序就会停止主程序,优先处理中断函数中的程序,处理完再返回主程序,这就是中断程序的流程,在下面的代码中将会有进一步加深印象;

STC89C52的中断资源

在STC89C52中有8个中断资源:外部中断、定时器0中断、外部中断1、定时器1中断、串口中断、外部中断2、外部中断3;
中断的优先级个数有4个;
在这里插入图片描述
在这里i,函数后面的nterrupt+序列号就是表示不同的中断资源,当中断请求向CPU发出后中断系统响应后,那么就会执行这个中断程序;

定时器和中断系统

在这里插入图片描述

这里的中断系统实际上是简化的了,但对于原理来说,其实是一致的,为了方便对初学者的了解,才使用该原理图;

这个就是定时器连接着中断系统了。当我们计数系统满的时候,就会向TF0标志位告知,让它发出中断请求,接着就是ETO得闭合,允许T0中断,然后就是PT0选择0,选择好定时器的优先级;
在这里插入图片描述

定时器的相关寄存器

在前面几篇文章,我们使用的寄存器相对来说是比较少的,对于定时器来说,它有以下的相关寄存器:
在这里插入图片描述
在这里插入图片描述
我们可以看到对于计时器和中断系统的寄存器来说,还是相当多的,对于中断寄存器的,我们只挑出相关定时器的寄存器来讲;

TCON

在这里插入图片描述

寄存器都会有相应的地址,程序会通过指针指向的地址来找到对应的寄存器位置,寄存器一般有8个bit位,这里的可位寻址,表示根据它的bit位来寻找对应的地址;

首先T1和T0对应的bit位功能基本相同,所以这里只对T0展开论述;

TF0:定时器T0溢出中断标志(Timer Flag)。 T0开始计数后,但计数达到最大值后,开始产生溢出,TF0会由硬件置“1”,向CPU发出请求中断,CPU响应后,TF0才由硬件置“0”。
TR0:定时器T0控制位(Timer Run); 当GATE(一个开关)=0,TR0=1 T0开始计数,TR0=0禁止T0计数;
IE0:外部中断0请求源标志(Interrupt Enable);IE0=1外部中断0向CPU请求中断,CPU响应后,外部中断0由硬件清‘0’IE0;
IT0:外部中断0触发方式控制位(Interrupt Trigger);IT0=0时,外部中断0为低电平触发方式,输入低电平时,置位IE0。当IT1=0时,则外部中断0端口由“1”->"0"下降沿跳变,激活中断请求标志位IE0,向主机请求中断处理。

TMOD

在这里插入图片描述

这里不可位寻址就是不能利用TMOD的bit位来寻找对应的地址,必须使用TMOD寄存器,直接对它赋值

GATE与C/T这里不涉及就不再讲,M1和M0时选择定时器的模式:
在这里插入图片描述

这里由于是不可位寻址,我们用到了一种巧妙的方式——按位运算,对于我们要实现定时器0模式1 那么我们可以先对TMOD按位与0xF0,使TMOD定时器0都保持为0,接着用按位或的按位运算,将它或上0x01,这种做的目的是不用管TMOD的初始状态是什么,与上1就是1;

TH与TL

TH与TL后面跟0就表示定时器0的计数,后面跟1就表示定时器1的计数。

有关中断的寄存器

在这里,我们跟着原理图的走向,列出相关的寄存器;

==EA:CPU的中断允许控制位(Interrupt All);==这是一个总的中断控制,当EA=0,CPU将会屏蔽所有的中断申请;EA=1才允许申请。
ET0:T0的溢出中断允许位;ET0=1,允许T0中断;
PT0: 一个特殊位申请,当PT0=0,为中断优先级;PT0=1时为高级优先权。

按键控制流水灯模式

这里我们需要对定时器进行初始化
Timer0.h

#ifndef __TIMER0_H__
#define __TIMER0_H__

void Timer0Init();

#endif

Timer0.c:

#include <REGX52.H>
void Timer0Init()		//1毫秒@11.0592MHz
{
	TMOD &= 0xF0;
	TMOD |= 0x01; //设置定时器模式
	TL0 = 0x66;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0=1;     //允许T0中断
	EA=1;       //CPU开放中断
	PT0=0;      //定时器0中断优先级
}

这里初始化的是可以走1ms的定时器,首先需要对定时器0模式选择为1,然后设置定时的初值,根据每一个计数到下一个计数的时间差,从65535向前推算需要多少个计数,进行对应的高低位初始化;那么1ms后就会向TF0发出中断请求;TF0初始化为0;TR0选择1,让计时器计时,ET0选择1允许T0中断,EA为总中断控制位,选择1为打开,PT0选择0为低级中断优先级

接着我们写一个按键选择函数:
Delay.h:

#ifndef __DELAY_H__
#define __DELAY_H__

void Delayms(unsigned int x);

#endif

Delay.c

oid Delayms(unsigned int x)		//@11.0592MHz
{
	unsigned char i, j;

	while(x--)
	{
	
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
	}
}

Key.h

#ifndef __KEY_H__
#define __KEY_H__

unsigned char Key();

#endif

Key.c

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

/**
  * @brief 获取独立按键键码
  * @param 无
	* @reval 按下按键的键码,范围0~4,无按键按下时返回值为0
  */
unsigned char Key()
{
		unsigned char KeyNumber=0;
		if(P3_1==0){Delayms(20);while(P3_1==0);Delayms(20);KeyNumber=1;}
		if(P3_0==0){Delayms(20);while(P3_0==0);Delayms(20);KeyNumber=2;}
		if(P3_2==0){Delayms(20);while(P3_2==0);Delayms(20);KeyNumber=3;}
		if(P3_3==0){Delayms(20);while(P3_3==0);Delayms(20);KeyNumber=4;}
		
		return KeyNumber;
}

最后写上主函数:

#include <REGX52.H>
#include "Timer0.h"
#include "Key.h"
#include <INTRINS.H>
unsigned char KeyNum,LEDMode;
void main()
{
	P2=0xFE;
	Timer0Init();
	while(1)
	{
		KeyNum=Key();
		if(KeyNum==1)
		{
					LEDMode++;
					LEDMode%=2;
		}
	}
}
	

void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count;
	TL0 = 0x66;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	T0Count++;
	if(T0Count>=500)
	{
		T0Count=0;
		if(LEDMode==0)
				P2=_crol_(P2,1);
		if(LEDMode==1)
				P2=_cror_(P2,1);
	}
}

在主函数里,先对P2和定时器进行初始化,然后在循环里面走独立按键的程序,每当按一次按键1,LEDCode就会在0和1依次循环选择;
然后是中断函数,1表示是计时器的中断程序,每当计时器计数溢出时,那么我们就开始中断主程序,对中断函数开始执行,先重新对计时器初始化,便于下一次计时,这里ToCount表示多少毫秒走一次LED灯,当LEDMode为0时,向左跑流水灯,LEDMode为1时向右跑流水灯;这里的 crol()是一个LED流水灯函数,第二个参数表示每一次跨越的灯数,1也就是表示跨越一个灯数,就会形成我们的流水灯。

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

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

相关文章

基于Springboot的宠物店管理系统(源代码+数据库)087

基于Springboot的宠物店管理系统(源代码数据库)087 一、系统介绍 本系统分为管理员、店员两种角色 店员角色包含以下功能&#xff1a; 登录、宠物主人管理、宠物管理、宠物医疗管理、宠物销售管理、宠物寄养管理、宠物用品管理、宠物日常服务管理、宠物常见问题、个人中心、…

CSDN 个性化推荐系统的设计和演进

个性化推荐项目 个性化推荐的设计和演进项目概览项目梳理依赖管理实现代码的重构和改进持续演化 个性化推荐的设计和演进 CSDN 的个性化推荐系统&#xff0c;是从既有的推荐项目中剥离出来的一个子项目&#xff0c;这个项目随后移交到了我们AI组。在近一年的时间内&#xff0c…

Apollo、RocketMQ加载顺序问题

在SpringCloudAlibaba框架中&#xff0c;因Nacos配置中心管理权限过于简单&#xff0c;决定用Apollo代替Nacos配置中心&#xff0c;但在启动时&#xff0c;Nacos、Redis等配置读取正常&#xff0c;RocketMQ由于启动过早&#xff0c;无法从Apollo读取自己的服务地址配置。 报错…

第41节:cesium 闪烁效果-熊出没(含源码+视频)

结果示例: 点的闪烁:1.逐渐放大后消失;2.点闪烁。 图的闪烁:熊出没,含自定义显示文字效果。 完整源码: <template><div class="viewer"><vc-viewer @ready="ready" :logo="false">

科技资讯|苹果Vision Pro手部追踪和手势相关新专利曝光

近日&#xff0c;美国专利商标局正式授予苹果一项与 Apple Vision Pro 主要功能相关的专利&#xff1a;手部追踪和手指手势。 苹果专利指出&#xff0c;沉浸感的质量取决于几个重要因素。例如&#xff0c;显示器的特性&#xff0c;如图像质量、帧率、像素分辨率、高动态范围 …

信号波形时序图常用工具推荐

Refer: 下载&#xff1a;画时序图的四大神器_可编程器件-面包板社区 (eet-china.com) 软件工程师&#xff0c;习惯使用StarUML画Timing Diagram, 硬件工程师建议使用一下软件。 1、AndyTiming 免费的&#xff0c;这个有一个知乎的博文可以参考 https://zhuanlan.zhihu.com/p…

如何成为微软MVP?

对一个普通的开发人员来说&#xff0c;最大的认可就是得到微软官方的MVP 认证了&#xff0c;是一份对技术人的荣誉证书。 微软的MVP是相对公平公正的&#xff0c;只要你热爱技术&#xff0c;热爱分享&#xff0c;在一定的领域里有足够的深度&#xff0c;就会得到微软官方的认证…

MURF2080CT-ASEMI快恢复二极管对管MURF2080CT

编辑&#xff1a;ll MURF2080CT-ASEMI快恢复二极管对管MURF2080CT 型号&#xff1a;MURF2080CT 品牌&#xff1a;ASEMI 封装&#xff1a;TO-220F 恢复时间&#xff1a;75ns 正向电流&#xff1a;20A 反向耐压&#xff1a;800V 芯片个数&#xff1a;2 引脚数量&#xf…

〖码银送书第三期〗《Python机器学习:基于PyTorch和Scikit-Learn》

前言 近年来&#xff0c;机器学习方法凭借其理解海量数据和自主决策的能力&#xff0c;已在医疗保健、 机器人、生物学、物理学、大众消费和互联网服务等行业得到了广泛的应用。自从AlexNet模型在2012年ImageNet大赛被提出以来&#xff0c;机器学习和深度学习迅猛发展&#xf…

WebDAV之π-Disk派盘 + PDF Expert

PDF Expert 支持WebDAV方式连接π-Disk派盘。 PDF Expert是一款macOS上的办公软件,它具有专业的PDF编辑功能,可以快速从邮件、网页支持PDF打开,支持用户进行阅读、批注等功能,用户可以直接在PDF上进行编辑文字图片,表单文档、创建笔记、添加书单等自定义使用,大大提高工…

C国演义 [第五章]

第五章 子集题目理解步骤树形结构递归函数递归结束的条件单层逻辑 代码 子集II题目理解步骤树形结构递归函数递归结束的条件单层逻辑 代码 子集 力扣链接 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的子集&#xff08;幂集&#xff09;。…

HarmonyOS/OpenHarmony应用开发-程序包多HAP机制(上)

一、多HAP机制设计目标 方便开发者模块化的管理应用&#xff0c;好的应用一般都是模块化管理&#xff0c;模块之间属于松耦合关系。多HAP方便了开发者将业务划分成多个模块&#xff0c;每个模块放到独立的HAP中。例如支付类应用&#xff0c;有统一的主界面&#xff0c;主界面管…

Windows mingw64 最简易 安装配置

其实挺简单一件事 很多教程都搞复杂了 自己写一个 只需要两步 1. 下载压缩包并解压 2. 配置环境变量 (1). GitHub 下载地址 Releases niXman/mingw-builds-binaries GitHub 如果GitHub下载太慢可以来这里加速 或者用地址2 GitHub Proxy 代理加速 (ghproxy.com) (2). 下…

学无止境·MySQL⑥(数据库备份和还原)

数据库备份和还原 备份和还原练习1、创建库和表2、使用mysqldump命令备份数据库中的所有表3、备份booksDB数据库中的books表4、使用mysqldump备份booksDB和test数据库5、使用mysqldump备份服务器中的所有数据库6、使用mysql命令还原第二题导出的book表7、进入数据库使用source命…

Rainbond开源

Rainbond的 Gateway API 插件制作实践 Gateway API 作为新一代的流量管理标准&#xff0c;对原有 Ingress 的扩展不规范、移植性差等问题做出了改进。从兼容K8s生态和优化网关体验出发&#xff0c;Rainbond 支持以插件的形式扩展平台网关能力&#xff0c;目前已经有多家社区提供…

领域知识图谱的医生推荐系统:利用BERT+CRF+BiLSTM的医疗实体识别,建立医学知识图谱,建立知识问答系统

项目设计集合&#xff08;人工智能方向&#xff09;&#xff1a;助力新人快速实战掌握技能、自主完成项目设计升级&#xff0c;提升自身的硬实力&#xff08;不仅限NLP、知识图谱、计算机视觉等领域&#xff09;&#xff1a;汇总有意义的项目设计集合&#xff0c;助力新人快速实…

DevOps基础服务1——版本控制gitlab

文章目录 一、基本了解1.1 安装git客户端1.2 git命令1.2.1 本地仓库1.2.2 远程仓库 二、安装gitlab三、功能管理3.1 创建账号3.2 用户注册授权通知功能3.3 创建项目远程库3.4 ssh设置3.5 克隆远程库项目到本地3.6 上传本地项目代码到远程库3.7 授权用户查看项目权限 一、基本了…

electron+vue3全家桶+vite项目搭建【21】自定义无边框窗口拖拽移动

文章目录 引入实现思路实现步骤1.主进程监听窗口移动2.通信工具补充ipc调用3.渲染进程封装通用拖拽组件 测试 引入 如果你尝试过透明窗口&#xff0c;并控制透明部分事件击穿&#xff0c;就会发现使用 drag属性样式去控制窗口拖拽会导致点击事件失效&#xff0c;并且带drag属性…

陌陌聊天数据分析 (一)

陌陌聊天数据分析&#xff08;一&#xff09; 目标 基于Hadoop和Hive实现聊天数据统计分析&#xff0c;构建聊天数据分析报表 需求 统计今日总消息量统计今日每小时消息量&#xff0c;发送和接收用户数量统计今日各地区发送消息数据量统计今日发送消息和接收消息用户数统计…

机器学习 day25(softmax在神经网络模型上的应用,提高数据精度的方法)

输出层采用softmax 在识别手写数字的模型中&#xff0c;预测y只有两个结果&#xff0c;所以输出层采用sigmoid激活函数且只有一个神经元。若预测y有10个结果&#xff08;0-9&#xff09;&#xff0c;该模型的前向传播计算方式与识别数字的模型完全相同&#xff0c;即隐藏层的…