51单片机-第四节-定时器

一、定时器:

1.介绍:

单片机内部实现的计时系统。

作用:代替长时间Daley,提高cpu效率。

数量:至少2个,T0,T1,T2等。其中T0,T1为所有51单片机共有,T2等为不同单片机特化。

工作模式:(只讲模式1)

模式0:13位定时器,计数器; 模式1:16位定时器,计数器(常用);

模式2:8位自动重装模式; 模式3:两个8位计数器

2.模式1原理:

时钟每一秒释放一个脉冲,使计数单元加一,计数单元到达最大值2^16,再加一变为0,且TF0变为1,使中断系统执行中断。

(1)时钟:

本单片机晶振周期12MHz,如果链接12分频(即+12),变为1MHz,每一微秒记一次数。

(2)控制系统:

1为取反,2为y按位或(同为0才为0),3为按位与(同为1才为1)。

本节我们将GATE置为0,则接通与否只由TR0控制,1连通,0断开。(自己推一下)

(3)中断系统:

为cpu处理紧急事件设置,如果出现紧急事件,中断系统会中断当前行动,优先处理紧急事件。

本节令 ET0 = EA = 1,PT0 = 0 即可。(只有一个中断,无所谓优先级)

什么是中断资源?

中断资源是指需要中断时,根据不同的中断源,进入不同的函数,这些函数称为中断资源。

其中,函数内部进行什么操作需自己实现。

注:不同单片机中断资源不同。

本单片机中断资源:

(4)寄存器介绍:(需要哪一个来这里找)

TMOD:定时器模式寄存器

M1,M0为控制模式的,我们运用模式1,令 M1,M0 为 0,1 即可。

TCON:定时器控制寄存器

TL0,TH0,TL1,TH1:计时系统寄存器。

(5)计时原理:

TL0,TH0共16位可计 0 - 65535,每隔1us计数+1。

需通过给TL0,TH0赋初始值,来控制计时时长。

3.定时器模块化:

cpp 复制代码
//定时器0初始化
void Time0_Init()
{
	TMOD &= 0xF0;
	TMOD |= 0x01;//可使前4位保持不变,只改变定时器0对应的后4位
	TF0 = 0;
	TR0 = 1;
	//控制计时时长,1ms计一次
	TH0 = 64535 / 256;
	TL0 = 64535 % 256 + 1;
	//中断系统
	ETO = 1;
	EA = 1;
	PT0 = 0;
}
//定时器模板1s
/*
unsigned int T0Count = 0;
void Timer0_Routine() interrupt 1
{
	T0Count++;
	TH0 = 64535 / 256;
	TH0 = 64535 % 256;
	if (T0Count >= 1000)//计到1s执行一次
	{
		T0Count = 0;
		//需执行的操作

	}
}
*/

二、实战:按键控制LED流水灯

1.循环左移和右移的库函数:

包含头文件 <INTRINS.H>

函数 crol :unsigned char crol(unsigned char a , unsigned char num);

循环左移,将变量a左移num位,到达最高位后返回最低位。

函数 cror :循环右移。

2.设置变量:

cpp 复制代码
unsigned char KeyNum,LEDMode;
//KeyNum --- 检测独立按键状态
//LEDMode --- 控制流水灯模式

3.根据LEDMode控制流水灯:(中断)

cpp 复制代码
//定时器模板1s
void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count = 0;
	T0Count++;
	TH0 = 64535 / 256;
	TL0 = 64535 % 256 + 1;
	if (T0Count >= 1000)//计到1s执行一次
	{
		T0Count = 0;
		//需执行的操作
		if (LEDMode == 0)P2 = _crol_(P2, 1);
		if (LEDMode == 1)P2 = _cror_(P2, 1);
	}
}

4.根据独立按键改变LEDMode:

cpp 复制代码
while (1)
{
	KeyNum = Key();
	if (KeyNum)
	{
		if (KeyNum == 1)
		{
			if (LEDMode == 1)LEDMode = 0;

		}
		if (KeyNum == 2)
		{
			if (LEDMode == 0)LEDMode = 1;
		}
	}

}

5.组合成品:

cpp 复制代码
#include <REGX52.h>
#include"51singlechip.h"
#include<INTRINS.H>

unsigned char KeyNum,LEDMode;

void main()
{
	P_2 = 0xFE;//初始化
	Time0_Init();
	while (1)
	{
		KeyNum = Key();
		if (KeyNum)
		{
			if (KeyNum == 1)
			{
				if (LEDMode == 1)LEDMode = 0;

			}
			if (KeyNum == 2)
			{
				if (LEDMode == 0)LEDMode = 1;
			}
		}

	}
}

//定时器模板1s
void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count = 0;
	T0Count++;
	TH0 = 64535 / 256;
	TL0 = 64535 % 256 + 1;
	if (T0Count >= 1000)//计到1s执行一次
	{
		T0Count = 0;
		//需执行的操作
		if (LEDMode == 0)P2 = _crol_(P2, 1);
		if (LEDMode == 1)P2 = _cror_(P2, 1);
	}
}
相关推荐
驴友花雕6 小时前
【花雕动手做】行空板 K10 系列实验之人工智能语音识别小车的10个参考案例
人工智能·单片机·嵌入式硬件·语音识别·行空板 k10 系列实验·花雕动手做·小车的10个参考案例
日拱一卒的小田12 小时前
ZYNQ学习笔记3-ZYNQ的IIC控制器1
笔记·单片机·学习
cardinal_50813 小时前
STM32MP157F-DK2开发板构建交叉编译链
stm32·单片机·嵌入式硬件
小羊先生car13 小时前
F429-HAL-RS485(回环/双机实验)(2026/8/16)
c语言·单片机·嵌入式硬件·软件构建
木白CPP13 小时前
Linux 驱动UART子系统源码分析
linux·运维·服务器·驱动开发·嵌入式硬件·开源软件
zlinear数据采集卡15 小时前
数据采集卡从入门到精通(10):采样率与分辨率的核心关系——反比律、架构分布与过采样
arm开发·嵌入式硬件·算法·fpga开发·架构·开源
水果里面有苹果17 小时前
33-TPS62130RGTR-3A降压器
嵌入式硬件
振南的单片机世界17 小时前
推挽vs开漏:一个“强拉硬灌”,一个“只拉不管”
arm开发·stm32·单片机·嵌入式硬件
小心亦新18 小时前
STM32学习23--I2C-1
stm32·嵌入式硬件·学习
小羊先生car18 小时前
F429-HAL-Can总线(回环及双机实验)(2026/8/15)
c语言·单片机·嵌入式硬件·软件构建