07 51单片机之定时器

文章目录


1、前言

在前面的文章中介绍了51单片机之矩阵键盘,今天介绍单片机的定时器。


2、定时器

  1. 定时器介绍:51单片机的定时器属于单片机的内部资源,其电路的连接和运转均在单片机内部完成。
  2. 定时器作用:
    • 用于计时系统,可实现软件计时,或者使程序每隔一固定时间完成一项操作。
    • 替代长时间的Delay,提高CPU的运行效率和处理速度
    • 操作系统多任务的切换等等(参考STM模块)。

3、STC89C52定时器资源

  • 定时器个数:3个(T0、T1、T2),T0和T1与传统的51单片机兼容,T2是此型号单片机增加的资源;
  • 注意:定时器的资源和单片机的型号是关联在一起的,不同的型号可能会有不同的定时器个数和操作方式,但一般来说,T0和T1的操作方式是所有51单片机所共有的。

3-1、定时器/计数器(T0/T1)

  1. STC89C52系列单片机的定时器0和定时器1,与传统8051的的定时器完全兼容,当在定时器1做波特率发生器时,定时器0可以当两个8位定时器用。
  2. STC89C52系列单片机内部设置的两个16位定时器/计数器T0和T1都具有计数方式定时方式 两种工作方式。对每个定时器/计数器(T0和T1),在特殊殊功能寄存器TMOD中都有一控制位一C/T来选择T0或T1为定时器还是计数器。定时器/计数器的核心部件是一个加法(也有减法)的计数器,其本质是对脉冲进行计数 。只是计数脉冲来源不同:如果计数脉冲来自系统时钟,则为定时方式,此时定时器/计数器每12个时钟或者每6个时钟得到一个计数脉冲,计数值加1;如果计数脉冲来自单片机外部引脚(T0为P3.4,T1为P3.5),则为计数方式,每来一个脉冲加1
  3. 当定时器/计数器工作在定时模式 时,可在烧录用户程序时在STC-ISP编程器中设置(如下图所示)是系统时钟÷12还是系统时钟÷6后让T0和T1过进行计数。当定时器/计数器工作在计数模式 时,对外部脉冲计数不分频。

Figure1. STC-ISP编程器设置

  1. 定时器/计数器0有4种工作模式:模式0(13位定时器/计数器),模式1(16位定时器/计数器模式),模式2(8位自动重装模式),模式3(两个8位定时器/计数器)。定时器/计数器1除模式3外,其他工作模式与定时器/计数器0相同,T1在模式3时无效,停止计数。

3-2、定时器框图

定时器在单片机内部就像一个小闹钟一样,根据时钟的输出言号,每隔"一秒",计数单元的数值就增加一,当计数单元数值增加到"设定的闹钟提醒时间"时,计数单元就会向中断系统发出中断申请 ,产生"响铃提醒",使程序跳转到中断服务函数 中执行。

Figure2. 定时器框图


3-3、定时器/计数器0和1的相关寄存器


Figure3. 定时器/计数器0和1的相关寄存器


3-3-1、定时器/计数器控制寄存器TCON

TCON为定时器/计数器T0、 T1的控制寄存器,同时也锁存T0、 T1溢出中断源和外部请求中断源等, TCON格式如下:

Figure4. 定时器/计数器控制寄存器TCON


3-3-2、定时器/计数器工作模式寄存器TMOD

定时和计数功能由特殊功能寄存器TMOD 的控制位C/\T进行选择,TMOD寄存器的各位信息如下表所列。可以看出,2个定时/计数器有4种操作模式,通过TMOD的M1和M0选择。2个定时/计数器的模式0、1和2都相同,模式3不同,各模式下的功能如下所述。

Figure5. 定时器/计数器工作模式寄存器TMOD


3-4、模式1:16位定时器/计数器(常用)

由于STC89C52的T0和T1均有四种工作模式。模式0:13位定时器/计数器;模式1:16位定时器/计数器;模式2:8位自动重装模式;模式3:两个8位计数器。其中模式1最为常用。模式1除了使用了TH0及TL0全部16位外,其他与模式0完全相同。即此模式下定时器/计数器0作为16位定时器/计数器 ,如Figure5. 定时器/计数器0的模式1:16位定时器/计数器所示为工作模式1的框图。

