文章目录
一、定时器
1.1.定时器介绍
- 51单片机的定时器属于单片机的内部资源,其电路的连接和运转均在单片机内部完成。
- 定时器作用:
(1)用于计时系统,可实现软件计时,或者使程序每隔一固定时间完成一项操作
(2)替代长时间的Delay,提高CPU的运行效率和处理速度
1.2.STC89C52定时器的资源
- 定时器个数:3个(T0、T1、T2),T0和T1与传统的51单片机兼容,T2是此型号单片机增加的资源。
- 注意:定时器的资源和单片机的型号是关联在一起的,不同的型号可能会有不同的定时器个数和操作方式,但一般来说,T0和T1的操作方式是所有51单片机所共有的。
1.3.定时器的工作原理
TC89C5X 单片机内有两个可编程的定时/计数器 T0、T1 和一个特殊功能定时器 T2。定时/计数器的实质是加 1 计数器(16 位),由高 8 位和低 8 位两个寄存器 THx 和 TLx 组成。它随着计数器的输入脉冲进行自加 1,也就是每来一个脉冲,计数器就自动加 1,当加到计数器为全 1 时,再输入一个脉冲就使计数器回零,且计数器的溢出使相应的中断标志位置 1,向 CPU 发出中断请求(定时/计数器中断允许时)。如果定时/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。可见,由溢出时计数器的值减去计数初值才是加 1 计数器的计数值。
上图中的 T0 和 T1 引脚对应的是单片机 P3.4 和 P3.5 管脚。51 单片机定时/计数器的工作由两个特殊功能寄存器控制。TMOD 是定时/计数器的工作方式寄存器,确定工作方式和功能;TCON 是控制寄存器,控制 T0、 T1 的启动和停止及设置溢出标志。
1.4.定时器工作模式
- STC89C52的T0和T1均有四种工作模式:
模式0:13位定时器/计数器
模式1:16位定时器/计数器(常用)
模式2:8位自动重装模式
模式3:两个8位计数器 - 工作模式1框图:
- SYSclk:系统时钟,即晶振周期。
二、中断系统
2.1.中断系统的概念
中断是为使单片机具有对外部或内部随机发生的事件实时处理而设置的,中断功能的存在,很大程度上提高了单片机处理外部或内部事件的能力。它也是单片机最重要的功能之一,是学习单片机必须要掌握的。举一个生活事例: 你打开火,烧上一壶水。然后去洗衣服,在洗衣服的过程中,突然听到水壶发出水开的报警声,这时,你停止洗衣服动作,立即去关掉火,然后将开水灌入暖水瓶中,灌完开水后,你又回去继续洗衣服。这个过程中实际上就发生了一次中断。对于单片机来讲,中断是指 CPU 在处理某一事件 A 时,发生了另一事件 B,请求 CPU 迅速去处理(中断发生);CPU 暂时停止当前的工作(中断响应), 转去处理事件 B(中断服务);待 CPU 将事件 I 处理完毕后,再回到原来事件 A 被中断的地方继续处理事件 A(中断返回),这一过程称为中断。
2.2.中断优先级
微型机的中断系统一般允许多个中断源,当几个中断源同时向 CPU 请求中断,要求为它服务的时候,这就存在CPU 优先响应哪一个中断源请求的问题。通常根据中断源的轻重缓急排队,优先处理最紧急事件的中断请求源,即规定每一个中断源有一个优先级别。CPU 总是先响应优先级别最高的中断请求。
2.3.中断嵌套
引起 CPU 中断的根源称为中断源。当CPU正在处理一个中断源请求时候(执行相应的中断服务),发生了另外一个优先级比它还高的中断源请求。如果CPU能够暂停对原来中断源的服务程序,转而去处理优先级更高的中断请求源,处理完以后,再回到原低级中断服务程序,这样的过程称为中断嵌套。这样的中断系统称为多级中断系统,没有中断嵌套功能的中断系统称为单级中断系统。
2.4.STC89C52中断的资源
- 中断源个数:8个(外部中断0、定时器0中断、外部中断1、定时器1中断、串口中断、定时器2中断、外部中断2、外部中断3)。
- 中断优先级个数:4个。
- 中断号:
- 注意:中断的资源和单片机的型号是关联在一起的,不同的型号可能会有不同的中断资源,例如中断源个数不同、中断优先级个数不同等等。
2.5.中断结构及相关寄存器
下面以 51 单片机一定有的 5 个中断来介绍,其内部结构框图如下所示:
①INT0 对应的是 P3.2 口的附加功能,可由 IT0(TCON.0)选择其为低电平有效还是下降沿有效。当 CPU 检测到 P3.2 引脚上出现有效的中断信号时,中断标志 IE0(TCON.1)置 1,向 CPU 申请中断。
②INT1 对应的是 P3.3 口的附加功能,可由 IT1(TCON.2)选择其为低电平有效还是下降沿有效。当 CPU 检测到 P3.3 引脚上出现有效的中断信号时,中断标志 IE1(TCON.3)置 1,向 CPU 申请中断。
③T0 对应的是 P3.4 口的附加功能,TF0(TCON.5),片内定时/计数器 T0 溢出中断请求标志。当定时/计数器 T0 发生溢出时,置位 TF0并向 CPU 申请中断。
④T1 对应的是 P3.5 口的附加功能,TF1(TCON.7),片内定时/计数器 T1溢出中断请求标志。当定时/计数器 T1 发生溢出时,置位 TF1,并向 CPU 申请中断。
⑤RXD 和 TXD 对应对应的是 P3.0 和 P3.1 口的附加功能,RI(SCON.0)或 TI(SCON.1),串行口中断请求标志。当串行口接收完一帧串行数据时置位 RI 或当串行口发送完一帧串行数据时置位 TI,向 CPU 申请中断。
2.6.中断允许控制
CPU 对中断系统所有中断以及某个中断源的开放和屏蔽是由中断允许寄存器IE 控制的。
- EX0(IE.0),外部中断 0 允许位;
- ET0(IE.1),定时/计数器 T0 中断允许位;
- EX1(IE.2),外部中断 0 允许位;
- ET1(IE.3),定时/计数器 T1 中断允许位;
- ES(IE.4),串行口中断允许位;
- EA (IE.7), CPU 中断允许(总允许)位。
2.7.中断请求标志 TCON
- IT0(TCON.0),外部中断 0 触发方式控制位。
当 IT0=0 时,为电平触发方式。
当 IT0=1 时,为边沿触发方式(下降沿有效)。 - IE0(TCON.1),外部中断 0 中断请求标志位。
- IT1(TCON.2),外部中断 1 触发方式控制位。
- IE1(TCON.3),外部中断 1 中断请求标志位。
- TF0(TCON.5),定时/计数器 T0 溢出中断请求标志位。
- TF1(TCON.7),定时/计数器 T1 溢出中断请求标志位
2.8.中断响应条件
- 中断源有中断请求;
- 此中断源的中断允许位为 1;
- CPU 开中断(即 EA=1)。
三、使用内部中断实现定时器
3.1.模块化定时器
将定时器有关的代码进行模块化,创建.c和.h命名为Timer:
#include <REGX52.H>
void Timer0_Init ()
{
TMOD&=0xF0; //前四位保持不变,后面置零
TMOD|=0x01; //让最低位置1,前面保持不变
TL0 = 0x18; //按照每个单片机的晶振频率,设计定时器的高四位和第四位,让他们装满刚好为1ms
TH0 = 0xFC;
TF0 = 0;
TR0 = 1;
ET0=1;
EA=1;
PT0=1;
}
/*这是定时器的中断号,尽量放在主函数使用
void Timer0() interrupt 1
{
static unsigned int Tcount;
TL0 = 0x18;
TH0 = 0xFC;
Tcount++;
}
*/
#ifndef __TIME0_H__
#define __TIME0_H__
void Timer0_Init ();
#endif
接下来是主函数main,将他们的模块进行拼接,设计中断:
#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "Time0.h"
unsigned char sec,min,hour;
void main()
{
Timer0_Init();
LCD_Init(); //LCD是一块小的显示屏
LCD_ShowString(1,1,"clock");
LCD_ShowString(2,1," : : ");
while(1)
{
LCD_ShowNum(2,1,hour,2);
LCD_ShowNum(2,4,min,2);
LCD_ShowNum(2,7,sec,2);
}
}
void Timer0() interrupt 1
{
static unsigned int Tcount;
TL0 = 0x18;
TH0 = 0xFC; //TL和TH两个满了之后加1ms
Tcount++; //每次加1ms
if(Tcount==1000) //这里就是1s中断一次
{
Tcount=0;
sec++;
if(sec>=60) //秒
{
sec=0;
min++;
if(min>=60) //分
{
min=0;
hour++;
if(hour>=24) //时
{
hour=0;
}
}
}
}
}