目录
一、定时器/计数器的结构
AT89S51单片机的定时器/计数器结构如下图所示,定时器/计数器T0由特殊功能寄存器TH0、TL0构成,定时器/计数器T1由特殊功能寄存器TH1、TL1构成。
AT89S51单片机的定时器/计数器结构框图
AT89S51的Timer 0(T0)和Timer 1(T1)都具有定时器和计数器两种工作模式。
在定时器模式下,T0和T1可以被用作定时器来测量时间间隔。它们可以根据预设的初值进行计数,当计数值达到设定的目标值时,会触发定时器中断。这个机制可以用来生成精确的定时延迟。
在计数器模式下,T0和T1可以被用作计数器来计算外部脉冲的数量。它们可以根据外部脉冲的输入进行计数。一般来说,这种模式用于测量外部事件的频率或时间间隔。
为了切换工作模式,对应的控制寄存器需要进行相应的设置。在AT89S51中,T0的工作模式由T0CON寄存器来设置,T1的工作模式由T1CON寄存器来设置。
1.1 定时器/计数器工作方式寄存器TMOD
在AT89S51中,定时器/计数器的工作方式由寄存器TMOD(Timer Mode)来控制。TMOD是一个8位寄存器,用于设置T0和T1的工作模式和工作方式。
TMOD寄存器的位布局如下:
位7 | 位6 | 位5 | 位4 | 位3 | 位2 | 位1 | 位0 |
---|---|---|---|---|---|---|---|
GATE | C/T1 | M1 | M0 | GATE | C/T0 | M1 | M0 |
8位分为两组,高4位控制T1,低4位控制T0。
- GATE:门控位
GATE=0,定时器/计数器是否计数,仅由控制位TRx(x=0,1)来控制。(通常)
GATE=1,定时器/计数器是否计数,要由外中断引脚 INT0(或INT1)上的电平与运动控制位TRx两个条件共同控制。
- M1和M0:工作方式选择位
M1和M0位用于选择T0和T1的工作方式。M1和M0位的取值情况如下:
M1 | M0 | 工作方式 |
---|---|---|
0 | 0 | 13位定时器/计数器(Mode 0) |
0 | 1 | 16位定时器/计数器(Mode 1) |
1 | 0 | 8位自动重装载的定时器/计数器(Mode 2) |
1 | 1 | 仅适用于T0,此时T0分成2个8位计数器,T1停止计数(Mode 3) |
1.2 定时器/计数器控制寄存器TCON
在AT89S51中,定时器/计数器的控制由寄存器TCON(Timer/Counter Control)来进行。TCON是一个8位寄存器,用于启动、停止和设置定时器/计数器的工作方式。
TCON寄存器的位布局如下:
位7 | 位6 | 位5 | 位4 | 位3 | 位2 | 位1 | 位0 |
---|---|---|---|---|---|---|---|
TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
- TR1和TR0位
TR1和TR0位用于启动和停止T1和T0的定时器/计数器。
TR1和TR0位的取值情况如下:
TR1 | TR0 | 功能 |
---|---|---|
0 | 0 | 停止T1和T0的计数器 |
0 | 1 | 启动T0的计数器 |
1 | 0 | 启动T1的计数器 |
1 | 1 | 同时启动T1和T0的计数器 |
- TF1和TF0位
TF1和TF0位用于检测T1和T0的溢出标志。当定时器/计数器溢出时,这些位将被设置为1。可以通过软件将它们清零。
- IE1和IE0位
IE1和IE0位用于使能T1和T0的中断。当相应的位设置为1时,若定时器/计数器溢出时,将触发相应的中断。
- IT1和IT0位
IT1和IT0位用于设置T1和T0的中断类型。当IT1位设置为1时,T1的中断为高电平触发,当IT1位设置为0时,T1的中断为下降沿触发。当IT0位设置为1时,T0的中断为高电平触发,当IT0位设置为0时,T0的中断为下降沿触发。
二、定时器/计数器的4种工作方式
2.1 方式0
定时器/计数器的4种工作方式中,方式0是最简单的工作方式,也被称为13位定时器计数器模式(13-bit Timer/Counter Mode)。
在方式0中,定时器/计数器的输入时钟源为时钟频率的12分频。它可以被用作13位定时器或13位计数器,由T0引脚的控制位决定。当T0引脚连接到外部时钟源时,可以选择将定时器/计数器配置为计数器,否则配置为定时器。
在方式0中,定时器/计数器的计数范围为0到8191。这意味着定时器/计数器将在计数到8191时溢出,并自动从0开始重新计数。当计数器溢出时,会发生中断(如果中断使能位IE0被设置为1)。
定时器/计数器方式0的工作方式可以通过设置TCON寄存器中位1和位0的值来控制。当位1和位0都设置为0时,定时器/计数器处于停止状态,不进行计数。当位1设置为1而位0设置为0时,定时器/计数器将开始倒计时。当位1设置为0而位0设置为1时,定时器/计数器将开始正计时。当位1和位0都设置为1时,定时器/计数器将同时进行正计时和倒计时。
2.2 方式1
方式1是定时器/计数器的第二种工作方式,也被称为16位自动重装定时器模式(16-bit Auto-reload Timer Mode)。
在方式1中,定时器/计数器的输入时钟源为时钟频率的12分频。它被配置为一个16位定时器/计数器,每次计数范围从0到65535。当计数器达到最大值65535时,会自动从初始值(预设的重载值)重新开始计数。
定时器/计数器方式1适用于需要长时间计时的应用,因为它的计数范围更大。它可以更精确地测量较长的时间间隔。
方式1的工作方式可以通过设置TMOD寄存器中的位[1:0]来配置。具体的设置如下:
- BIT1 = 1,BIT0 = 0:定时器/计数器开始倒计时,并根据设置的重载值进行自动重装。当计数器溢出时,会发生中断(如果中断使能位IE1被设置为1)。
- BIT1 = 0,BIT0 = 1:定时器/计数器开始正计时,计数范围从0到65535,当计数器达到最大值时,会自动从初始值重新开始计数。
2.3 方式2
方式2是定时器/计数器的第三种工作方式,也被称为8位自动重装定时器模式(8-bit Auto-reload Timer Mode)。
在方式2中,定时器/计数器的输入时钟源为时钟频率的12分频。它被配置为一个8位定时器/计数器,每次计数范围从0到255。当计数器达到最大值255时,会自动从初始值(预设的重载值)重新开始计数。
定时器/计数器方式2适用于需要短时间计时的应用,因为它的计数范围较小。它可以更快地测量较短的时间间隔。
方式2的工作方式可以通过设置TMOD寄存器中的位[3:2]来配置。具体的设置如下:
- BIT3 = 1,BIT2 = 0:定时器/计数器开始倒计时,并根据设置的重载值进行自动重装。当计数器溢出时,会发生中断(如果中断使能位IE2被设置为1)。
- BIT3 = 0,BIT2 = 1:定时器/计数器开始正计时,计数范围从0到255,当计数器达到最大值时,会自动从初始值重新开始计数。
2.4 方式3
方式3是定时器/计数器的第四种工作方式,也被称为两个8位定时器/计数器模式(Two 8-bit Timer/Counter Mode)。
在方式3中,定时器/计数器被分为两个独立的8位定时器/计数器,分别被称为定时器/计数器0(T0)和定时器/计数器1(T1)。每个定时器/计数器都有自己的寄存器和控制位。
定时器/计数器0(T0)和定时器/计数器1(T1)拥有独立的工作方式和计时引脚。它们可以同时进行不同的计时操作,具有更高的灵活性和多任务处理能力。
方式3的工作方式可以通过设置TMOD寄存器中的位[1:0]来配置。具体的设置如下:
- BIT1 = 1,BIT0 = 0:定时器/计数器0工作在方式1中的8位自动重装定时器模式。
- BIT1 = 0,BIT0 = 1:定时器/计数器1工作在方式1中的8位自动重装定时器模式。
- BIT1 = 1,BIT0 = 1:定时器/计数器0和定时器/计数器1同时工作,各自独立配置工作方式。
三、定时器/计数器T0、T1的编程应用
3.1 P1口控制8只LED
在AT89S51单片机的P1口上接有8只LED,采用定时器T0的方式1的定时中断方式,使P1口外接的8只LED每0.5秒闪亮一次。
方式1定时中断LED闪亮电路示意图
程序代码:
#include <reg51.h> // 包含51单片机寄存器定义
#define LED P1 // 将P1口定义为LED
// 初始化定时器T0为模式1
void Timer0_Init() {
TMOD |= 0x01; // 设置定时器0为模式1(16位定时器模式)
TH0 = 0xB8; // 装载初值,定时器高8位
TL0 = 0x00; // 装载初值,定时器低8位
ET0 = 1; // 开启定时器T0中断
EA = 1; // 开启全局中断
TR0 = 1; // 启动定时器T0
}
// 定时器T0中断服务程序
void Timer0_ISR() interrupt 1 {
static unsigned int count = 0;
TH0 = 0xB8; // 重新装载初值,定时器高8位
TL0 = 0x00; // 重新装载初值,定时器低8位
count++;
if (count >= 10) { // 累计中断次数,0.5秒闪烁一次
count = 0;
LED = ~LED; // 取反LED的状态,实现闪烁
}
}
void main() {
LED = 0xFF; // 初始化LED状态,全部熄灭(假设LED为共阳极接法)
Timer0_Init(); // 初始化定时器T0
while(1) {
// 主循环中不需要做任何事,LED闪烁由定时器中断控制
}
}
或
#include <reg51.h> // 包含51单片机寄存器定义
#define LED P1 // 将P1口定义为LED
// 初始化定时器T0为模式1
void Timer0_Init() {
TMOD |= 0x01; // 设置定时器0为模式1(16位定时器模式)
TH0 = 0xB8; // 装载初值,定时器高8位
TL0 = 0x00; // 装载初值,定时器低8位
ET0 = 1; // 开启定时器T0中断
EA = 1; // 开启全局中断
TR0 = 1; // 启动定时器T0
}
// 定时器T0中断服务程序
void Timer0_ISR() interrupt 1 {
static unsigned int count = 0;
TH0 = 0xB8; // 重新装载初值,定时器高8位
TL0 = 0x00; // 重新装载初值,定时器低8位
count++;
if (count >= 10) { // 累计中断次数,0.5秒闪烁一次
count = 0;
LED = ~LED; // 取反LED的状态,实现闪烁
}
}
void main() {
LED = 0xFF; // 初始化LED状态,全部熄灭(假设LED为共阳极接法)
Timer0_Init(); // 初始化定时器T0
while(1) {
// 主循环中不需要做任何事,LED闪烁由定时器中断控制
}
}
3.2 计数器的应用
定时器T1采用计数模式,方式1中断,计数输入引脚T1上外接按钮开关,作为计数信号输入。按4次按钮开关后,P1口的8只LED闪烁不停。
程序代码:
#include <reg51.h>
#define LED P1
#define BUTTON P3_6
void Delay (unsigned int i){ //延时函数Delay(),i为形式参数,不能赋初值
unsigned int j;
for(;i > 0;i--)
for (j=0;j<333;j++) //晶体振荡器为12MHz,j的选择与晶体振荡器频率有关
{;} //空函数
// 假设已经有一个函数用于初始化定时器T1
void Timer1_Init() {
// 定时器初始化代码
}
// 假设已经有一个函数用于初始化外部中断
void ExternalInterrupt_Init() {
// 外部中断初始化代码
IT0 = 1; // 配置INT0为下降沿触发
EX0 = 1; // 启用外部中断0
}
// 定义一个全局变量来计数按钮按下的次数
unsigned char button_press_count = 0;
// 外部中断0的中断服务程序
void External0_ISR() interrupt 0 {
button_press_count++; // 按钮被按下,计数加1
if (button_press_count >= 4) {
// 如果按了4次按钮,使LED闪烁不停
while (1) {
LED = 0xFF; // LED全亮
Delay(100); // 延时函数
LED = 0x00; // LED全灭
Delay(100); // 延时函数
}
}
}
void main() {
Timer1_Init(); // 初始化定时器T1
ExternalInterrupt_Init(); // 初始化外部中断
EA = 1; // 全局中断使能
while (1) {
// 主循环代码,如果需要可以执行其他任务
}
}
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » 单片机原理及技术(七)—— 定时器/计数器的工作原理
发表评论 取消回复