Figure5. 定时器/计数器0的模式1:16位定时器/计数器


  1. 此模式下,定时器配置为16位定时器/计数器,由TL0的8位和TH0的8位所构成。TL0的8位溢出向TH0进位,TH0计数溢出置位TCON中的溢出标志位TF0。TL最大值是65535,然后就给TF0置位,触发中断操作。
  2. SYSclk:系统时钟,即晶振周期,本开发板上的晶振为12MHz
  3. 当GATE=0(TMOD.3)时,如TRO=1,则定时器计数。GATE=1时,允许由外部输入INTO控制定时器0,这样可实现脉宽测量。TR0为TCON寄存器内的控制位,TCON寄存器各位的具体功能描述见上节TCON寄存器的介绍。
  4. 当C/ \T=0时,多路开关连接到系统时钟的分频输出,T0对时钟周期计数,T0工作在定时方式 。当C/ \T=1时,多路开关连接到外部脉冲输入P3.4/T0,即T0工作在计数方式
  5. STC89C52系列单片机的定时器有两种计数速率:一种是12T模式,每12个时钟加1,与传统8051单片机相同;另外一种是6T模式,每6个时钟加1,速度是传统8051单片机的2倍。T0的速率在烧录用户程序时在STC-ISP编程器中设置

4、中断系统

4-1、概念介绍

  1. 中断系统是为使CPU具有对外界紧急事件的实时处理能力而可设置的。
  2. 当中央处理机CPU正在处理某件事的时候外界发生了紧急事件请求,要求CPU暂停当前的工作,转而去处理这个紧急事件,处理完以后,再回到原来被中断的地方,继续原来的工作,这样的过程称为中断 。实现这种功能的部件称为中断系统,请示CPU中断的请求源称为中断源 。微型机的中断系统一般允许多个中断源,当几个中断源同时向CPU请求中断,要求为它服务的时候,这就存在CPU优先响应哪一个中断源请求的问题。通常根据中断源的轻重缓急排队,优先处理最紧急事件的中断请求源,即规定每一个中断源有一个优先级别。CPU总是先响应优先级别最高的中断请求
  3. 当CPU正在处理一个中断源请求的时候(执行相应的中断服务程序),发生了另外一个优先级比它还高 的中断源请求。如果CPU能够暂停对原来可中断源的服务程序,转而去处理优先级更高的中断请求源,处理完以后,再回到原低级中断服务程序,这样的过程称为中断嵌套 。这样的中断系统称为多级中断系统 ,没有中断嵌套功能的中断系统称为单级中断系统
  4. STC89C52系列单片机提供了8个中断请求源,它们分别是:外部中断0(\INT0)、定时器0中断、外部中断1(\INTI)、定时器1中断、串口(UART)中断、定时器2中断、外部中断2(\INT2)、外部中断3(\INT3) 。所有的中断都具有4个中断优先级。用户可以用用关总中断允许位(EA/IE.7)或相应中断的允许位来屏蔽所有的中断请求,也可以用打开相应的中断允许位来使CPU响应相应的中断申请:每一个中断源可以用软件独立地控制为开中断或关中断状态:每一个中断的优先级别均可用软件设置。高优先级的中断请求可以打断低优先先级的中断,反之,低优先级的中断请求不可以打断高优先级及同优先级的中断。当两个相同优先级的中断同时产生时,将由查询次序来决定系统先响应哪个中断。

Figure6. 中断程序流程图


Table1. 中断查询次序

通过设置新增加的特殊功能寄存器IPH 中的相应位,可将中断优先级设为四级,如果只设置IP或XICON,那么中断优先级就只有两级,与传统80511单片机两级中断优先级完全兼容。如果使用C语言编程,中断查询次序号就是中断号,例如:
Table2. 中断查询次序号

void 中断函数接口 中断号
void Int0_Routine(void) interrupt 0;
void Timer0_Rountine(void) interrupt 1;
void Int1_Routine(void) interrupt 2;
void Timer1_Rountine(void) interrupt 3;
void UART_Routine(void) interrupt 4;
void Timer2_Routine(void) interrupt 5;
void Int2_Routine(void) interrupt 6;
void Int3_Routine(void) interrupt 7;

4-2、中断系统结构


Figure7. 中断系统结构


4-3、中断系统寄存器

