51单片机-实现定时器模块教程

本章概述思维导图:

51单片机驱动定时器模块

CPU时序简介

CPU时序定义了CPU内部操作的时间节奏,以下从四个时序周期进行逐步解析;

1、振荡周期

振荡周期:CPU内部时钟源产生的最小时间单位,由晶振或内部振荡器决定;

公式为:T osc=1 / f osc; f osc为时钟频率

作用为:所有操作的基础时间单位,CPU所有动作均同步于此信号。

2、状态周期

状态周期:部分CPU(如8051)将振荡周期分为两个状态(高电平与低电平),每个状态周期包含两个振荡周期

公式为:T state=2×T osc;

3、机器周期

机器周期:完成一个基本操作(如取指、读写内存)所需的时间,由多个状态周期或振荡周期组成;1个机器周期=6个状态周期=12个振荡周期(以8051为列);

公式为:T machin=6×T state=12×Tosc

作用:CPU执行指令的阶段性时间单位,所有指令均由若干机器周期组成。

4、指令周期

指令周期:执行一条完整指令所需要的全部时间,包含取指、解码、执行等阶段。

公式为:指令周期=N个机器周期(1<= N <=4)

简单指令(如NOP):1个机器周期

复杂指令(如乘法):4个机器周期(8051为例)

例如:外接晶振为12MHZ时,51单片机相关周期的具体值为:

振荡周期:1/12us;

状态周期:1/6us;

机器周期:1us;

指令周期:1us-4us;


定时器简介

51单片机定时器原理

定时原理的核心:机器周期与计数频率;

机器周期:51单片机执行一条单周期指令所需的时间(如12个振荡周期,假设时钟频率为12MHZ时,机器周期为1us);

定时器计数频率:定时器的计数频率为机器周期的倒数,即每过一个机器周期,定时器计数值加1;公式为:f timer =1 / T machin;若T machin=1us,则f timer=1MHZ(即每秒计数1000000次)

51单片机定时器工作模式

STC89C51RC/RD+系列单片机内部设置的两个16位定时器/计数器T0和T1都具有计数方式和定时方式两种工作方式。对每个定时器/计数器(TO和T1),在特殊功能寄存器TMOD中都有一控制位一C/T来选择T0或T1为定时器还是计数器。定时器/计数器的核心部件是一个加法(也有减法)的计数器,其本质是对脉冲进行计数。只是计数脉冲来源不同:如果计数脉冲来自系统时钟,则为定时方式,此时定时器/计数器每12个时钟或者每6个时钟得到一个计数脉冲,计数值加1;如果计数脉冲来自单片机外部引脚(T0为P3.4,T1为P3.5),则为计数方式,每来一个脉冲加1。

51单片机通常有4种工作模式(通过TMOD寄存器配置),常用模式为模式1(16位定时器)和模式2(8位自动重装)。

|-------------|------|---------------------------------------|
| 模式 | 位数 | 特点 |
| 模式0 | 13位 | 定时器使用THx的高5位和TLx的低8位(最大计数值8192) |
| 模式1 | 16位 | 定时器使用THx和TLx组成的16位计数器(最大计数值65536) |
| 模式2 | 8位自动 | TLx为8位计数器,溢出后自动将THx的值重装到TLx(适合固定周期定时) |
| 模式3 | 分裂模式 | 定时器0为8位自动重装,定时器1停止(仅52系列支持) |


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

结构特点:

位数:13位(THX的高5位+TLX的低8位)

最大计数值:2的13次方=8192

寄存器组合:

THX的高5位(D3~D7)参与计数,TLX的8位全部参与计数

计数范围:0x0000-0x1FFF(十六进制)

应用场景:适用于需要较短定时时间(<8192个机器周期)且对精度要求不高的场景。

代码示例:测量外部脉冲宽度(需结合GATE=1和INTx引脚)。

cpp 复制代码
TMOD = 0x00; // T0模式0(M1=0, M0=0) 
TH0 = 0xF0; // 高5位初值(假设计数16个机器周期) 
TL0 = 0x00; // 低8位初值 
TR0 = 1; // 启动T0

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

结构特点:

位数:16位(THX和TLX各8位)

最大计数值:2的16次方=65536

寄存器组合:

THX和TLX共组成16位计数器

计数范围:0x0000-0xFFFF

应用场景:最常用模式,适用于需要较长定时时间(如毫秒级、秒级定时)。

代码示例:LED闪烁(50ms中断一次)、PWM信号生成(需结合中断服务程序)。

cpp 复制代码
TMOD = 0x01; // T0模式1(M1=0, M0=1) 
TH0 = 0x3C; // 初值高8位(50ms定时,机器周期1μs) 
TL0 = 0xB0; // 初值低8位 
TR0 = 1; // 启动T0

3、模式2(8位自动重载定时器 / 计数器)

结构特点:

位数:8位(仅TLX参与计数,THX为重载值寄存器)

最大计数值:2的8次方=256

自动重载:

