本章概述思维导图:
51单片机驱动定时器模块
CPU时序简介
CPU时序定义了CPU内部操作的时间节奏,以下从四个时序周期进行逐步解析;
1、振荡周期
振荡周期:CPU内部时钟源产生的最小时间单位,由晶振或内部振荡器决定;
公式为:Tosc=1 / fosc; fosc为时钟频率
作用为:所有操作的基础时间单位,CPU所有动作均同步于此信号。
2、状态周期
状态周期:部分CPU(如8051)将振荡周期分为两个状态(高电平与低电平),每个状态周期包含两个振荡周期
公式为:Tstate=2×Tosc;
3、机器周期
机器周期:完成一个基本操作(如取指、读写内存)所需的时间,由多个状态周期或振荡周期组成;1个机器周期=6个状态周期=12个振荡周期(以8051为列);
公式为:Tmachin=6×Tstate=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;公式为:ftimer =1 / Tmachin;若Tmachin=1us,则ftimer=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引脚)。
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信号生成(需结合中断服务程序)。
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个机器周期)。
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的中断标志)。
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): |
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毫秒配置
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灯实现闪烁
第一步:首先进行定时器配置,并且封装成函数;
第二步:在主函数中实现定时器的判断并且进行对应的操作
代码示例:
#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; //初值高八位存放0x4cTL0=0x00; //初值第八位存放0x00TR0=1; //开启定时器0
}
int main()
{u16 i=0; //记录延时次数TIM0_Init(); //定时50毫秒定时器0配置LED=0x00; //LED灯初始化为点亮while(1){if(TF0) //定时器时间到{TF0=0; //软件清0TH0=0x4C; //高八位存放0x4cTL0=0x00; //第八位存放0x00i++; }if(i==10){i=0; //次数到,清零重新计数LED=~LED; //LED灯翻转实现闪烁}}
}
实现定时器定时500毫秒LED灯闪烁(要求:中断方式实现)
第一步:首先进行定时器配置,并且封装成函数;
第二步:创建定时器中断服务函数
第三步:在主函数中进行定时器配置函数等申明
代码示例:
#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; //初值高八位存放0x4cTL0=0x00; //初值第八位存放0x00ET0=1; //开启定时器0中断EA=1; //开启总中断TR0=1; //开启定时器0
}
void TIM0_ET0() interrupt 1
{static u8 i=0;TF0=0; //软件清零TH0=0x4C; //初值高八位存放0x4cTL0=0x00; //初值第八位存放0x00i++;if(i==10){LED=~LED;i=0;} }
int main()
{TIM0_Init();while(1){}
}
定时器定时500毫秒LED灯实现闪烁效果展示
定时器模块实现定时500毫秒LED灯闪烁
制作不易!喜欢的小伙伴给个小赞赞!喜欢我的小伙伴点个关注!有不懂的地方和需要的资源随时问我哟!