寄存器是连接软硬件的媒介。在单片机中寄存器就是一段特殊的RAM存储器,一方面,寄存器可以存储和读取数据,另一方面,每一个寄存器背后都连接了一根导线,控制着电路的连接方式 。寄存器相当于一个复杂机器的"操作按钮"。

Figure8. 中断系统寄存器


4-3-1、中断允许寄存器IE


Figure9. 中断允许寄存器IE


4-3-2、中断允许寄存器XICON


Figure10. 中断允许寄存器XICON


4-3-3、中断优先级控制寄存器IP/XICON和IPH


Figure11. 中断优先级控制寄存器IP/XICON和IPH


4-3-4、定时器/计数器0/1控制寄存器TCON


Figure12. 定时器/计数器0/1控制寄存器TCON


4-3-5、串行口控制寄存器SCON


Figure13. 串行口控制寄存器SCON


4-3-6、定时器/计数器2控制寄存器T2CON


Figure14. 定时器/计数器2控制寄存器T2CON


5、工程编码

5-1、点亮一个LED(Timer0)


Figure15. 点亮一个LED


c 复制代码
#include <REGX52.H>

void Timer0_Init()
{
	/* 1.set timer0 as mode1 (16-bit). M1 = 0, M0 = 1. */
	TMOD = 0x01; 
	/* 2.TF0 = 0 */
	TF0 = 0;
	/* 3.timer0 start running. */
	TR0 = 1;
	/* 4.0~65535 每隔1us计数加一, 总共定时时间65535us. 64535离计数器溢出差值1000, 所以计时时间为1ms. */
	/* 4-1.initial timer0 low byte. */
	TH0 = 64535 / 256; // 0xFC17 / 0x100
	/* 4-2.initial timer0 high byte. */
	TL0 = 64535 % 256; // 0xFC17 % 0x100
	/* 5.enable timer0 interrupt. */
	ET0 = 1;
	/* 6.open global interrupt switch. */
	EA = 1;
	/* 7. */
	PT0 = 0;
	
}

void main()
{
	Timer0_Init();
	//loop
	while(1)
	{
		
	}
}

void Timer0_Routine() interrupt 1
{
	P2_0 = 0;
}

5-2、以1s间隔点亮LED(Timer0)


Figure16. 以1s间隔点亮LED


c 复制代码
#include <REGX52.H>

void Timer0_Init()
{
	/* 1.set timer0 as mode1 (16-bit). M1 = 0, M0 = 1. */
	TMOD = 0x01; 
	/* 2.TF0 = 0 */
	TF0 = 0;
	/* 3.timer0 start running. */
	TR0 = 1;
	/* 4.0~65535 每隔1us计数加一, 总共定时时间65535us. 64535离计数器溢出差值1000, 所以计时时间为1ms. */
	/* 4-1.initial timer0 low byte. */
	TH0 = 64535 / 256; // 0xFC17 / 0x100
	/* 4-2.initial timer0 high byte. */
	TL0 = 64535 % 256; // 0xFC17 % 0x100
	/* 5.enable timer0 interrupt. */
	ET0 = 1;
	/* 6.open global interrupt switch. */
	EA = 1;
	/* 7. */
	PT0 = 0;
}

void main()
{
	Timer0_Init();
	//loop
	while(1)
	{
		
	}
}

unsigned int T0Cnt;

void Timer0_Routine() interrupt 1
{
	/* Inhibit timer0 count overflow. */
	/* 4-1.initial timer0 low byte. */
	TH0 = 64535 / 256; // 0xFC17 / 0x100
	/* 4-2.initial timer0 high byte. */
	TL0 = 64535 % 256; // 0xFC17 % 0x100
	T0Cnt++;
	if(T0Cnt >= 1000) //1s = 1000ms
	{
		T0Cnt = 0;
		P2_0 = ~P2_0;
	}
}

5-3、STC_ISP生成定时器配置代码


Figure17. 以1s间隔点亮LED(Timer0)


c 复制代码
void Timer0_Isr(void) interrupt 1
{
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
}

void Timer0_Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0x7F;			//定时器时钟12T模式
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x01;			//设置定时器模式
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;				//使能定时器0中断
}


Figure18. STC_ISP生成定时器配置代码


5-4、流水灯LED


Figure19. 流水灯LED