TLX溢出后,硬件自动将THX的值重装到TLX,无需软件干预。

计数范围:0x00-0xFF(TLX),重载值由THX设定。

应用场景:适用于需要固定周期中断的场景(如串口波特率生成、LED呼吸灯)。

代码示例:生成1kHz PWM信号(周期1ms,需250个机器周期)。

cpp 复制代码
TMOD = 0x02; // T0模式2(M1=1, M0=0) 
TH0 = 0x9C; // 重载值(250个机器周期,对应1ms) 
TL0 = 0x9C; // 初始值(首次计数从0x9C开始) 
TR0 = 1; // 启动T0

4、模式3(定时器0的分裂模式)

结构特点:

仅支持T0,T1不支持此模式

分裂为两个8为计数器:

TL0:独立的8位计数器,由TR0控制启动,使用T0的溢出标志TF0。

TL1:独立的8为计数器,由TR1控制启动(需占用T1的TR1位),使用T1的溢出标志TF1。

应用场景:适用于需要同时控制两个独立定时器的场景(如双通道PWM输出)。

代码示例:TL0生成PWM1,TH0生成PWM2(需配合T1的中断标志)。

cpp 复制代码
TMOD = 0x03; // T0模式3(M1=1, M0=1)
TH0 = 0x3C; // TH0初值(独立计数器) 
TL0 = 0xB0; // TL0初值(独立计数器) 
TR0 = 1; // 启动TL0 
TR1 = 1; // 启动TH0(需注意:T1的TR1被占用)

定时器模式总结

|-------------|-----|-------|--------------|---------------|
| 模式 | 位数 | 最大计数值 | 特点 | 适用场景 |
| 模式0 | 13位 | 8192 | 结构简单,计数范围小 | 短时间定时、外部信号测量 |
| 模式1 | 16位 | 65536 | 计数范围大,精度高 | 长时间定时、PWM信号生成 |
| 模式2 | 8位 | 256 | 自动重载,无需软件干预 | 固定周期中断、波特率生成 |
| 模式3 | 分裂 | 2×8位 | T0分裂为两个独立计数器 | 多通道定时、双PWM输出 |


定时器寄存器介绍

TMOD(定时器/计数器模式控制寄存器)

功能:控制定时器/计数器的工作模式,分为高四位(控制T1)和低四位(控制T0)

|---------------|-------|--------------------------------------------------------------------------------------------------------------------|
| | 名称 | 功能描述 |
| D7 | GATE | 门控位(T1)。GATE=1时,T1启动需同时满足TR1=1且INT1引脚为高电平;GATE=0时,仅TR1控制启动。 |
| D6 | C/T | 功能选择位(T1)。C/T=0为定时器模式(对内部时钟计数),C/T=1为计数器模式(对外部脉冲计数)。 |
| D5-D4 | M1/M0 | 工作方式选择位(T1): - 方式0(00):13位定时器/计数器。 - 方式1(01):16位定时器/计数器。 - 方式2(10):8位自动重载定时器/计数器。 - 方式3(11):仅T0支持,分为两个8位计数器;T1不支持。 |
| D3 | GATE | 门控位(T0),功能同T1的GATE位。 |
| D2 | C/T | 功能选择位(T0),功能同T1的C/T位。 |
| D1-D0 | M1/M0 | 工作方式选择位(T0),功能同T1的M1/M0位。 |


TCON(定时器/计数器控制寄存器)

功能:控制定时器/计数器的启动、停止及溢出标志

|---------------|---------|-------------------------------------|
| | 名称 | 功能描述 |
| D7 | TF1 | T1溢出标志位。计数溢出时硬件置1,需软件清零(中断方式下自动清零)。 |
| D6 | TR1 | T1运行控制位。TR1=1时启动T1,TR1=0时停止T1。 |
| D5 | TF0 | T0溢出标志位,功能同TF1。 |
| D4 | TR0 | T0运行控制位,功能同TR1。 |
| D3-D0 | 外部中断相关位 | 用于控制外部中断,与定时器无关。 |


THx/TLx(定时器高/低8位寄存器)

功能:存储定时器/计数器的计数值,分为:TH0/TL0对应T0的高8位和低8位。TH1/TL1对应T1的高8位和低8位。


定时器配置

定时器配置步骤:

1、对TMOD寄存器赋值,以确定T0或T1的工作方式(模式)

2、根据所要定时的时间计算初值,并将其写入TH0、TL0或TH1、TL1

3、如果使用中断,则对EA开启总中断,开启定时器对应中断允许位

4、使TR0或TR1置位,启动定时/计数器定时或计数;

示例:定时50毫秒配置

cpp 复制代码
TMOD=0x01;    //设置定时器TO工作模式为1
/*计算初值步骤为:
第一步、    根据时钟源频率计算振荡周期    1/11.0592us;
第二步、    根际振荡周期计算出机器周期    12*(1/11.0592)us
第三步、    根据延时时间50ms除以机器周期时间得出要计时为46080次
第四步、    根据定时器模式1计数的最高定时次数65536减去要计时的次数为19456;
第五步、    得到初值为19456转换为16进制,分别分配给TH0和TL0寄存器上
*/
TH0=0x4c;    
TL0=0x00;
EA=1;        //开启总中断
TR0=1;       //开启TR0寄存器启动定时器