c 复制代码
#include <REGX52.H>
#include "Timer0.h"
#include "Key.h"
#include <INTRINS.H>

unsigned char KeyNum,LEDMode;

void main(void)
{
	P2 = 0xFE;
	Timer0_Init();
	//loop
	while(1)
	{
		KeyNum = Key();
		if(KeyNum)
		{
			if(1 == KeyNum)
			{
				LEDMode++;
				if(LEDMode >= 2)
				{
					LEDMode = 0;
				}
			}
		}
	}
}

void Timer0_Isr(void) interrupt 1
{
	static unsigned int T0Cnt;
	/* Inhibit timer0 count overflow. */
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	T0Cnt++;
	if(T0Cnt >= 500) //0.5s = 500ms
	{
		T0Cnt = 0;
		if(LEDMode == 0)
			P2 = _crol_(P2,1);
		if(LEDMode == 1)
			P2 = _cror_(P2,1);
	}
}

5-5、实验现象

流水灯LED


5-6、时钟显示


Figure20. 时钟显示


c 复制代码
#include <REGX52.H>
#include "Timer0.h"
#include "Key.h"
#include <INTRINS.H>
#include "LCD1602.h"

unsigned char KeyNum,LEDMode,Sec,Mins,Hour;

void main(void)
{
	LCD_Init();
	Timer0_Init();
	
	P2 = 0xFE;
	LCD_ShowString(1,1,"GalaxyClock:");
	LCD_ShowString(2,1,"S:");
	LCD_ShowString(2,6,"M:");
	LCD_ShowString(2,11,"H:");
	//loop
	while(1)
	{
		KeyNum = Key();
		if(KeyNum)
		{
			if(1 == KeyNum)
			{
				LEDMode++;
				if(LEDMode >= 2)
				{
					LEDMode = 0;
				}
			}
		}
		LCD_ShowNum(2,3,Sec,2);
		LCD_ShowNum(2,8,Mins,2);
		LCD_ShowNum(2,13,Hour,2);
	}
}

void Timer0_Isr(void) interrupt 1
{
	static unsigned int T0Cnt0,T0Cnt1;
	/* Inhibit timer0 count overflow. */
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	T0Cnt0++;
	T0Cnt1++;
//	if(T0Cnt0 >= 500) //0.5s = 500ms
//	{
//		T0Cnt0 = 0;
//		if(LEDMode == 0)
//			P2 = _crol_(P2,1);
//		if(LEDMode == 1)
//			P2 = _cror_(P2,1);
//	}
	
	if(T0Cnt1 >= 1000) //1s = 1000ms
	{
		T0Cnt1 = 0;
		Sec++;
		if(Sec >= 60)
		{
			Sec = 0;
			Mins++;
			if(Mins >= 60)
			{
				Mins = 0;
				Hour++;
				if(Hour >= 24)
				{
					Hour = 0;
				}
			}
		}
	}
}

5-7、实验现象

时钟显示


相关推荐
月阳羊3 小时前
【硬件-笔试面试题】硬件/电子工程师,笔试面试题-26,(知识点:硬件电路的调试方法:信号追踪,替换,分段调试)
笔记·嵌入式硬件·面试·职场和发展
嵌入式小白牙6 小时前
ARM-I2C软实现
stm32·单片机·嵌入式硬件
金色光环6 小时前
【阅读整理】野火ADC_AD7192模块资料
单片机·嵌入式硬件
jllllyuz6 小时前
基于AD7147电容触摸芯片与STC12C5A60S2单片机方案
单片机·嵌入式硬件
范纹杉想快点毕业10 小时前
ZYNQ芯片,SPI驱动开发自学全解析个人笔记【FPGA】【赛灵思
stm32·单片机·嵌入式硬件·mcu·架构·51单片机·proteus
景彡先生10 小时前
STM32 GPIO(通用输入输出)详解:从模式原理到实战应用
stm32·单片机·嵌入式硬件
苏州向日葵11 小时前
篇五 网络通信硬件之PHY,MAC, RJ45
网络·嵌入式硬件
flashier11 小时前
ESP32学习笔记_Peripherals(4)——MCPWM基础使用
单片机·学习·esp32·pwm·mcpwm
书山有路勤为径~11 小时前
1 51单片机-C51语法
单片机·嵌入式硬件·51单片机