定时器硬件电路原理图分析

定时器是MCU内置的功能,在开发板中并没有电路连接。这里用LED灯模块电路实现500毫秒闪烁;

可分析出有8个LED灯分别为D1~D8;LED灯左侧连接高电平VCC,LED灯右侧连接排阻在连接51单片机的P20~P27编号引脚;51单片机P20~P27编号引脚分别对应51芯片P2.0引脚~P2.7引脚;所以要得LED灯点亮电路中51单片机P2.0引脚~P2.7引脚输出低电平形成电势差;

定时器模块软件编程设计

实现定时器定时500毫秒LED灯实现闪烁

第一步:首先进行定时器配置,并且封装成函数;

第二步:在主函数中实现定时器的判断并且进行对应的操作

代码示例:

cpp 复制代码
#include "reg52.h"
typedef unsigned char u8;
typedef unsigned int u16;
#define LED P2		//LED灯宏定义
void TIM0_Init(void)//函数封装:定时器0初始化,定时时间为50毫秒
{
	TMOD=0x01;		//开启定时器0的模式1:16位定时
	TH0=0x4C;		//初值高八位存放0x4c
	TL0=0x00;		//初值第八位存放0x00
	TR0=1;			//开启定时器0
}
int main()
{
	u16 i=0;		//记录延时次数
	TIM0_Init();	//定时50毫秒定时器0配置
	LED=0x00;		//LED灯初始化为点亮
	while(1)
	{
	  if(TF0)		//定时器时间到
	  {
	  	TF0=0;		//软件清0
		TH0=0x4C;	//高八位存放0x4c
		TL0=0x00;	//第八位存放0x00
		i++;	  	
	  }
	  if(i==10)
	  {
	  	i=0;		//次数到,清零重新计数
		LED=~LED;	//LED灯翻转实现闪烁
	  }
	}
}

实现定时器定时500毫秒LED灯闪烁(要求:中断方式实现)

第一步:首先进行定时器配置,并且封装成函数;

第二步:创建定时器中断服务函数

第三步:在主函数中进行定时器配置函数等申明

代码示例:

cpp 复制代码
#include "reg52.h"
typedef unsigned char u8;
typedef unsigned int u16;
#define LED P2		//LED灯宏定义
void TIM0_Init(void)//函数封装:定时器0初始化,定时时间为50毫秒
{
	TMOD=0x01;		//开启定时器0的模式1:16位定时
	TH0=0x4C;		//初值高八位存放0x4c
	TL0=0x00;		//初值第八位存放0x00
	ET0=1;			//开启定时器0中断
	EA=1;			//开启总中断
	TR0=1;			//开启定时器0
}
void TIM0_ET0()	interrupt 1
{
	static u8 i=0;
		TF0=0;			//软件清零
		TH0=0x4C;		//初值高八位存放0x4c
		TL0=0x00;		//初值第八位存放0x00
		i++;
		if(i==10)
		{
			LED=~LED;
			i=0;
		}	

}	
int main()
{
	TIM0_Init();
	while(1)
	{
	  
	}
}

定时器定时500毫秒LED灯实现闪烁效果展示

定时器模块实现定时500毫秒LED灯闪烁


制作不易!喜欢的小伙伴给个小赞赞!喜欢我的小伙伴点个关注!有不懂的地方和需要的资源随时问我哟!

相关推荐
IT永勇4 小时前
STM32高级定时器-输出比较模式
stm32·单片机·嵌入式开发·pwm输出·高级定时器
正在努力的小河5 小时前
GPIO子系统自主实现(简单版)
linux·单片机·嵌入式硬件
什么半岛铁盒6 小时前
处理端口和 IP 地址
网络·单片机·tcp/ip
国科安芯17 小时前
高速CANFD收发器ASM1042在割草机器人轮毂电机通信系统中的适配性研究
网络·单片机·嵌入式硬件·性能优化·机器人·硬件工程
CC呢17 小时前
基于单片机智能路灯控制
单片机·嵌入式硬件·智能路灯
DDUU__17 小时前
STM32低功耗模式
stm32·单片机·嵌入式硬件
小莞尔19 小时前
【51单片机】【protues仿真】基于51单片机宠物投食器系统
c语言·stm32·单片机·嵌入式硬件·51单片机·proteus
逼子格19 小时前
【Protues仿真】基于AT89C52单片机的数码管驱动事例
单片机·嵌入式硬件·硬件工程·硬件工程师·protues·数码管·电路仿真
風清掦19 小时前
零基础玩转STM32:深入理解ARM Cortex-M内核与寄存器编程
stm32·单片机·嵌入式硬件·mcu·物联网